home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / tgif / patch2.1 < prev    next >
Internet Message Format  |  1990-08-03  |  58KB

  1. Path: uunet!cs.utexas.edu!sun-barr!newstop!sun!CS.UCLA.EDU
  2. From: william@CS.UCLA.EDU (William Cheng)
  3. Newsgroups: comp.sources.x
  4. Subject: v08i058: tgif (tgif-1.9 => tgif-1.12), Patch2, Part01/03
  5. Message-ID: <140168@sun.Eng.Sun.COM>
  6. Date: 4 Aug 90 02:12:10 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1818
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: william@CS.UCLA.EDU (William Cheng)
  12. Posting-number: Volume 8, Issue 58
  13. Archive-name: tgif/patch2.01
  14. Patch-To: tgif: Volume 7, Issue 56-76 (original: tgif-1.2)
  15. Patch-To: tgif: Volume 8, Issue 46-48 (Patch1: tgif-1.2 => tgif-1.9)
  16.  
  17. Patch2 of tgif takes tgif-1.9 to tgif-1.12.  Below is a list of
  18. added features/bug fixes, followed by the actual patch.
  19.  
  20. tgif-1.9 => tgif-1.10
  21.  
  22. 1) Fix bugs reported by Michael Webb regarding reading very long polygline.
  23. 2) Disallow stretching of zero width or zero height objects.
  24. 3) Add feature:  Add points and delete points to poly and splines.
  25. 4) In case of emergency, save working file in EmergencySave.obj or
  26.    EmergencySave.sym.  (Thanks to Stephen Doyle and Christos Zoulas.)
  27. 5) Add XDefault "Tgif*Synchronize" call XSynchronize ().
  28. 6) Add -p command line option to prtgif to print encapsulated PostScript
  29.    file.  (Thanks to Stephen Doyle.)
  30.  
  31. tgif-1.10 => tgif-1.11
  32.  
  33. 1) Fix bugs reported by Christos Zoulas regarding prtgif bounding box.
  34.    Text objects was generating wrong boudning boxes.
  35. 2) When text objects are saved, its bounding boxes are also saved now.
  36.    This fixes the problem in 1).  File version is bumped to 7!
  37. 3) Fix bugs in select.c (change calls to DelObj () to FreeObj ()).
  38.    This caused segmentation faults when tgif is dbx-ed, it caused
  39.    XError when not dbx-ed.
  40. 4) Prtgif is cleaned up to share functions with the tgif code.  (Turned
  41.    out to be a lot of changes.)
  42. 5) Add double-clicking in selecting file names.  New Xdefaults
  43.    Tgif*DoubleClickInterval (in milli-seconds) is added.
  44.  
  45. tgif-1.11 => tgif-1.12
  46.  
  47. 1) Fix bugs related to stretching boxes and ovals.  It used to complain
  48.    that object width or height is ZERO while it's not.
  49. 2) Fix a minor bug related to a seg fault when exiting tgif.  This doesn't
  50.    really cause problem before.
  51.  
  52. ---------------------------------> cut here <---------------------------------
  53. *** attr.c.orig    Thu Aug  2 09:42:50 1990
  54. --- attr.c    Thu Aug  2 09:42:52 1990
  55. ***************
  56. *** 6,10 ****
  57.   #ifndef lint
  58.   static char RCSid[] =
  59. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/attr.c,v 1.4 90/06/26 00:03:55 william Exp $";
  60.   #endif
  61.   
  62. --- 6,10 ----
  63.   #ifndef lint
  64.   static char RCSid[] =
  65. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/attr.c,v 1.6 90/07/30 11:09:21 william Exp $";
  66.   #endif
  67.   
  68. ***************
  69. *** 484,488 ****
  70.   static
  71.   char * ReadAttrString (Str)
  72. !    char *    Str;
  73.   {
  74.      register char    * s = Str;
  75. --- 484,488 ----
  76.   static
  77.   char * ReadAttrString (Str)
  78. !    char    * Str;
  79.   {
  80.      register char    * s = Str;
  81. ***************
  82. *** 496,502 ****
  83.   }
  84.   
  85. ! int  ReadAttr (FP, AttrPtr)
  86.      FILE            * FP;
  87.      struct AttrRec    * * AttrPtr;
  88.   {
  89.      struct ObjRec    * TextObj;
  90. --- 496,503 ----
  91.   }
  92.   
  93. ! int ReadAttr (FP, AttrPtr, PRTGIF)
  94.      FILE            * FP;
  95.      struct AttrRec    * * AttrPtr;
  96. +    int            PRTGIF;
  97.   {
  98.      struct ObjRec    * TextObj;
  99. ***************
  100. *** 505,509 ****
  101.      int            len, shown, nameshown, inherited;
  102.    
  103. !    fgets (inbuf, 255, FP); 
  104.   
  105.      if (inbuf[0] == ']')  return (FALSE);
  106. --- 506,510 ----
  107.      int            len, shown, nameshown, inherited;
  108.    
  109. !    fgets (inbuf, MAXSTRING, FP); 
  110.   
  111.      if (inbuf[0] == ']')  return (FALSE);
  112. ***************
  113. *** 533,537 ****
  114.      (*AttrPtr)->inherited = inherited;
  115.   
  116. !    ReadObj (FP, &TextObj);
  117.      TextObj->detail.t->attr = *AttrPtr;
  118.      (*AttrPtr)->obj = TextObj;
  119. --- 534,538 ----
  120.      (*AttrPtr)->inherited = inherited;
  121.   
  122. !    ReadObj (FP, &TextObj, PRTGIF);
  123.      TextObj->detail.t->attr = *AttrPtr;
  124.      (*AttrPtr)->obj = TextObj;
  125. ***************
  126. *** 1015,1019 ****
  127.      int            * fore_colors, * pixel_ptr, * valid, * flag_ptr;
  128.      int            len1, len2;
  129. !    char            * * attrStrs, * s, buf[256], msg[80];
  130.      unsigned int        button;
  131.   
  132. --- 1016,1020 ----
  133.      int            * fore_colors, * pixel_ptr, * valid, * flag_ptr;
  134.      int            len1, len2;
  135. !    char            * * attrStrs, * s, buf[MAXSTRING], msg[80];
  136.      unsigned int        button;
  137.   
  138. *** box.c.orig    Thu Aug  2 09:43:01 1990
  139. --- box.c    Thu Aug  2 09:43:02 1990
  140. ***************
  141. *** 6,10 ****
  142.   #ifndef lint
  143.   static char RCSid[] =
  144. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/box.c,v 1.4 90/06/26 00:04:27 william Exp $";
  145.   #endif
  146.   
  147. --- 6,10 ----
  148.   #ifndef lint
  149.   static char RCSid[] =
  150. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/box.c,v 1.5 90/07/16 10:29:15 william Exp $";
  151.   #endif
  152.   
  153. ***************
  154. *** 19,24 ****
  155.   #include "grid.e"
  156.   #include "obj.e"
  157. - #include "poly.e"
  158.   #include "pattern.e"
  159.   #include "raster.e"
  160.   #include "ruler.e"
  161. --- 19,24 ----
  162.   #include "grid.e"
  163.   #include "obj.e"
  164.   #include "pattern.e"
  165. + #include "poly.e"
  166.   #include "raster.e"
  167.   #include "ruler.e"
  168. *** color.c.orig    Thu Aug  2 09:43:08 1990
  169. --- color.c    Thu Aug  2 09:43:10 1990
  170. ***************
  171. *** 6,10 ****
  172.   #ifndef lint
  173.   static char RCSid[] =
  174. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/color.c,v 1.9 90/06/26 00:04:37 william Exp $";
  175.   #endif
  176.   
  177. --- 6,10 ----
  178.   #ifndef lint
  179.   static char RCSid[] =
  180. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/color.c,v 1.11 90/07/31 15:11:08 william Exp $";
  181.   #endif
  182.   
  183. ***************
  184. *** 368,370 ****
  185. --- 368,384 ----
  186.      if (index != INVALID) ChangeAllSelColor (index);
  187.      cfree (pixmap);
  188. + }
  189. + void CleanUpColors ()
  190. + {
  191. +    register int    i;
  192. +    cfree (colorPixels);
  193. +    cfree (xorColorPixels);
  194. +    if (colorDisplay) for (i = 0; i < maxColors; i++) cfree (colorMenuItems[i]);
  195. +    cfree (colorMenuItems);
  196. +    maxColors = MAXCOLORS;
  197. +    defaultColorIndex = 4;
  198. +    colorIndex = 0;
  199.   }
  200. *** cursor.c.orig    Thu Aug  2 09:43:16 1990
  201. --- cursor.c    Thu Aug  2 09:43:17 1990
  202. ***************
  203. *** 6,10 ****
  204.   #ifndef lint
  205.   static char RCSid[] =
  206. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/cursor.c,v 1.2 90/05/22 14:08:44 william Exp $";
  207.   #endif
  208.   
  209. --- 6,10 ----
  210.   #ifndef lint
  211.   static char RCSid[] =
  212. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/cursor.c,v 1.5 90/07/16 10:31:01 william Exp $";
  213.   #endif
  214.   
  215. ***************
  216. *** 11,16 ****
  217.   #include <X11/Xlib.h>
  218.   #include <X11/cursorfont.h>
  219. - #include "types.h"
  220.   #include "const.h"
  221.   
  222.   #include "choice.e"
  223. --- 11,16 ----
  224.   #include <X11/Xlib.h>
  225.   #include <X11/cursorfont.h>
  226.   #include "const.h"
  227. + #include "types.h"
  228.   
  229.   #include "choice.e"
  230. *** dialog.c.orig    Thu Aug  2 09:43:24 1990
  231. --- dialog.c    Thu Aug  2 09:43:25 1990
  232. ***************
  233. *** 6,10 ****
  234.   #ifndef lint
  235.   static char RCSid[] =
  236. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/dialog.c,v 1.4 90/05/25 13:36:58 william Exp $";
  237.   #endif
  238.   
  239. --- 6,10 ----
  240.   #ifndef lint
  241.   static char RCSid[] =
  242. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/dialog.c,v 1.5 90/07/12 09:01:47 william Exp $";
  243.   #endif
  244.   
  245. ***************
  246. *** 117,121 ****
  247.            key_code = key_ev->keycode;
  248.            XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
  249. !          if ((buf[0]=='\r' && (key_sym & 0xff)=='\r') ||
  250.                  (buf[0]=='\n' && (key_sym & 0xff)=='\n') ||
  251.                  (buf[0]=='\b' && (key_sym & 0xff)=='\b') ||
  252. --- 117,122 ----
  253.            key_code = key_ev->keycode;
  254.            XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
  255. !          if ((buf[0]=='\033' && (key_sym & 0xff)=='\033') ||
  256. !                (buf[0]=='\r' && (key_sym & 0xff)=='\r') ||
  257.                  (buf[0]=='\n' && (key_sym & 0xff)=='\n') ||
  258.                  (buf[0]=='\b' && (key_sym & 0xff)=='\b') ||
  259. ***************
  260. *** 127,130 ****
  261. --- 128,135 ----
  262.               switch (buf[0])
  263.               {
  264. +                case '\033':
  265. +                   ReturnStr[0] = '\0';
  266. +                   dialoging = FALSE;
  267. +                   break;
  268.                  case '\r':
  269.                  case '\n':
  270. *** drawing.c.orig    Thu Aug  2 09:43:40 1990
  271. --- drawing.c    Thu Aug  2 09:43:42 1990
  272. ***************
  273. *** 6,10 ****
  274.   #ifndef lint
  275.   static char RCSid[] =
  276. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/drawing.c,v 1.3 90/05/22 14:10:35 william Exp $";
  277.   #endif
  278.   
  279. --- 6,10 ----
  280.   #ifndef lint
  281.   static char RCSid[] =
  282. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/drawing.c,v 1.8 90/07/29 15:34:38 william Exp $";
  283.   #endif
  284.   
  285. ***************
  286. *** 30,35 ****
  287.   #include "menu.e"
  288.   #include "msg.e"
  289. - #include "oval.e"
  290.   #include "obj.e"
  291.   #include "pattern.e"
  292.   #include "poly.e"
  293. --- 30,35 ----
  294.   #include "menu.e"
  295.   #include "msg.e"
  296.   #include "obj.e"
  297. + #include "oval.e"
  298.   #include "pattern.e"
  299.   #include "poly.e"
  300. ***************
  301. *** 471,475 ****
  302.               case '\016': /*^N*/ NewProc (); break;
  303.               case '\017': /*^O*/ OpenProc (); break;
  304. !             case '\020': /*^P*/ Dump (); break;
  305.               case '\021': /*^Q*/ return (QuitProc ());
  306.               case '\022': /*^R*/ ClearAndRedrawDrawWindow (); break;
  307. --- 471,475 ----
  308.               case '\016': /*^N*/ NewProc (); break;
  309.               case '\017': /*^O*/ OpenProc (); break;
  310. !             case '\020': /*^P*/ Dump (FALSE, ""); break;
  311.               case '\021': /*^Q*/ return (QuitProc ());
  312.               case '\022': /*^R*/ ClearAndRedrawDrawWindow (); break;
  313. ***************
  314. *** 530,537 ****
  315.            switch (buf[0])
  316.            {
  317. !             case '\001': /*^#A*/ break;
  318.               case '\002': /*^#B*/ ChangeFontStyle (STYLE_BR); break;
  319.               case '\003': /*^#C*/ ChangeFontJust (JUST_C); break;
  320. !             case '\004': /*^#D*/ break;
  321.               case '\005': /*^#E*/ break;
  322.               case '\006': /*^#F*/ break;
  323. --- 530,537 ----
  324.            switch (buf[0])
  325.            {
  326. !             case '\001': /*^#A*/ AddPoint (); break;
  327.               case '\002': /*^#B*/ ChangeFontStyle (STYLE_BR); break;
  328.               case '\003': /*^#C*/ ChangeFontJust (JUST_C); break;
  329. !             case '\004': /*^#D*/ DeletePoint (); break;
  330.               case '\005': /*^#E*/ break;
  331.               case '\006': /*^#F*/ break;
  332. ***************
  333. *** 552,556 ****
  334.               case '\025': /*^#U*/ break;
  335.               case '\026': /*^#V*/ SetCurChoice (DRAWCIRCLE); break;
  336. !             case '\027': /*^#W*/ break;
  337.               case '\030': /*^#X*/ break;
  338.               case '\031': /*^#Y*/ break;
  339. --- 552,556 ----
  340.               case '\025': /*^#U*/ break;
  341.               case '\026': /*^#V*/ SetCurChoice (DRAWCIRCLE); break;
  342. !             case '\027': /*^#W*/ ToggleAllSelLineType (); break;
  343.               case '\030': /*^#X*/ break;
  344.               case '\031': /*^#Y*/ break;
  345. *** dup.c.orig    Thu Aug  2 09:43:49 1990
  346. --- dup.c    Thu Aug  2 09:43:51 1990
  347. ***************
  348. *** 6,10 ****
  349.   #ifndef lint
  350.   static char RCSid[] =
  351. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/dup.c,v 1.2 90/06/26 00:04:49 william Exp $";
  352.   #endif
  353.   
  354. --- 6,10 ----
  355.   #ifndef lint
  356.   static char RCSid[] =
  357. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/dup.c,v 1.3 90/07/08 00:29:43 william Exp $";
  358.   #endif
  359.   
  360. ***************
  361. *** 306,308 ****
  362. --- 306,342 ----
  363.      HighLightForward ();
  364.      SetFileModified (TRUE);
  365. + }
  366. + void JustDupSelObj (NewTopSel, NewBotSel)
  367. +    struct SelRec    * * NewTopSel, * * NewBotSel;
  368. + {
  369. +    struct SelRec    * sel_ptr, * new_sel_ptr;
  370. +    struct ObjRec    * obj_ptr, * top_obj, * bot_obj;
  371. +    *NewTopSel = *NewBotSel = NULL;
  372. +    if (topSel == NULL) return;
  373. +    top_obj = bot_obj = NULL;
  374. +    for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
  375. +    {
  376. +       obj_ptr = DupObj (sel_ptr->obj);
  377. +       obj_ptr->next = top_obj;
  378. +       new_sel_ptr = (struct SelRec *) calloc (1, sizeof (struct SelRec));
  379. +       new_sel_ptr->next = *NewTopSel;
  380. +       new_sel_ptr->obj = obj_ptr;
  381. +       if (top_obj == NULL)
  382. +       {
  383. +          bot_obj = obj_ptr;
  384. +          *NewBotSel = new_sel_ptr;
  385. +       }
  386. +       else
  387. +       {
  388. +          top_obj->prev = obj_ptr;
  389. +          (*NewTopSel)->prev = new_sel_ptr;
  390. +       }
  391. +       top_obj = obj_ptr;
  392. +       *NewTopSel = new_sel_ptr;
  393. +    }
  394. +    top_obj->prev = NULL;
  395. +    (*NewTopSel)->prev = NULL;
  396.   }
  397. *** edit.c.orig    Thu Aug  2 09:43:59 1990
  398. --- edit.c    Thu Aug  2 09:44:01 1990
  399. ***************
  400. *** 6,13 ****
  401.   #ifndef lint
  402.   static char RCSid[] =
  403. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/edit.c,v 1.2 90/06/26 00:04:59 william Exp $";
  404.   #endif
  405.   
  406.   #include <stdio.h>
  407.   #include <X11/Xlib.h>
  408.   #include "const.h"
  409. --- 6,14 ----
  410.   #ifndef lint
  411.   static char RCSid[] =
  412. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/edit.c,v 1.6 90/07/13 12:51:58 william Exp $";
  413.   #endif
  414.   
  415.   #include <stdio.h>
  416. + #include <math.h>
  417.   #include <X11/Xlib.h>
  418.   #include "const.h"
  419. ***************
  420. *** 16,29 ****
  421. --- 17,41 ----
  422.   #include "align.e"
  423.   #include "color.e"
  424. + #include "cursor.e"
  425.   #include "drawing.e"
  426.   #include "dup.e"
  427. + #include "font.e"
  428.   #include "group.e"
  429.   #include "mark.e"
  430.   #include "obj.e"
  431. + #include "poly.e"
  432.   #include "raster.e"
  433.   #include "select.e"
  434.   #include "setup.e"
  435. + #include "spline.e"
  436.   #include "stretch.e"
  437.   
  438. + #define OFFSET_X(x) (((x) - drawOrigX) >> zoomScale)
  439. + #define OFFSET_Y(y) (((y) - drawOrigY) >> zoomScale)
  440. + #define MARK(X,Y) \
  441. +       XFillRectangle(mainDisplay,drawWindow,revDefaultGC,(X)-2,(Y)-2,5,5)
  442. + #define MyDashedLine(W,GC,V,N) XDrawLines (mainDisplay, W, GC, V, N, \
  443. +       CoordModeOrigin)
  444.   #define EDIT_REDRAW 0
  445.   #define EDIT_DUP 1
  446. ***************
  447. *** 31,44 ****
  448.   #define EDIT_SELALL 3
  449.   #define EDIT_UNDODEL 4
  450. ! #define MAXEDITMENUS 5
  451.   
  452.   static char * editMenuStr[] =
  453. !       { "Redraw     ^R",
  454. !         "Duplicate  ^D",
  455. !         "Delete     ^X",
  456. !         "SelectAll  ^A",
  457. !         "UndoDelete #U"
  458.         };
  459.   
  460.   void EditMenu (X, Y)
  461.      int    X, Y;
  462. --- 43,664 ----
  463.   #define EDIT_SELALL 3
  464.   #define EDIT_UNDODEL 4
  465. ! #define EDIT_DEL_POINT 5
  466. ! #define EDIT_ADD_POINT 6
  467.   
  468. + #define MAXEDITMENUS 7
  469.   static char * editMenuStr[] =
  470. !       { "Redraw       ^R",
  471. !         "Duplicate    ^D",
  472. !         "Delete       ^X",
  473. !         "SelectAll    ^A",
  474. !         "UndoDelete   #U",
  475. !         "DeletePoint ^#D",
  476. !         "AddPoint    ^#A"
  477.         };
  478.   
  479. + void DeletePoint ()
  480. + {
  481. +    register int            i;
  482. +    register struct ObjRec    * obj_ptr;
  483. +    struct PolyRec        * poly_ptr;
  484. +    struct PolygonRec        * polygon_ptr;
  485. +    int                index, n, point_deleted, deleting = TRUE;
  486. +    int                root_x, root_y, old_x, old_y;
  487. +    unsigned int            status;
  488. +    Window            root_win, child_win;
  489. +    XEvent            input;
  490. +    if (!(topSel != NULL && topSel == botSel &&
  491. +          (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON)))
  492. +    {
  493. +       Msg ("Please select only one POLY or POLYGON object.");
  494. +       return;
  495. +    }
  496. +    obj_ptr = topSel->obj;
  497. +    switch (obj_ptr->type)
  498. +    {
  499. +       case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break;
  500. +       case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break;
  501. +    }
  502. +    TwoLineMsg ("Click left mouse button to DELETE points.",
  503. +          "Click other buttons to quit.");
  504. +    XGrabPointer (mainDisplay, drawWindow, False,
  505. +          PointerMotionMask | ButtonPressMask,
  506. +          GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime);
  507. +    XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
  508. +          &root_x, &root_y, &old_x, &old_y, &status);
  509. +    XDrawString (mainDisplay, drawWindow, revDefaultGC,
  510. +          old_x+4, old_y+defaultFontAsc, "DEL", 3);
  511. +    MarkRulers (old_x, old_y);
  512. +    while (deleting)
  513. +    {
  514. +       XNextEvent (mainDisplay, &input);
  515. +       if (input.type == ButtonPress)
  516. +       {
  517. +          if (input.xbutton.button == Button1)
  518. +          {
  519. +             point_deleted = FALSE;
  520. +             if (obj_ptr->type == OBJ_POLY &&
  521. +                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
  522. +                   poly_ptr->n, poly_ptr->vlist, &index) ||
  523. +                   obj_ptr->type == OBJ_POLYGON &&
  524. +                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
  525. +                   polygon_ptr->n-1, polygon_ptr->vlist, &index))
  526. +             {
  527. +                point_deleted = TRUE;
  528. +                HighLightReverse ();
  529. +                if (obj_ptr->type == OBJ_POLY && poly_ptr->n == 2 ||
  530. +                      obj_ptr->type == OBJ_POLYGON && polygon_ptr->n == 4)
  531. +                {
  532. +                   CopySelToCut ();
  533. +                   DelObj (obj_ptr);
  534. +                   deleting = FALSE;
  535. +                   obj_ptr = NULL;
  536. +                   cfree (topSel);
  537. +                   topSel = botSel = NULL;
  538. +                }
  539. +                else
  540. +                {
  541. +                   switch (obj_ptr->type)
  542. +                   {
  543. +                      case OBJ_POLY:
  544. +                         n = poly_ptr->n;
  545. +                         for (i = index+1; i < n; i++)
  546. +                            poly_ptr->vlist[i-1] = poly_ptr->vlist[i];
  547. +                         poly_ptr->n--;
  548. +                         if (poly_ptr->curved)
  549. +                         {
  550. +                            cfree (poly_ptr->svlist);
  551. +                            poly_ptr->svlist = MakeSplinePolyVertex (
  552. +                                  &(poly_ptr->sn), drawOrigX, drawOrigY,
  553. +                                  poly_ptr->n, poly_ptr->vlist);
  554. +                         }
  555. +                         UpdPolyBBox (obj_ptr, poly_ptr->n, poly_ptr->vlist);
  556. +                         break;
  557. +                      case OBJ_POLYGON:
  558. +                         n = polygon_ptr->n;
  559. +                         for (i = index+1; i < n; i++)
  560. +                            polygon_ptr->vlist[i-1] = polygon_ptr->vlist[i];
  561. +                         polygon_ptr->n--;
  562. +                         n--;
  563. +                         if (index == 0)
  564. +                            polygon_ptr->vlist[n-1] = polygon_ptr->vlist[0];
  565. +                         if (polygon_ptr->curved)
  566. +                         {
  567. +                            cfree (polygon_ptr->svlist);
  568. +                            polygon_ptr->svlist = MakeSplinePolygonVertex (
  569. +                                  &(polygon_ptr->sn), drawOrigX, drawOrigY,
  570. +                                  polygon_ptr->n, polygon_ptr->vlist);
  571. +                         }
  572. +                         UpdPolyBBox (obj_ptr, polygon_ptr->n,
  573. +                               polygon_ptr->vlist);
  574. +                         break;
  575. +                   }
  576. +                   AdjObjBBox (obj_ptr);
  577. +                }
  578. +             }
  579. +             if (point_deleted)
  580. +             {
  581. +                XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4,
  582. +                      old_y+defaultFontAsc, "DEL", 3);
  583. +                old_x = input.xbutton.x;
  584. +                old_y = input.xbutton.y;
  585. +                RedrawAnArea (botObj,
  586. +                      selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
  587. +                      selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
  588. +                HighLightForward ();
  589. +                if (obj_ptr != NULL)
  590. +                   XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4,
  591. +                         old_y+defaultFontAsc, "DEL", 3);
  592. +                UpdSelBBox ();
  593. +                SetFileModified (TRUE);
  594. +             }
  595. +          }
  596. +          else
  597. +          {
  598. +             deleting = FALSE;
  599. +             XDrawString (mainDisplay, drawWindow, revDefaultGC,
  600. +                   old_x+4, old_y+defaultFontAsc, "DEL", 3);
  601. +          }
  602. +       }
  603. +       else if (input.type == MotionNotify)
  604. +       {
  605. +          XDrawString (mainDisplay, drawWindow, revDefaultGC,
  606. +                old_x+4, old_y+defaultFontAsc, "DEL", 3);
  607. +          old_x = input.xmotion.x;
  608. +          old_y = input.xmotion.y;
  609. +          XDrawString (mainDisplay, drawWindow, revDefaultGC,
  610. +                old_x+4, old_y+defaultFontAsc, "DEL", 3);
  611. +          MarkRulers (old_x, old_y);
  612. +       }
  613. +    }
  614. +    XUngrabPointer (mainDisplay, CurrentTime);
  615. +    Msg ("");
  616. + }
  617. + static
  618. + void ContinueAddPolyPoint (ObjPtr, MouseX, MouseY, Index, PolyPtr,
  619. +       LastMouseX, LastMouseY)
  620. +    struct ObjRec    * ObjPtr;
  621. +    int            MouseX, MouseY, Index;
  622. +    struct PolyRec    * PolyPtr;
  623. +    int            * LastMouseX, * LastMouseY;
  624. +    /* (MouseX,MouseY) is the mouse's origin in screen offsets */
  625. + {
  626. +    int        n = PolyPtr->n, already_moved=FALSE, done=FALSE, before;
  627. +    XPoint    * vs = PolyPtr->vlist, v[3];
  628. +    int        prev_x, prev_y, x, y, next_x, next_y, new_x, new_y, dx, dy;
  629. +    int        orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y;
  630. + /* int        prev_dist, next_dist, new_prev_dist, new_next_dist; */
  631. +    int        sel_ltx, sel_lty, sel_rbx, sel_rby, num, i;
  632. +    double    prev_angle, next_angle, new_angle, theta_1, theta_2;
  633. +    XEvent    input;
  634. +    MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
  635. +    sel_ltx =  selLtX; sel_lty = selLtY;
  636. +    sel_rbx =  selRbX; sel_rby = selRbY;
  637. +    x = vs[Index].x;
  638. +    y = vs[Index].y;
  639. +    if (Index == 0)
  640. +    {
  641. +       next_x = vs[1].x;    next_y = vs[1].y;
  642. +       prev_x = 2*x-next_x; prev_y = 2*y-next_y;
  643. + /*    prev_dist = next_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
  644. +    }
  645. +    else if (Index == n-1)
  646. +    {
  647. +       prev_x = vs[n-2].x;  prev_y = vs[n-2].y;
  648. +       next_x = 2*x-prev_x; next_y = 2*y-prev_y;
  649. + /*    prev_dist = next_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
  650. +    }
  651. +    else
  652. +    {
  653. +       prev_x = vs[Index-1].x; prev_y = vs[Index-1].y;
  654. +       next_x = vs[Index+1].x; next_y = vs[Index+1].y;
  655. + /*    prev_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
  656. + /*    next_dist = (x-next_x)*(x-next_x) + (y-next_y)*(y-next_y); */
  657. +    }
  658. +    prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x));
  659. +    next_angle = atan2 ((double)(next_y-y), (double)(next_x-x));
  660. +    GridXY (MouseX, MouseY, &orig_x, &orig_y);
  661. +    new_mouse_x = MouseX; new_mouse_y = MouseY;
  662. +    XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  663. +          new_mouse_y+defaultFontAsc, "ADD", 3);
  664. +    while (!done)
  665. +    {
  666. +       XNextEvent (mainDisplay, &input);
  667. +       if (input.type == MotionNotify)
  668. +       {
  669. +          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  670. +                new_mouse_y+defaultFontAsc, "ADD", 3);
  671. +          new_mouse_x = input.xmotion.x;
  672. +          new_mouse_y = input.xmotion.y;
  673. +          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  674. +                new_mouse_y+defaultFontAsc, "ADD", 3);
  675. +          GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y);
  676. +          new_x = ((new_mouse_x-MouseX)<<zoomScale) + x;
  677. +          new_y = ((new_mouse_y-MouseY)<<zoomScale) + y;
  678. +          if (!already_moved)
  679. +          {
  680. +             already_moved = TRUE;
  681. +             new_angle = atan2 ((double)(new_y-y), (double)(new_x-x));
  682. +             theta_1 = fabs (prev_angle - new_angle);
  683. +             theta_2 = fabs (next_angle - new_angle);
  684. +             if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1;
  685. +             if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2;
  686. +             before = (theta_1 <= theta_2);
  687. + /*          new_prev_dist = (new_x-prev_x)*(new_x-prev_x) + */
  688. + /*                (new_y-prev_y)*(new_y-prev_y); */
  689. + /*          new_next_dist = (new_x-next_x)*(new_x-next_x) + */
  690. + /*                (new_y-next_y)*(new_y-next_y); */
  691. + /*          if ((new_prev_dist-prev_dist)*(new_next_dist-next_dist) < 0) */
  692. + /*             before = (new_prev_dist < prev_dist); */
  693. + /*          else */
  694. + /*             before = (abs (new_prev_dist-prev_dist) < */
  695. + /*                   abs (new_next_dist-next_dist)); */
  696. +             if (before)
  697. +             {  /* Add a point between the current and the previous point */
  698. +                if (Index == 0)
  699. +                {
  700. +                   num = 2;
  701. +                   v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y);
  702. +                   v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
  703. +                }
  704. +                else
  705. +                {
  706. +                   num = 3;
  707. +                   v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y);
  708. +                   v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
  709. +                   v[2].x = OFFSET_X(x);      v[2].y = OFFSET_Y(y);
  710. +                }
  711. +             }
  712. +             else
  713. +             {  /* Add a point between the current and the next point */
  714. +                if (Index == n-1)
  715. +                {
  716. +                   num = 2;
  717. +                   v[0].x = OFFSET_X(x);      v[0].y = OFFSET_Y(y);
  718. +                   v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
  719. +                }
  720. +                else
  721. +                {
  722. +                   num = 3;
  723. +                   v[0].x = OFFSET_X(x);      v[0].y = OFFSET_Y(y);
  724. +                   v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
  725. +                   v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y);
  726. +                }
  727. +             }
  728. +             MyDashedLine (drawWindow, revDefaultGC, v, num);
  729. +          }
  730. +          else
  731. +          {
  732. +             MyDashedLine (drawWindow, revDefaultGC, v, num);
  733. +             v[1].x = OFFSET_X(x) + grid_x - orig_x;
  734. +             v[1].y = OFFSET_Y(y) + grid_y - orig_y;
  735. +             MyDashedLine (drawWindow, revDefaultGC, v, num);
  736. +             MarkRulers (grid_x, grid_y);
  737. +          }
  738. +       }
  739. +       else if (input.type == ButtonRelease)
  740. +       {
  741. +          done = TRUE;
  742. +          *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y;
  743. +          MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
  744. +          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  745. +                new_mouse_y+defaultFontAsc, "ADD", 3);
  746. +          if (!already_moved)
  747. +             continue;
  748. +          else
  749. +          {
  750. +             MyDashedLine (drawWindow, revDefaultGC, v, num);
  751. +             if (grid_x == orig_x && grid_y == orig_y)
  752. +                continue;
  753. +          }
  754. +          HighLightReverse ();
  755. +          vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint));
  756. +          if (vs == NULL)
  757. +          {
  758. +             printf ("Can not realloc () in ContinueAddPolyPoint ().\n");
  759. +             exit (-1);
  760. +          }
  761. +          PolyPtr->vlist = vs;
  762. +          if (before)
  763. +          {
  764. +             for (i = n-1; i >= Index; i--) vs[i+1] = vs[i];
  765. +             vs[Index].x = x + ((grid_x-orig_x)<<zoomScale);
  766. +             vs[Index].y = y + ((grid_y-orig_y)<<zoomScale);
  767. +          }
  768. +          else
  769. +          {
  770. +             for (i = n-1; i > Index; i--) vs[i+1] = vs[i];
  771. +             vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale);
  772. +             vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale);
  773. +          }
  774. +          PolyPtr->n++;
  775. +          n++;
  776. +          if (PolyPtr->curved)
  777. +          {
  778. +             cfree (PolyPtr->svlist);
  779. +             PolyPtr->svlist = MakeSplinePolyVertex (&(PolyPtr->sn),
  780. +                   drawOrigX, drawOrigY, PolyPtr->n, PolyPtr->vlist);
  781. +          }
  782. +          UpdPolyBBox (ObjPtr, PolyPtr->n, PolyPtr->vlist);
  783. +          AdjObjBBox (ObjPtr);
  784. +          UpdSelBBox ();
  785. +          RedrawAreas (botObj,
  786. +                sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
  787. +                sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
  788. +                selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
  789. +                selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
  790. +          HighLightForward ();
  791. +          SetFileModified (TRUE);
  792. +       }
  793. +    }
  794. + }
  795. + static
  796. + void ContinueAddPolygonPoint (ObjPtr, MouseX, MouseY, Index, PolygonPtr,
  797. +       LastMouseX, LastMouseY)
  798. +    struct ObjRec    * ObjPtr;
  799. +    int            MouseX, MouseY, Index;
  800. +    struct PolygonRec    * PolygonPtr;
  801. +    int            * LastMouseX, * LastMouseY;
  802. +    /* (MouseX,MouseY) is the mouse's origin in screen offsets */
  803. + {
  804. +    int        n = PolygonPtr->n, already_moved=FALSE, done=FALSE, before;
  805. +    XPoint    * vs = PolygonPtr->vlist, v[3];
  806. +    int        prev_x, prev_y, x, y, next_x, next_y, new_x, new_y, dx, dy;
  807. +    int        orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y;
  808. + /* int        prev_dist, next_dist, new_prev_dist, new_next_dist; */
  809. +    int        sel_ltx, sel_lty, sel_rbx, sel_rby, i;
  810. +    double    prev_angle, next_angle, new_angle, theta_1, theta_2;
  811. +    XEvent    input;
  812. +    MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
  813. +    sel_ltx =  selLtX; sel_lty = selLtY;
  814. +    sel_rbx =  selRbX; sel_rby = selRbY;
  815. +    x = vs[Index].x;
  816. +    y = vs[Index].y;
  817. +    if (Index == 0 || Index == n-1)
  818. +    {
  819. +       next_x = vs[1].x;   next_y = vs[1].y;
  820. +       prev_x = vs[n-2].x; prev_y = vs[n-2].y;
  821. +    }
  822. +    else
  823. +    {
  824. +       prev_x = vs[Index-1].x; prev_y = vs[Index-1].y;
  825. +       next_x = vs[Index+1].x; next_y = vs[Index+1].y;
  826. +    }
  827. +    prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x));
  828. +    next_angle = atan2 ((double)(next_y-y), (double)(next_x-x));
  829. + /* prev_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
  830. + /* next_dist = (x-next_x)*(x-next_x) + (y-next_y)*(y-next_y); */
  831. +    GridXY (MouseX, MouseY, &orig_x, &orig_y);
  832. +    new_mouse_x = MouseX; new_mouse_y = MouseY;
  833. +    XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  834. +          new_mouse_y+defaultFontAsc, "ADD", 3);
  835. +    while (!done)
  836. +    {
  837. +       XNextEvent (mainDisplay, &input);
  838. +       if (input.type == MotionNotify)
  839. +       {
  840. +          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  841. +                new_mouse_y+defaultFontAsc, "ADD", 3);
  842. +          new_mouse_x = input.xmotion.x;
  843. +          new_mouse_y = input.xmotion.y;
  844. +          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  845. +                new_mouse_y+defaultFontAsc, "ADD", 3);
  846. +          GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y);
  847. +          new_x = ((new_mouse_x-MouseX)<<zoomScale) + x;
  848. +          new_y = ((new_mouse_y-MouseY)<<zoomScale) + y;
  849. +          if (!already_moved)
  850. +          {
  851. +             already_moved = TRUE;
  852. +             new_angle = atan2 ((double)(new_y-y), (double)(new_x-x));
  853. +             theta_1 = fabs (prev_angle - new_angle);
  854. +             theta_2 = fabs (next_angle - new_angle);
  855. +             if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1;
  856. +             if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2;
  857. +             before = (theta_1 <= theta_2);
  858. + /*          new_prev_dist = (new_x-prev_x)*(new_x-prev_x) + */
  859. + /*                (new_y-prev_y)*(new_y-prev_y); */
  860. + /*          new_next_dist = (new_x-next_x)*(new_x-next_x) + */
  861. + /*                (new_y-next_y)*(new_y-next_y); */
  862. + /*          if ((new_prev_dist-prev_dist)*(new_next_dist-next_dist) < 0) */
  863. + /*             before = (new_prev_dist < prev_dist); */
  864. + /*          else */
  865. + /*             before = (abs (new_prev_dist-prev_dist) < */
  866. + /*                   abs (new_next_dist-next_dist)); */
  867. +             if (before)
  868. +             {  /* Add a point between the current and the previous point */
  869. +                v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y);
  870. +                v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
  871. +                v[2].x = OFFSET_X(x);      v[2].y = OFFSET_Y(y);
  872. +             }
  873. +             else
  874. +             {  /* Add a point between the current and the next point */
  875. +                v[0].x = OFFSET_X(x);      v[0].y = OFFSET_Y(y);
  876. +                v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
  877. +                v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y);
  878. +             }
  879. +             MyDashedLine (drawWindow, revDefaultGC, v, 3);
  880. +          }
  881. +          else
  882. +          {
  883. +             MyDashedLine (drawWindow, revDefaultGC, v, 3);
  884. +             v[1].x = OFFSET_X(x) + grid_x - orig_x;
  885. +             v[1].y = OFFSET_Y(y) + grid_y - orig_y;
  886. +             MyDashedLine (drawWindow, revDefaultGC, v, 3);
  887. +             MarkRulers (grid_x, grid_y);
  888. +          }
  889. +       }
  890. +       else if (input.type == ButtonRelease)
  891. +       {
  892. +          done = TRUE;
  893. +          *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y;
  894. +          MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
  895. +          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
  896. +                new_mouse_y+defaultFontAsc, "ADD", 3);
  897. +          if (!already_moved)
  898. +             continue;
  899. +          else
  900. +          {
  901. +             MyDashedLine (drawWindow, revDefaultGC, v, 3);
  902. +             if (grid_x == orig_x && grid_y == orig_y)
  903. +                continue;
  904. +          }
  905. +          HighLightReverse ();
  906. +          vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint));
  907. +          if (vs == NULL)
  908. +          {
  909. +             printf ("Can not realloc () in ContinueAddPolygonPoint ().\n");
  910. +             exit (-1);
  911. +          }
  912. +          PolygonPtr->vlist = vs;
  913. +          if (Index == 0 || Index == n-1)
  914. +          {
  915. +             if (before)
  916. +             {
  917. +                vs[n].x = vs[n-1].x;
  918. +                vs[n].y = vs[n-1].y;
  919. +                vs[n-1].x = x + ((grid_x-orig_x)<<zoomScale);
  920. +                vs[n-1].y = y + ((grid_y-orig_y)<<zoomScale);
  921. +             }
  922. +             else
  923. +             {
  924. +                for (i = n-1; i > 0; i--) vs[i+1] = vs[i];
  925. +                vs[1].x = x + ((grid_x-orig_x)<<zoomScale);
  926. +                vs[1].y = y + ((grid_y-orig_y)<<zoomScale);
  927. +             }
  928. +          }
  929. +          else
  930. +          {
  931. +             if (before)
  932. +             {
  933. +                for (i = n-1; i >= Index; i--) vs[i+1] = vs[i];
  934. +                vs[Index].x = x + ((grid_x-orig_x)<<zoomScale);
  935. +                vs[Index].y = y + ((grid_y-orig_y)<<zoomScale);
  936. +             }
  937. +             else
  938. +             {
  939. +                for (i = n-1; i > Index; i--) vs[i+1] = vs[i];
  940. +                vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale);
  941. +                vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale);
  942. +             }
  943. +          }
  944. +          PolygonPtr->n++;
  945. +          n++;
  946. +          if (PolygonPtr->curved)
  947. +          {
  948. +             cfree (PolygonPtr->svlist);
  949. +             PolygonPtr->svlist = MakeSplinePolygonVertex (&(PolygonPtr->sn),
  950. +                   drawOrigX, drawOrigY, PolygonPtr->n, PolygonPtr->vlist);
  951. +          }
  952. +          UpdPolyBBox (ObjPtr, PolygonPtr->n, PolygonPtr->vlist);
  953. +          AdjObjBBox (ObjPtr);
  954. +          UpdSelBBox ();
  955. +          RedrawAreas (botObj,
  956. +                sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
  957. +                sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
  958. +                selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
  959. +                selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
  960. +          HighLightForward ();
  961. +          SetFileModified (TRUE);
  962. +       }
  963. +    }
  964. + }
  965. + void AddPoint ()
  966. + {
  967. +    register int            i;
  968. +    register struct ObjRec    * obj_ptr;
  969. +    struct PolyRec        * poly_ptr;
  970. +    struct PolygonRec        * polygon_ptr;
  971. +    int                index, n, point_deleted, adding = TRUE;
  972. +    int                root_x, root_y, old_x, old_y;
  973. +    unsigned int            status;
  974. +    Window            root_win, child_win;
  975. +    XEvent            input;
  976. +    if (!(topSel != NULL && topSel == botSel &&
  977. +          (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON)))
  978. +    {
  979. +       Msg ("Please select only one POLY or POLYGON object.");
  980. +       return;
  981. +    }
  982. +    obj_ptr = topSel->obj;
  983. +    switch (obj_ptr->type)
  984. +    {
  985. +       case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break;
  986. +       case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break;
  987. +    }
  988. +    TwoLineMsg ("Drag left mouse button to ADD points.",
  989. +          "Click other buttons to quit.");
  990. +    XGrabPointer (mainDisplay, drawWindow, False,
  991. +          PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
  992. +          GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime);
  993. +    XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
  994. +          &root_x, &root_y, &old_x, &old_y, &status);
  995. +    XDrawString (mainDisplay, drawWindow, revDefaultGC,
  996. +          old_x+4, old_y+defaultFontAsc, "ADD", 3);
  997. +    MarkRulers (old_x, old_y);
  998. +    while (adding)
  999. +    {
  1000. +       XNextEvent (mainDisplay, &input);
  1001. +       if (input.type == ButtonPress)
  1002. +       {
  1003. +          if (input.xbutton.button == Button1)
  1004. +          {
  1005. +             XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1006. +                   old_x+4, old_y+defaultFontAsc, "ADD", 3);
  1007. +             if (obj_ptr->type == OBJ_POLY &&
  1008. +                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
  1009. +                   poly_ptr->n, poly_ptr->vlist, &index))
  1010. +                ContinueAddPolyPoint (obj_ptr, input.xbutton.x, input.xbutton.y,
  1011. +                      index, poly_ptr, &old_x, &old_y);
  1012. +             else if (obj_ptr->type == OBJ_POLYGON &&
  1013. +                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
  1014. +                   polygon_ptr->n-1, polygon_ptr->vlist, &index))
  1015. +                ContinueAddPolygonPoint (obj_ptr, input.xbutton.x,
  1016. +                      input.xbutton.y, index, polygon_ptr, &old_x, &old_y);
  1017. +             XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1018. +                   old_x+4, old_y+defaultFontAsc, "ADD", 3);
  1019. +          }
  1020. +          else
  1021. +          {
  1022. +             adding = FALSE;
  1023. +             XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1024. +                   old_x+4, old_y+defaultFontAsc, "ADD", 3);
  1025. +          }
  1026. +       }
  1027. +       else if (input.type == MotionNotify)
  1028. +       {
  1029. +          XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1030. +                old_x+4, old_y+defaultFontAsc, "ADD", 3);
  1031. +          old_x = input.xmotion.x;
  1032. +          old_y = input.xmotion.y;
  1033. +          XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1034. +                old_x+4, old_y+defaultFontAsc, "ADD", 3);
  1035. +          MarkRulers (old_x, old_y);
  1036. +       }
  1037. +    }
  1038. +    XUngrabPointer (mainDisplay, CurrentTime);
  1039. +    Msg ("");
  1040. + }
  1041.   void EditMenu (X, Y)
  1042.      int    X, Y;
  1043. ***************
  1044. *** 57,60 ****
  1045. --- 677,682 ----
  1046.         case EDIT_SELALL: SelAllObj (); break;
  1047.         case EDIT_UNDODEL: UndoDelete (); break;
  1048. +       case EDIT_DEL_POINT: DeletePoint (); break;
  1049. +       case EDIT_ADD_POINT: AddPoint (); break;
  1050.      }
  1051.   }
  1052. *** file.c.orig    Thu Aug  2 09:44:28 1990
  1053. --- file.c    Thu Aug  2 09:44:31 1990
  1054. ***************
  1055. *** 6,10 ****
  1056.   #ifndef lint
  1057.   static char RCSid[] =
  1058. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/file.c,v 1.15 90/06/26 13:03:47 william Exp $";
  1059.   #endif
  1060.   
  1061. --- 6,10 ----
  1062.   #ifndef lint
  1063.   static char RCSid[] =
  1064. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/file.c,v 1.28 90/07/30 16:08:30 william Exp $";
  1065.   #endif
  1066.   
  1067. ***************
  1068. *** 12,15 ****
  1069. --- 12,16 ----
  1070.   #include <sys/file.h>
  1071.   #include <stdio.h>
  1072. + #include <signal.h>
  1073.   #include <X11/Xlib.h>
  1074.   #include "const.h"
  1075. ***************
  1076. *** 27,38 ****
  1077.   #include "grid.e"
  1078.   #include "group.e"
  1079.   #include "menu.e"
  1080.   #include "msg.e"
  1081.   #include "names.e"
  1082.   #include "poly.e"
  1083.   #include "polygon.e"
  1084.   #include "obj.e"
  1085.   #include "oval.e"
  1086. - #include "pattern.e"
  1087.   #include "rect.e"
  1088.   #include "ruler.e"
  1089. --- 28,41 ----
  1090.   #include "grid.e"
  1091.   #include "group.e"
  1092. + #include "mainloop.e"
  1093.   #include "menu.e"
  1094.   #include "msg.e"
  1095.   #include "names.e"
  1096. + #include "pattern.e"
  1097.   #include "poly.e"
  1098.   #include "polygon.e"
  1099. + #include "prtgif.e"
  1100.   #include "obj.e"
  1101.   #include "oval.e"
  1102.   #include "rect.e"
  1103.   #include "ruler.e"
  1104. ***************
  1105. *** 43,47 ****
  1106.   #include "text.e"
  1107.   
  1108. ! #define CUR_VERSION 6
  1109.   
  1110.   char    curFileName[MAXPATHLENGTH];
  1111. --- 46,50 ----
  1112.   #include "text.e"
  1113.   
  1114. ! #define CUR_VERSION 7
  1115.   
  1116.   char    curFileName[MAXPATHLENGTH];
  1117. ***************
  1118. *** 134,138 ****
  1119.   
  1120.   static
  1121. ! int SaveTmpFile ()
  1122.      /* return TRUE if file successfully saved */
  1123.   {
  1124. --- 137,142 ----
  1125.   
  1126.   static
  1127. ! int SaveTmpFile (NewFileName)
  1128. !    char    * NewFileName;
  1129.      /* return TRUE if file successfully saved */
  1130.   {
  1131. ***************
  1132. *** 142,146 ****
  1133.      struct ObjRec    * obj_ptr;
  1134.   
  1135. !    strcpy (new_file_name, "tmpmodel");
  1136.   
  1137.      for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
  1138. --- 146,150 ----
  1139.      struct ObjRec    * obj_ptr;
  1140.   
  1141. !    strcpy (new_file_name, NewFileName);
  1142.   
  1143.      for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
  1144. ***************
  1145. *** 355,360 ****
  1146.   }
  1147.   
  1148. ! void ReadState (Inbuf)
  1149.      char    * Inbuf;
  1150.   {
  1151.      char    * s;
  1152. --- 359,365 ----
  1153.   }
  1154.   
  1155. ! void ReadState (Inbuf, PRTGIF)
  1156.      char    * Inbuf;
  1157. +    int    PRTGIF;
  1158.   {
  1159.      char    * s;
  1160. ***************
  1161. *** 369,372 ****
  1162. --- 374,379 ----
  1163.         sscanf (s, "%d", &fileVersion);
  1164.   
  1165. +    if (PRTGIF) return;
  1166.      if (!importingFile)
  1167.      {
  1168. ***************
  1169. *** 419,433 ****
  1170.   }
  1171.   
  1172. ! int ReadObj (FP, ObjPtr)
  1173.      FILE            * FP;
  1174.      struct ObjRec    * * ObjPtr;
  1175.   {
  1176.      char            inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
  1177.      char            * line = NULL, * c_ptr, * s, * s1;
  1178. !    int            len, id, old_len, cur_size, done = FALSE;
  1179. !    int            allocated = FALSE;
  1180. !    struct ObjRec    * tmp_obj_ptr;
  1181. !    struct ObjRec    * tmp_top_obj = NULL, * tmp_bot_obj = NULL;
  1182. !    struct AttrRec       * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  1183.   
  1184.      while (fgets (inbuf, MAXSTRING, FP) != NULL)
  1185. --- 426,438 ----
  1186.   }
  1187.   
  1188. ! int ReadObj (FP, ObjPtr, PRTGIF)
  1189.      FILE            * FP;
  1190.      struct ObjRec    * * ObjPtr;
  1191. +    int            PRTGIF;
  1192.   {
  1193.      char            inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
  1194.      char            * line = NULL, * c_ptr, * s, * s1;
  1195. !    int            len, id, cur_size, done = FALSE, allocated = FALSE;
  1196. !    struct AttrRec    * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  1197.   
  1198.      while (fgets (inbuf, MAXSTRING, FP) != NULL)
  1199. ***************
  1200. *** 444,448 ****
  1201.            strcpy (line, inbuf);
  1202.            c_ptr = &(line[MAXSTRING-1]);
  1203. !          while (fgets (inbuf, MAXSTRING, FP) != NULL && !done)
  1204.            {
  1205.               len = strlen(inbuf);
  1206. --- 449,453 ----
  1207.            strcpy (line, inbuf);
  1208.            c_ptr = &(line[MAXSTRING-1]);
  1209. !          while (!done && fgets (inbuf, MAXSTRING, FP) != NULL)
  1210.            {
  1211.               len = strlen(inbuf);
  1212. ***************
  1213. *** 478,482 ****
  1214.            ReadPolyObj (line, ObjPtr);
  1215.            if (fileVersion != INVALID)
  1216. !             while (ReadAttr (FP, &attr_ptr))
  1217.               {
  1218.                  attr_ptr->owner = *ObjPtr;
  1219. --- 483,487 ----
  1220.            ReadPolyObj (line, ObjPtr);
  1221.            if (fileVersion != INVALID)
  1222. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1223.               {
  1224.                  attr_ptr->owner = *ObjPtr;
  1225. ***************
  1226. *** 510,514 ****
  1227.         else if (strcmp (obj_name, "text") == 0)
  1228.         {
  1229. !          ReadTextObj (FP, line, ObjPtr);
  1230.            if (allocated) cfree (line);
  1231.            return (TRUE);
  1232. --- 515,519 ----
  1233.         else if (strcmp (obj_name, "text") == 0)
  1234.         {
  1235. !          ReadTextObj (FP, line, ObjPtr, PRTGIF);
  1236.            if (allocated) cfree (line);
  1237.            return (TRUE);
  1238. ***************
  1239. *** 522,528 ****
  1240.         else if (strcmp (obj_name, "group") == 0)
  1241.         {
  1242. !          ReadGroupObj (FP, ObjPtr);
  1243.            if (fileVersion != INVALID)
  1244. !             while (ReadAttr (FP, &attr_ptr))
  1245.               {
  1246.                  attr_ptr->owner = *ObjPtr;
  1247. --- 527,533 ----
  1248.         else if (strcmp (obj_name, "group") == 0)
  1249.         {
  1250. !          ReadGroupObj (FP, ObjPtr, PRTGIF);
  1251.            if (fileVersion != INVALID)
  1252. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1253.               {
  1254.                  attr_ptr->owner = *ObjPtr;
  1255. ***************
  1256. *** 544,551 ****
  1257.         else if (strcmp (obj_name, "sym") == 0)
  1258.         {
  1259. !          ReadGroupObj (FP, ObjPtr);
  1260.            (*ObjPtr)->type = OBJ_SYM;
  1261.            if (fileVersion != INVALID)
  1262. !             while (ReadAttr (FP, &attr_ptr))
  1263.               {
  1264.                  attr_ptr->owner = *ObjPtr;
  1265. --- 549,556 ----
  1266.         else if (strcmp (obj_name, "sym") == 0)
  1267.         {
  1268. !          ReadGroupObj (FP, ObjPtr, PRTGIF);
  1269.            (*ObjPtr)->type = OBJ_SYM;
  1270.            if (fileVersion != INVALID)
  1271. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1272.               {
  1273.                  attr_ptr->owner = *ObjPtr;
  1274. ***************
  1275. *** 567,571 ****
  1276.         else if (strcmp (obj_name, "icon") == 0)
  1277.         {
  1278. !          ReadGroupObj (FP, ObjPtr);
  1279.            (*ObjPtr)->type = OBJ_ICON;
  1280.            if (fgets (line, MAXSTRING, FP) == NULL)
  1281. --- 572,576 ----
  1282.         else if (strcmp (obj_name, "icon") == 0)
  1283.         {
  1284. !          ReadGroupObj (FP, ObjPtr, PRTGIF);
  1285.            (*ObjPtr)->type = OBJ_ICON;
  1286.            if (fgets (line, MAXSTRING, FP) == NULL)
  1287. ***************
  1288. *** 588,592 ****
  1289.            strcpy ((*ObjPtr)->detail.r->s, tmp_str);
  1290.            if (fileVersion != INVALID)
  1291. !             while (ReadAttr (FP, &attr_ptr))
  1292.               {
  1293.                  attr_ptr->owner = *ObjPtr;
  1294. --- 593,597 ----
  1295.            strcpy ((*ObjPtr)->detail.r->s, tmp_str);
  1296.            if (fileVersion != INVALID)
  1297. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1298.               {
  1299.                  attr_ptr->owner = *ObjPtr;
  1300. ***************
  1301. *** 608,612 ****
  1302.         else if (strcmp (obj_name, "state") == 0)
  1303.         {
  1304. !          ReadState (line);
  1305.            *ObjPtr = NULL;
  1306.            if (allocated) cfree (line);
  1307. --- 613,617 ----
  1308.         else if (strcmp (obj_name, "state") == 0)
  1309.         {
  1310. !          ReadState (line, PRTGIF);
  1311.            *ObjPtr = NULL;
  1312.            if (allocated) cfree (line);
  1313. ***************
  1314. *** 692,696 ****
  1315.      Msg (s);
  1316.   
  1317. !    while (ReadObj (fp, &obj_ptr))
  1318.         if (obj_ptr != NULL)
  1319.            AddObj (NULL, topObj, obj_ptr);
  1320. --- 697,701 ----
  1321.      Msg (s);
  1322.   
  1323. !    while (ReadObj (fp, &obj_ptr, FALSE))
  1324.         if (obj_ptr != NULL)
  1325.            AddObj (NULL, topObj, obj_ptr);
  1326. ***************
  1327. *** 747,751 ****
  1328.      XClearWindow (mainDisplay, drawWindow);
  1329.   
  1330. !    while (ReadObj (fp, &obj_ptr))
  1331.         if (obj_ptr != NULL)
  1332.         {
  1333. --- 752,756 ----
  1334.      XClearWindow (mainDisplay, drawWindow);
  1335.   
  1336. !    while (ReadObj (fp, &obj_ptr, FALSE))
  1337.         if (obj_ptr != NULL)
  1338.         {
  1339. ***************
  1340. *** 794,809 ****
  1341.   }
  1342.   
  1343. ! void DumpAttrs (FP, AttrPtr)
  1344.      FILE                * FP;
  1345.      register struct AttrRec    * AttrPtr;
  1346.   {
  1347.      for ( ; AttrPtr != NULL; AttrPtr = AttrPtr->prev)
  1348.         if (AttrPtr->shown)
  1349. !          DumpTextObj (FP, AttrPtr->obj);
  1350.   }
  1351.   
  1352. ! void DumpAllObj (FP, ObjPtr)
  1353.      FILE                * FP;
  1354.      register struct ObjRec    * ObjPtr;
  1355.   {
  1356.      register struct ObjRec    * obj_ptr;
  1357. --- 799,816 ----
  1358.   }
  1359.   
  1360. ! void DumpAttrs (FP, AttrPtr, PRTGIF)
  1361.      FILE                * FP;
  1362.      register struct AttrRec    * AttrPtr;
  1363. +    int                PRTGIF;
  1364.   {
  1365.      for ( ; AttrPtr != NULL; AttrPtr = AttrPtr->prev)
  1366.         if (AttrPtr->shown)
  1367. !          DumpTextObj (FP, AttrPtr->obj, PRTGIF);
  1368.   }
  1369.   
  1370. ! void DumpAllObj (FP, ObjPtr, PRTGIF)
  1371.      FILE                * FP;
  1372.      register struct ObjRec    * ObjPtr;
  1373. +    int                PRTGIF;
  1374.   {
  1375.      register struct ObjRec    * obj_ptr;
  1376. ***************
  1377. *** 813,821 ****
  1378.         case OBJ_POLY:
  1379.            DumpPolyObj (FP, ObjPtr);
  1380. !          DumpAttrs (FP, ObjPtr->detail.p->lattr);
  1381.            break;
  1382.         case OBJ_BOX: DumpBoxObj (FP, ObjPtr); break;
  1383.         case OBJ_OVAL: DumpOvalObj (FP, ObjPtr); break;
  1384. !       case OBJ_TEXT: DumpTextObj (FP, ObjPtr); break;
  1385.         case OBJ_POLYGON: DumpPolygonObj (FP, ObjPtr); break;
  1386.         case OBJ_SYM:
  1387. --- 820,828 ----
  1388.         case OBJ_POLY:
  1389.            DumpPolyObj (FP, ObjPtr);
  1390. !          DumpAttrs (FP, ObjPtr->detail.p->lattr, PRTGIF);
  1391.            break;
  1392.         case OBJ_BOX: DumpBoxObj (FP, ObjPtr); break;
  1393.         case OBJ_OVAL: DumpOvalObj (FP, ObjPtr); break;
  1394. !       case OBJ_TEXT: DumpTextObj (FP, ObjPtr, PRTGIF); break;
  1395.         case OBJ_POLYGON: DumpPolygonObj (FP, ObjPtr); break;
  1396.         case OBJ_SYM:
  1397. ***************
  1398. *** 824,829 ****
  1399.            obj_ptr = ObjPtr->detail.r->last;
  1400.            for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
  1401. !             DumpAllObj (FP, obj_ptr);
  1402. !          DumpAttrs (FP, ObjPtr->detail.r->lattr);
  1403.            if (ObjPtr->type == OBJ_SYM) DumpSymOutline (FP, ObjPtr);
  1404.            break;
  1405. --- 831,836 ----
  1406.            obj_ptr = ObjPtr->detail.r->last;
  1407.            for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
  1408. !             DumpAllObj (FP, obj_ptr, PRTGIF);
  1409. !          DumpAttrs (FP, ObjPtr->detail.r->lattr, PRTGIF);
  1410.            if (ObjPtr->type == OBJ_SYM) DumpSymOutline (FP, ObjPtr);
  1411.            break;
  1412. ***************
  1413. *** 875,879 ****
  1414.   }
  1415.   
  1416. ! void Dump ()
  1417.   {
  1418.      register struct ObjRec    * obj_ptr;
  1419. --- 882,888 ----
  1420.   }
  1421.   
  1422. ! void Dump (PRTGIF, FileName)
  1423. !    int    PRTGIF;
  1424. !    char    * FileName;
  1425.   {
  1426.      register struct ObjRec    * obj_ptr;
  1427. ***************
  1428. *** 886,890 ****
  1429.      if (botObj == NULL) { Msg ("No object to print."); return; }
  1430.   
  1431. !    Msg ("Generating print file ...");
  1432.      strcpy (tmp_file, "/tmp/TgifXXXXXX");
  1433.      mktemp (tmp_file);
  1434. --- 895,900 ----
  1435.      if (botObj == NULL) { Msg ("No object to print."); return; }
  1436.   
  1437. !    if (!PRTGIF) Msg ("Generating print file ...");
  1438.      strcpy (tmp_file, "/tmp/TgifXXXXXX");
  1439.      mktemp (tmp_file);
  1440. ***************
  1441. *** 893,901 ****
  1442.      if ((fp = fopen (tmp_file, "w")) == NULL)
  1443.      {
  1444. !       sprintf (tmp_str, "Can not create %s, print aborted.", tmp_file);
  1445. !       Msg (tmp_str);
  1446.         return;
  1447.      }
  1448.   
  1449.      fprintf (fp, "%%!\n");
  1450.      DumpBBox (fp);
  1451. --- 903,918 ----
  1452.      if ((fp = fopen (tmp_file, "w")) == NULL)
  1453.      {
  1454. !       if (PRTGIF)
  1455. !          printf ("Can not create $s, print aborted.", tmp_file);
  1456. !       else
  1457. !       {
  1458. !          sprintf (tmp_str, "Can not create %s, print aborted.", tmp_file);
  1459. !          Msg (tmp_str);
  1460. !       }
  1461.         return;
  1462.      }
  1463.   
  1464. +    if (PRTGIF) printf ("Writing to %s ...\n", tmp_file);
  1465.      fprintf (fp, "%%!\n");
  1466.      DumpBBox (fp);
  1467. ***************
  1468. *** 903,908 ****
  1469.      if ((fps = fopen (ps_file, "r")) == NULL) 
  1470.      {
  1471. !       sprintf (message, "Can not find %s, print aborted.", ps_file);
  1472. !       Msg (message);
  1473.         fclose (fp);
  1474.         unlink (tmp_file);
  1475. --- 920,930 ----
  1476.      if ((fps = fopen (ps_file, "r")) == NULL) 
  1477.      {
  1478. !       if (PRTGIF)
  1479. !          printf ("Can not find %s, print aborted.\n", ps_file);
  1480. !       else
  1481. !       {
  1482. !          sprintf (message, "Can not find %s, print aborted.", ps_file);
  1483. !          Msg (message);
  1484. !       }
  1485.         fclose (fp);
  1486.         unlink (tmp_file);
  1487. ***************
  1488. *** 925,929 ****
  1489.   
  1490.      for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
  1491. !       DumpAllObj (fp, obj_ptr);
  1492.   
  1493.      fprintf (fp, "grestore\n\n");
  1494. --- 947,951 ----
  1495.   
  1496.      for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
  1497. !       DumpAllObj (fp, obj_ptr, PRTGIF);
  1498.   
  1499.      fprintf (fp, "grestore\n\n");
  1500. ***************
  1501. *** 934,946 ****
  1502.      {
  1503.         case PRINTER:
  1504. !          if ((c_ptr = XGetDefault (mainDisplay,"Tgif","PrintCommand")) != NULL)
  1505. !             sprintf (cmd, "%s %s 2>&1", c_ptr, tmp_file);
  1506.            else
  1507. !             sprintf (cmd, "lpr %s 2>&1", tmp_file);
  1508.   
  1509.            if ((fp = popen (cmd, "r")) == NULL)
  1510.            {
  1511. !             sprintf (message, "Can not execute '%s', print aborted.", cmd);
  1512. !             Msg (message);
  1513.               unlink (tmp_file);
  1514.               return;
  1515. --- 956,991 ----
  1516.      {
  1517.         case PRINTER:
  1518. !          if (PRTGIF)
  1519. !          {
  1520. !             if (lastFile)
  1521. !                sprintf (cmd, "lpr %s 2>&1", tmp_file);
  1522. !             else
  1523. !                sprintf (cmd, "lpr -h %s 2>&1", tmp_file);
  1524. !          }
  1525.            else
  1526. !          {
  1527. !             if ((c_ptr = XGetDefault (mainDisplay,"Tgif","PrintCommand")) !=
  1528. !                   NULL)
  1529. !             {
  1530. !                sprintf (cmd, "%s %s 2>&1", c_ptr, tmp_file);
  1531. !                sprintf (message, "Printing with '%s' command.", c_ptr);
  1532. !             }
  1533. !             else
  1534. !             {
  1535. !                sprintf (cmd, "lpr %s 2>&1", tmp_file);
  1536. !                sprintf (message, "Printing with 'lpr' command.");
  1537. !             }
  1538. !             Msg (message);
  1539. !          }
  1540.   
  1541.            if ((fp = popen (cmd, "r")) == NULL)
  1542.            {
  1543. !             if (PRTGIF)
  1544. !                printf ("Can not execute '%s', print aborted.\n", cmd);
  1545. !             else
  1546. !             {
  1547. !                sprintf (message, "Can not execute '%s', print aborted.", cmd);
  1548. !                Msg (message);
  1549. !             }
  1550.               unlink (tmp_file);
  1551.               return;
  1552. ***************
  1553. *** 948,978 ****
  1554.            while (fgets (tmp_str, MAXSTRING, fp) != NULL)
  1555.            {
  1556. !             Msg (tmp_str);
  1557.               sleep (5);
  1558.            }
  1559. !          pclose (fp);
  1560.            break;
  1561.         case LATEX_FIG:
  1562. !          if (!curFileDefined)
  1563.            {
  1564. !             Dialog ("No current file.  Can not generate LaTeX output!", cmd);
  1565. !             unlink (tmp_file);
  1566. !             return;
  1567.            }
  1568.   
  1569. -          strcpy (ps_file, curDomainName);
  1570. -          if (*curDomainName != '\0') strcat (ps_file, "/");
  1571. -          strcat (ps_file, curFileName);
  1572. -          len = strlen (ps_file);
  1573. -          for (i = len-1; ps_file[i] != '.'; i--) ;
  1574. -          strcpy (&ps_file[i], ".ps");
  1575. -          sprintf (cmd, "Printing into '%s'.", ps_file);
  1576. -          Msg (cmd);
  1577.            sprintf (cmd, "tgif2ps < %s 1> %s 2>&1; chmod %s %s", tmp_file,
  1578.                  ps_file, PSFILE_MOD, ps_file);
  1579.            if ((fp = popen (cmd, "r")) == NULL)
  1580.            {
  1581. !             sprintf (message, "Can not execute '%s', file not saved.", cmd);
  1582. !             Msg (message);
  1583.               unlink (tmp_file);
  1584.               return;
  1585. --- 993,1038 ----
  1586.            while (fgets (tmp_str, MAXSTRING, fp) != NULL)
  1587.            {
  1588. !             if (PRTGIF)
  1589. !                printf ("%s", tmp_str);
  1590. !             else
  1591. !                Msg (tmp_str);
  1592.               sleep (5);
  1593.            }
  1594. !          if (PRTGIF) printf ("%s printed.\n\n", tmp_file);
  1595.            break;
  1596.         case LATEX_FIG:
  1597. !          if (PRTGIF)
  1598. !             sprintf (ps_file, "%s.ps", FileName);
  1599. !          else
  1600.            {
  1601. !             if (!curFileDefined)
  1602. !             {
  1603. !                Dialog ("No current file.  Can not generate LaTeX output!", cmd);
  1604. !                unlink (tmp_file);
  1605. !                return;
  1606. !             }
  1607. !             strcpy (ps_file, curDomainName);
  1608. !             if (*curDomainName != '\0') strcat (ps_file, "/");
  1609. !             strcat (ps_file, curFileName);
  1610. !             len = strlen (ps_file);
  1611. !             for (i = len-1; ps_file[i] != '.'; i--) ;
  1612. !             strcpy (&ps_file[i], ".ps");
  1613. !             sprintf (cmd, "Printing into '%s'.", ps_file);
  1614. !             Msg (cmd);
  1615.            }
  1616.   
  1617.            sprintf (cmd, "tgif2ps < %s 1> %s 2>&1; chmod %s %s", tmp_file,
  1618.                  ps_file, PSFILE_MOD, ps_file);
  1619.            if ((fp = popen (cmd, "r")) == NULL)
  1620.            {
  1621. !             if (PRTGIF)
  1622. !                printf ("Can not execute '%s', print aborted.\n", cmd);
  1623. !             else
  1624. !             {
  1625. !                sprintf (message, "Can not execute '%s', file not saved.", cmd);
  1626. !                Msg (message);
  1627. !             }
  1628.               unlink (tmp_file);
  1629.               return;
  1630. ***************
  1631. *** 980,989 ****
  1632.            while (fgets(tmp_str, MAXSTRING, fp) != NULL)
  1633.            {
  1634. !             Msg (tmp_str);
  1635.               sleep (5);
  1636.            }
  1637. !          pclose (fp);
  1638.            break;
  1639.      }
  1640.      unlink (tmp_file);
  1641.   }
  1642. --- 1040,1059 ----
  1643.            while (fgets(tmp_str, MAXSTRING, fp) != NULL)
  1644.            {
  1645. !             if (PRTGIF)
  1646. !                printf ("%s", tmp_str);
  1647. !             else
  1648. !                Msg (tmp_str);
  1649.               sleep (5);
  1650.            }
  1651. !          if (PRTGIF)
  1652. !             printf ("LaTeX figure printed into '%s'.\n\n", ps_file);
  1653. !          else
  1654. !          {
  1655. !             sprintf (message, "LaTeX figure printed into '%s'.\n\n", ps_file);
  1656. !             Msg (message);
  1657. !          }
  1658.            break;
  1659.      }
  1660. +    pclose (fp);
  1661.      unlink (tmp_file);
  1662.   }
  1663. ***************
  1664. *** 1082,1086 ****
  1665.   int SolveProc ()
  1666.   {
  1667. !    switch (SaveTmpFile ())
  1668.      {
  1669.         case OBJ_FILE_SAVED: return (FILE_SOLVE);
  1670. --- 1152,1156 ----
  1671.   int SolveProc ()
  1672.   {
  1673. !    switch (SaveTmpFile ("tmpmodel"))
  1674.      {
  1675.         case OBJ_FILE_SAVED: return (FILE_SOLVE);
  1676. ***************
  1677. *** 1092,1096 ****
  1678.   int SimulateProc ()
  1679.   {
  1680. !    switch (SaveTmpFile ())
  1681.      {
  1682.         case OBJ_FILE_SAVED: return (FILE_SIMULATE);
  1683. --- 1162,1166 ----
  1684.   int SimulateProc ()
  1685.   {
  1686. !    switch (SaveTmpFile ("tmpmodel"))
  1687.      {
  1688.         case OBJ_FILE_SAVED: return (FILE_SIMULATE);
  1689. ***************
  1690. *** 1102,1106 ****
  1691.   int ProbeProc ()
  1692.   {
  1693. !    switch (SaveTmpFile ())
  1694.      {
  1695.         case OBJ_FILE_SAVED: return (FILE_PROBE);
  1696. --- 1172,1176 ----
  1697.   int ProbeProc ()
  1698.   {
  1699. !    switch (SaveTmpFile ("tmpmodel"))
  1700.      {
  1701.         case OBJ_FILE_SAVED: return (FILE_PROBE);
  1702. ***************
  1703. *** 1112,1116 ****
  1704.   int AnimateProc ()
  1705.   {
  1706. !    switch (SaveTmpFile ())
  1707.      {
  1708.         case OBJ_FILE_SAVED: return (FILE_ANIMATE);
  1709. --- 1182,1186 ----
  1710.   int AnimateProc ()
  1711.   {
  1712. !    switch (SaveTmpFile ("tmpmodel"))
  1713.      {
  1714.         case OBJ_FILE_SAVED: return (FILE_ANIMATE);
  1715. ***************
  1716. *** 1142,1146 ****
  1717.         case FILE_IMPORT: ImportFile (); break;
  1718.         case FILE_DOMAIN: ChangeDomain (); break;
  1719. !       case FILE_DUMP: Dump (); break;
  1720.         case FILE_SOLVE: return (SolveProc ()); break;
  1721.         case FILE_SIMULATE: return (SimulateProc ()); break;
  1722. --- 1212,1216 ----
  1723.         case FILE_IMPORT: ImportFile (); break;
  1724.         case FILE_DOMAIN: ChangeDomain (); break;
  1725. !       case FILE_DUMP: Dump (FALSE, ""); break;
  1726.         case FILE_SOLVE: return (SolveProc ()); break;
  1727.         case FILE_SIMULATE: return (SimulateProc ()); break;
  1728. ***************
  1729. *** 1151,1153 ****
  1730. --- 1221,1254 ----
  1731.      }
  1732.      return (INVALID);
  1733. + }
  1734. + void CleanUpFiles ()
  1735. + {
  1736. +    ClearFileInfo ();
  1737. +    fileModified = FALSE;
  1738. + }
  1739. + void EmergencySave ()
  1740. + {
  1741. +    if (exitNormally) return;
  1742. +    signal (SIGHUP, SIG_DFL);
  1743. +    signal (SIGFPE, SIG_DFL);
  1744. +    signal (SIGBUS, SIG_DFL);
  1745. +    signal (SIGSEGV, SIG_DFL);
  1746. +    switch (SaveTmpFile ("EmergencySave"))
  1747. +    {
  1748. +       case OBJ_FILE_SAVED:
  1749. +          fprintf (stderr, "Saved to EmergencySave.obj.\n");
  1750. +          break;
  1751. +       case SYM_FILE_SAVED:
  1752. +          fprintf (stderr, "Saved to EmergencySave.sym.\n");
  1753. +          break;
  1754. +       case INVALID:
  1755. +          fprintf (stderr, "Unable to save working file.\n");
  1756. +          break;
  1757. +    }
  1758. +    exitNormally = TRUE;
  1759. +    exit (0);
  1760.   }
  1761. ---------------------------------> cut here <---------------------------------
  1762. --
  1763. Bill Cheng // UCLA Computer Science Department // (213) 206-7135
  1764. 3277 Boelter Hall // Los Angeles, California 90024 // USA
  1765. william@CS.UCLA.EDU      ...!{uunet|ucbvax}!cs.ucla.edu!william
  1766.  
  1767. dan
  1768. ----------------------------------------------------
  1769. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1770. Opinions expressed reflect those of the author only.
  1771.