[comp.sources.x] v12i020: tgif, Part04/23

william@CS.UCLA.EDU (William Cheng) (03/11/91)

Submitted-by: william@CS.UCLA.EDU (William Cheng)
Posting-number: Volume 12, Issue 20
Archive-name: tgif/part04

---------------------------------> cut here <---------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 23)."
# Contents:  file.c
# Wrapped by william@oahu on Wed Mar  6 09:57:09 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'file.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'file.c'\"
else
echo shar: Extracting \"'file.c'\" \(41175 characters\)
sed "s/^X//" >'file.c' <<'END_OF_FILE'
X/*
X * Author:	William Chia-Wei Cheng (william@cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X      "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/file.c,v 2.0 91/03/05 14:17:43 william Exp $";
X#endif
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include <stdio.h>
X#include <signal.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "const.h"
X#include "types.h"
X
X#include "align.e"
X#include "arc.e"
X#include "attr.e"
X#include "box.e"
X#include "button.e"
X#include "choice.e"
X#include "color.e"
X#include "cursor.e"
X#include "dialog.e"
X#include "drawing.e"
X#include "dup.e"
X#include "font.e"
X#include "grid.e"
X#include "group.e"
X#include "mainloop.e"
X#include "menu.e"
X#include "msg.e"
X#include "names.e"
X#include "pattern.e"
X#include "poly.e"
X#include "polygon.e"
X#include "prtgif.e"
X#include "obj.e"
X#include "oval.e"
X#include "rcbox.e"
X#include "rect.e"
X#include "ruler.e"
X#include "scroll.e"
X#include "select.e"
X#include "setup.e"
X#include "special.e"
X#include "stk.e"
X#include "text.e"
X#include "xbitmap.e"
X
X#define CUR_VERSION 10
X#define START_HAVING_ATTRS 8
X
Xextern char	* getenv ();
X
Xchar	curFileName[MAXPATHLENGTH];
Xint	curFileDefined = FALSE;
Xint	fileVersion = INVALID;
Xint	importingFile = FALSE;
Xint	psDotsPerInch = 72;
Xchar	*psXOffStr[MAXPAGESTYLES]={"0.55","0.4","0.28","0.2","0.565","0.4"};
Xfloat	psXOff[MAXPAGESTYLES] =   { 0.55,  0.4,  0.28,  0.2,  0.565,  0.4 };
Xchar	*psYOffStr[MAXPAGESTYLES]={"10.4","-0.6","10.7","-0.3","10.4","-0.6"};
Xfloat	psYOff[MAXPAGESTYLES] =   { 10.4,  -0.6,  10.7,  -0.3,  10.4,  -0.6 };
Xchar	*psScaleStr[MAXPAGESTYLES]={"0.565","0.565","0.28","0.28","1.13","1.13"};
Xfloat	psScale[MAXPAGESTYLES] =   { 0.565,  0.565,  0.28,  0.28,  1.13,  1.13 };
Xfloat	psPageWidthInInch[MAXPAGESTYLES] = { 7.5, 10, 15.5, 21, 3.75, 5 };
Xfloat	psPageHeightInInch[MAXPAGESTYLES] = { 10, 7.5, 21, 15.5, 5, 3.75 };
X
Xchar	printCommand[MAXSTRING];
X
Xvoid ClearFileInfo ()
X{
X   curFileName[0] = '\0';
X   curFileDefined = FALSE;
X   *curSymDir = '\0';
X}
X
Xint OkayToCreateFile (FileName)
X   char	* FileName;
X{
X   FILE	* fp;
X
X   if ((fp = fopen (FileName, "r")) == NULL) return (TRUE);
X   fclose (fp);
X   switch (YesNoCancel ("File exists, okay to overwrite? [ync](y)"))
X   {
X      case CONFIRM_YES: break;
X      case CONFIRM_NO: return (FALSE);
X      case CONFIRM_CANCEL: return (FALSE);
X   }
X   unlink (FileName);
X   return (TRUE);
X}
X
Xvoid Save (FP, BotObjPtr, Level)
X   FILE			* FP;
X   struct ObjRec	* BotObjPtr;
X   int			Level;
X{
X   struct ObjRec	* obj_ptr;
X
X   TieLooseEnds ();
X
X   if (Level == 0)
X   {
X      fprintf (FP, "state(%1d,%1d,", pageStyle, CUR_VERSION);
X      fprintf (FP, "%1d,%1d,%1d,", drawOrigX, drawOrigY, zoomScale);
X      fprintf (FP, "%1d,%1d,%1d,", xyGrid, gridOn, colorIndex);
X      fprintf (FP, "%1d,%1d,%1d,", horiAlign, vertAlign, lineWidth);
X      fprintf (FP, "%1d,%1d,%1d,%1d,", curSpline, lineStyle, objFill, penPat);
X      fprintf (FP, "%1d,%1d,%1d,%1d,", textJust, curFont, curStyle, curSize);
X      fprintf (FP, "%1d,%1d).\n", curFontDPI, curDash);
X
X      fprintf (FP, "%%\n");
X      fprintf (FP, "%% @%s%s\n", "(#)$H", "eader$");
X      fprintf (FP, "%%\n");
X   }
X
X   for (obj_ptr = BotObjPtr; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X   {
X      switch (obj_ptr->type)
X      {
X         case OBJ_POLY: SavePolyObj (FP, obj_ptr); break;
X         case OBJ_BOX: SaveBoxObj (FP, obj_ptr); break;
X         case OBJ_OVAL: SaveOvalObj (FP, obj_ptr); break;
X         case OBJ_TEXT: SaveTextObj (FP, obj_ptr); break;
X         case OBJ_POLYGON: SavePolygonObj (FP, obj_ptr); break;
X         case OBJ_ARC: SaveArcObj (FP, obj_ptr); break;
X         case OBJ_RCBOX: SaveRCBoxObj (FP, obj_ptr); break;
X         case OBJ_XBM: SaveXBmObj (FP, obj_ptr); break;
X         case OBJ_GROUP: SaveGroupObj (FP, obj_ptr, Level); break;
X         case OBJ_SYM: SaveCompObj (FP, obj_ptr, Level); break;
X         case OBJ_ICON: SaveIconObj (FP, obj_ptr, Level); break;
X      }
X      if (obj_ptr->prev == NULL)
X         if (Level == 0)
X            fprintf (FP, ".\n");
X         else
X            fprintf (FP, "\n");
X      else
X         if (Level == 0)
X            fprintf (FP, ".\n");
X         else
X            fprintf (FP, ",\n");
X   }
X   SetCurChoice (NOTHING);
X}
X
X#define OBJ_FILE_SAVED 0
X#define SYM_FILE_SAVED 1
X
Xstatic
Xint SaveTmpFile (NewFileName)
X   char	* NewFileName;
X   /* return TRUE if file successfully saved */
X{
X   char			new_file_name[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   FILE			* fp;
X   int			count = 0, status = INVALID;
X   struct ObjRec	* obj_ptr;
X
X   strcpy (new_file_name, NewFileName);
X
X   for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X      if (obj_ptr->type == OBJ_SYM) count++;
X
X   switch (count)
X   {
X      case 0: strcat (new_file_name, ".obj"); status = OBJ_FILE_SAVED; break;
X      case 1: strcat (new_file_name, ".sym"); status = SYM_FILE_SAVED; break;
X      default:
X         Msg ("TOO MANY SYMBOLS!  Symbol file not saved.");
X         return (INVALID);
X   }
X
X   unlink (new_file_name);
X
X   if ((fp = fopen (new_file_name, "w")) == NULL)
X   {
X      sprintf (s, "Can not open '%s', file not saved.", new_file_name);
X      Msg (s);
X      return (INVALID);
X   }
X
X   sprintf (s, "Saving temporary file '%s' ...", new_file_name);
X   Msg (s);
X   Save (fp, botObj, 0);
X   fclose (fp);
X   sprintf (s, "Temporary file '%s' saved.", new_file_name);
X   Msg (s);
X
X   chmod (new_file_name, 0777);
X   return (status);
X}
X
Xvoid SaveNewFile ()
X{
X   char			new_file_name[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   char			new_full_name[MAXPATHLENGTH], tmp_str[MAXPATHLENGTH];
X   char			name_without_ext[MAXPATHLENGTH];
X   FILE			* fp;
X   int			count = 0, len;
X   struct ObjRec	* obj_ptr;
X
X   Dialog ("Please Enter New File Name:", new_file_name);
X   if (*new_file_name == '\0') return;
X   len = strlen (new_file_name);
X
X   for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X      if (obj_ptr->type == OBJ_SYM) count++;
X
X   switch (count)
X   {
X      case 0:
X         if (len >= 4)
X         {
X            if (strcmp (&new_file_name[len-4], ".sym") == 0)
X            {
X               Msg ("Can not save as a .sym file, no symbol defined.");
X               return;
X            }
X            else if (strcmp (&new_file_name[len-4], ".obj") != 0)
X            {
X               strcpy (name_without_ext, new_file_name);
X               strcat (new_file_name, ".obj");
X            }
X            else
X            {
X               strcpy (name_without_ext, new_file_name);
X               name_without_ext[len-4] = '\0';
X            }
X
X            if (strlen (new_file_name) == 4)
X            {
X               Msg ("No file name specified.  File not saved.");
X               return;
X            }
X         }
X         else
X         {
X            strcpy (name_without_ext, new_file_name);
X            strcat (new_file_name, ".obj");
X         }
X         break;
X      case 1:
X         if (len >= 4)
X         {
X            if (strcmp (&new_file_name[len-4], ".obj") == 0)
X            {
X               Msg ("Can not save as a .obj file, ther is a symbol defined.");
X               return;
X            }
X            else if (strcmp (&new_file_name[len-4], ".sym") != 0)
X            {
X               strcpy (name_without_ext, new_file_name);
X               strcat (new_file_name, ".sym");
X            }
X            else
X            {
X               strcpy (name_without_ext, new_file_name);
X               name_without_ext[len-4] = '\0';
X            }
X
X            if (strlen (new_file_name) == 4)
X            {
X               Msg ("No file name specified.  File not saved.");
X               return;
X            }
X         }
X         else
X         {
X            strcpy (name_without_ext, new_file_name);
X            strcat (new_file_name, ".sym");
X         }
X         break;
X      default:
X         Msg ("TOO MANY SYMBOLS!  Symbol file not saved.");
X         return;
X   }
X
X   if (*new_file_name == '/')
X      strcpy (new_full_name, new_file_name);
X   else
X      sprintf (new_full_name, "%s/%s", curDir, new_file_name);
X
X   if (!OkayToCreateFile (new_full_name)) return;
X
X   if ((fp = fopen (new_full_name, "w")) == NULL)
X   {
X      sprintf (s, "Can not open '%s', file not saved.", new_full_name);
X      Msg (s);
X      return;
X   }
X
X   strcpy (tmp_str, curDir);
X   SetCurDir (new_full_name);
X   curFileDefined = TRUE;
X
X   switch (count)
X   {
X      case 0:
X         *curSymDir = '\0';
X         if ((strcmp (tmp_str, curDir) != 0) || (!NameInCurDir (curFileName)))
X            UpdateDirInfo ();
X         break;
X      case 1:
X         strcpy (curSymDir, curDir);
X         if (!DirInSymPath (curDir)) UpdateSymInfo ();
X         break;
X   }
X
X   sprintf (s, "Saving '%s/%s' ...", curDir, curFileName);
X   Msg (s);
X   Save (fp, botObj, 0);
X   fclose (fp);
X   sprintf (s, "File '%s/%s' saved.", curDir, curFileName);
X   Msg (s);
X   SetFileModified (FALSE);
X
X   RedrawTitleWindow ();
X}
X
Xvoid SaveFile ()
X{
X   int			i, len, count;
X   struct ObjRec	* obj_ptr;
X   FILE			* fp;
X   char			ext[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   char			full_name[MAXPATHLENGTH];
X
X   if (!curFileDefined)
X   {
X      SaveNewFile ();
X      return;
X   }
X
X   len = strlen (curFileName);
X   for (i = len-1; curFileName[i] != '.'; i--) ;
X   strcpy (ext, &curFileName[i+1]);
X
X   for (obj_ptr = topObj, count = 0; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X      if (obj_ptr->type == OBJ_SYM) count++;
X   switch (count)
X   {
X      case 0:
X         if (strcmp (ext, "sym") == 0)
X         {
X            Msg ("No SYMBOL defined in symbol file.  Symbol file not saved.");
X            return;
X         }
X         break;
X      case 1:
X         if (strcmp (ext, "obj") == 0)
X         {
X            Msg ("One SYMBOL defined in OBJECT file.  Object file not saved.");
X            return;
X         }
X         break;
X      default:
X         if (strcmp (ext, "sym") == 0)
X         {
X            Msg ("Too many SYMBOLS in symbol file!  Symbol file not saved.");
X            return;
X         }
X         break;
X   }
X
X   if (strcmp (ext, "sym") == 0)
X      sprintf (full_name, "%s/%s", curSymDir, curFileName);
X   else if (strcmp (ext, "obj") == 0)
X      sprintf (full_name, "%s/%s", curDir, curFileName);
X
X   if ((fp = fopen (full_name, "w")) == NULL)
X   {
X      sprintf (s, "Can not open '%s', file not saved.", full_name);
X      Msg (s);
X      return;
X   }
X
X   sprintf (s, "Saving '%s' ...", full_name);
X   Msg (s);
X
X   Save (fp, botObj, 0);
X
X   fclose (fp);
X   sprintf (s, "File '%s' saved.", full_name);
X   Msg (s);
X   SetFileModified (FALSE);
X   if (!NameInCurDir (curFileName)) UpdateDirInfo ();
X}
X
Xchar * ParseStr (Str, C, Left)
X   char	* Str, C, * Left;
X{
X   register char	* s = Str, * l = Left;
X   register int		len = 0;
X
X   while (*s != '\0' && *s != C)
X   {
X      *l++ = *s++;
X      len++;
X   }
X
X   if (*s == C) s++;
X   *l = '\0';
X
X   while (len >= 2 && *Left == '\'' && *(l-1) == '\'')
X   {
X      *(--l) = '\0';
X      strcpy (Left, &Left[1]);
X      len -= 2;
X   }
X   return (s);
X}
X
Xchar * FindChar (C, Str)
X   char	C;
X   char	* Str;
X   /* returns the address of the character right after C of the string Str */
X{
X   register char	* s = Str;
X
X   while (*s != '\0' && *s != C) s++;
X
X   if (*s == C) s++;
X   return (s);
X}
X
Xvoid ReadState (Inbuf, PRTGIF)
X   char	* Inbuf;
X   int	PRTGIF;
X{
X   char	* s;
X   int	page_style;
X
X   s = FindChar ('(', Inbuf);
X   sscanf (s, "%d", &page_style);
X   s = FindChar (',', s);
X   if (*s == '\0')
X      fileVersion = INVALID;
X   else
X      sscanf (s, "%d", &fileVersion);
X
X   if (PRTGIF)
X   {
X      pageStyle = page_style;
X      return;
X   }
X
X   if (!importingFile)
X   {
X      pageStyle = page_style;
X      if (fileVersion >= 2)
X      {
X         s = FindChar (',', s);
X         if (fileVersion <= 3)
X         {
X            sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , %d , \
X                  %d , %d , %d , %d , %d , %d",
X                  &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn,
X                  &colorIndex, &horiAlign, &vertAlign, &lineWidth, &lineStyle,
X                  &objFill, &penPat, &textJust, &curFont, &curStyle, &curSize);
X            if (lineWidth == LINE_CURVED)
X            {
X               lineWidth = 0;
X               curSpline = LT_SPLINE;
X            }
X            else
X               curSpline = LT_STRAIGHT;
X            curFontDPI = FONT_DPI_75;
X            curDash = 0;
X         }
X         else if (fileVersion <= 7)
X         {
X            sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
X                  %d , %d , %d , %d , %d , %d , %d , %d",
X                  &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn,
X                  &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline,
X                  &lineStyle, &objFill, &penPat, &textJust, &curFont,
X                  &curStyle, &curSize);
X            curFontDPI = FONT_DPI_75;
X            curDash = 0;
X         }
X         else if (fileVersion <= 8)
X         {
X            sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
X                  %d , %d , %d , %d , %d , %d , %d , %d , %d",
X                  &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn,
X                  &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline,
X                  &lineStyle, &objFill, &penPat, &textJust, &curFont,
X                  &curStyle, &curSize, &curFontDPI);
X            curDash = 0;
X         }
X         else
X         {
X            sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
X                  %d , %d , %d , %d , %d , %d , %d , %d , %d , %d",
X                  &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn,
X                  &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline,
X                  &lineStyle, &objFill, &penPat, &textJust, &curFont,
X                  &curStyle, &curSize, &curFontDPI, &curDash);
X         }
X         if (colorIndex >= maxColors)
X         {
X            printf ("Can not find color #%1d, use '%s' instead.\n", colorIndex,
X                  colorMenuItems[defaultColorIndex]);
X            colorIndex = defaultColorIndex;
X         }
X         SetCanvasFont ();
X      }
X
X      UpdDrawWinWH ();
X      UpdPageStyle (pageStyle);
X      UpdDrawWinBBox ();
X
X      DrawPaperBoundary ();
X      RedrawGridLines ();
X      RedrawRulers ();
X      RedrawChoiceWindow ();
X   }
X}
X
Xvoid ReadObjAttrs (MinFileVersion, FP, ObjPtr, PRTGIF)
X   FILE			* FP;
X   struct ObjRec	* * ObjPtr;
X   int			PRTGIF;
X{
X   struct AttrRec	* top_attr = NULL, * bot_attr = NULL, * attr_ptr;
X
X   if (fileVersion <= MinFileVersion) return;
X
X   while (ReadAttr (FP, &attr_ptr, PRTGIF))
X   {
X      attr_ptr->owner = *ObjPtr;
X      attr_ptr->prev = NULL;
X      attr_ptr->next = top_attr;
X      if (top_attr == NULL)
X         bot_attr = attr_ptr;
X      else
X         top_attr->prev = attr_ptr;
X      top_attr = attr_ptr;
X   }
X   if (bot_attr != NULL) bot_attr->next = NULL;
X   (*ObjPtr)->fattr = top_attr;
X   (*ObjPtr)->lattr = bot_attr;
X}
X
Xint ReadObj (FP, ObjPtr, PRTGIF)
X   FILE			* FP;
X   struct ObjRec	* * ObjPtr;
X   int			PRTGIF;
X{
X   char			inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
X   char			* line = NULL, * c_ptr, * s, * s1;
X   int			len, id, cur_size, done = FALSE, allocated = FALSE;
X
X   while (fgets (inbuf, MAXSTRING, FP) != NULL)
X   {
X      if (inbuf[0] == ']') return (FALSE);
X
X      len = strlen(inbuf);
X      if (inbuf[len-1] != '\r' && inbuf[len-1] != '\n')
X      {  /* line longer than MAXSTRING characters */
X         /* inbuf[MAXSTRING-1] == '\0' and len == MAXSTRING-1 now */
X         cur_size = 2*(MAXSTRING-1);
X         allocated = TRUE;
X         line = (char *) calloc (cur_size, sizeof(char));
X         strcpy (line, inbuf);
X         c_ptr = &(line[MAXSTRING-1]);
X         while (!done && fgets (inbuf, MAXSTRING, FP) != NULL)
X         {
X            len = strlen(inbuf);
X            if (inbuf[len-1] == '\r' || inbuf[len-1] == '\n')
X            {
X               done = TRUE;
X               inbuf[len-1] = '\0';
X               strcpy (c_ptr, inbuf);
X            }
X            else
X            {
X               cur_size += MAXSTRING-1;
X               line = (char *) realloc (line, cur_size);
X               strcpy (c_ptr, inbuf);
X               c_ptr += MAXSTRING-1;
X            }
X         }
X         if (!done)
X         {
X            if (allocated) cfree (line);
X            return (FALSE);
X         }
X      }
X      else
X      {
X         line = inbuf;
X         line[len-1] = '\0';
X      }
X
X      if (line[0] == '%')
X      {  /* comment line, skip */
X         continue;
X      }
X
X      ParseStr (line, '(', obj_name);
X      if (strcmp (obj_name, "poly") == 0)
X      {
X         ReadPolyObj (line, ObjPtr);
X         ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "box") == 0)
X      {
X         ReadBoxObj (line, ObjPtr);
X         ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "oval") == 0)
X      {
X         ReadOvalObj (line, ObjPtr);
X         ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "text") == 0)
X      {
X         ReadTextObj (FP, line, ObjPtr, PRTGIF);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "polygon") == 0)
X      {
X         ReadPolygonObj (line, ObjPtr);
X         ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "arc") == 0)
X      {
X         ReadArcObj (line, ObjPtr);
X         ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "rcbox") == 0)
X      {
X         ReadRCBoxObj (line, ObjPtr);
X         ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "xbm") == 0)
X      {
X         ReadXBmObj (FP, line, ObjPtr, PRTGIF);
X         ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "group") == 0)
X      {
X         ReadGroupObj (FP, ObjPtr, PRTGIF);
X         ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "sym") == 0)
X      {
X         ReadGroupObj (FP, ObjPtr, PRTGIF);
X         (*ObjPtr)->type = OBJ_SYM;
X         ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "icon") == 0)
X      {
X         ReadGroupObj (FP, ObjPtr, PRTGIF);
X         (*ObjPtr)->type = OBJ_ICON;
X         if (fgets (line, MAXSTRING, FP) == NULL)
X         {
X            if (allocated) cfree (line);
X            return (FALSE);
X         }
X
X         strcpy(tmp_str, FindChar ('"', line));
X         s = FindChar ('"', tmp_str);
X         if (fileVersion != INVALID)
X         {
X            s1 = FindChar (',', s);
X            sscanf (s1, "%d", &id);
X            if (id >= objId) objId = id+1;
X            (*ObjPtr)->id = id;
X         }
X         (*ObjPtr)->dirty = FALSE;
X         *(--s) = '\0';
X         strcpy ((*ObjPtr)->detail.r->s, tmp_str);
X         ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
X         AdjObjBBox (*ObjPtr);
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X      else if (strcmp (obj_name, "state") == 0)
X      {
X         ReadState (line, PRTGIF);
X         *ObjPtr = NULL;
X         if (allocated) cfree (line);
X         return (TRUE);
X      }
X   }
X   if (allocated) cfree (line);
X   return (FALSE);
X}
X
Xvoid ChangeDomain ()
X{
X   char 	domain_name[MAXPATHLENGTH], env_str[MAXPATHLENGTH];
X   char 	s[MAXSTRING], s1[MAXSTRING], * c_ptr;
X
X   if (SelectDomain (domain_name) == INVALID) return;
X
X   sprintf (env_str, "TGIF_%s", domain_name);
X   if ((c_ptr = getenv (env_str)) == NULL)
X      ParseSymPath (".");
X   else
X      ParseSymPath (c_ptr);
X
X   UpdateSymInfo ();
X
X   strcpy (curDomainName, domain_name);
X   sprintf (s, "Current domain is '%s'.", curDomainName);
X   sprintf (s1, "Symbol path set to '%s'.", curDomainPath);
X   TwoLineMsg (s, s1);
X   RedrawTitleWindow ();
X}
X
Xvoid ImportFile ()
X{
X   struct ObjRec	* obj_ptr, * saved_top_obj, * saved_bot_obj;
X   char 		file_name[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   FILE			* fp;
X
X   importingFile = TRUE;
X   if (SelectFileNameToImport ("Please select a file to IMPORT ...",
X         "obj", file_name) == INVALID)
X   {
X      importingFile = FALSE;
X      return;
X   }
X
X   strcat (file_name, ".obj");
X
X   if ((fp = fopen (file_name, "r")) == NULL)
X   {
X      sprintf (s, "Can not import '%s'.", file_name);
X      Msg (s);
X      importingFile = FALSE;
X      return;
X   }
X
X   TieLooseEnds ();
X   if (topSel != NULL) { HighLightReverse (); RemoveAllSel (); }
X   saved_top_obj = topObj;
X   saved_bot_obj = botObj;
X   topObj = botObj = NULL;
X
X   sprintf (s, "Importing '%s' ...", file_name);
X   Msg (s);
X
X   while (ReadObj (fp, &obj_ptr, FALSE))
X      if (obj_ptr != NULL)
X         AddObj (NULL, topObj, obj_ptr);
X
X   fclose (fp);
X   importingFile = FALSE;
X   if (topObj != NULL) SetFileModified (TRUE);
X
X   RedrawDrawWindow (botObj);
X   SelAllObj ();
X
X   if (botObj != NULL)
X      botObj->next = saved_top_obj;
X   else
X      topObj = saved_top_obj;
X
X   if (saved_top_obj != NULL)
X   {
X      saved_top_obj->prev = botObj;
X      botObj = saved_bot_obj;
X   }
X
X   sprintf (s, "'%s' imported.", file_name);
X   Msg (s);
X}
X
Xvoid ImportXBitmapFile ()
X{
X   char 		file_name[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   unsigned int		w, h;
X   int			rc, x_hot, y_hot;
X   Pixmap		bitmap;
X
X   importingFile = TRUE;
X   if (SelectFileNameToImport ("Please select a XBitmap file to IMPORT ...",
X         XBM_FILE_EXT, s) == INVALID)
X   {
X      importingFile = FALSE;
X      return;
X   }
X
X   sprintf (file_name, "%s.%s", s, XBM_FILE_EXT);
X
X   rc = XReadBitmapFile (mainDisplay, mainWindow, file_name, &w, &h, &bitmap,
X         &x_hot, &y_hot);
X
X   if (rc != BitmapSuccess)
X   {
X      sprintf (s, "Can not import XBitmap file '%s'.", file_name);
X      Msg (s);
X      importingFile = FALSE;
X      return;
X   }
X
X   CreateXBmObj (w, h, bitmap);
X
X   TieLooseEnds ();
X   if (topSel != NULL) { HighLightReverse (); RemoveAllSel (); }
X   SetNullCursor (drawWindow);
X
X   PlaceTopObj ();
X   SelectTopObj ();
X   SetFileModified (TRUE);
X   justDupped = FALSE;
X   ShowCursor ();
X
X   sprintf (s, "XBitmap file (%1dx%1d) '%s' imported.", w, h, file_name);
X   Msg (s);
X   importingFile = FALSE;
X}
X
Xvoid LoadFile ()
X{
X   struct ObjRec	* obj_ptr;
X   char 		file_name[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   char 		saved_cur_dir[MAXPATHLENGTH];
X   FILE			* fp;
X
X   strcpy (saved_cur_dir, curDir);
X   if (SelectFileName ("Please select a file to OPEN ...",file_name) == INVALID)
X      return;
X
X   strcat (file_name, ".obj");
X
X   if ((fp = fopen (file_name, "r")) == NULL)
X   {
X      sprintf (s, "Can not open '%s'.", file_name);
X      Msg (s);
X      return;
X   }
X
X   TieLooseEnds ();
X   CleanUpDrawingWindow ();
X   SetFileModified (FALSE);
X   sprintf (s, "Loading '%s' ...", file_name);
X   Msg (s);
X
X   XClearWindow (mainDisplay, drawWindow);
X
X   while (ReadObj (fp, &obj_ptr, FALSE))
X      if (obj_ptr != NULL)
X      {
X         AddObj (NULL, topObj, obj_ptr);
X         if (PointInBBox (obj_ptr->x, obj_ptr->y, drawWinBBox) ||
X               BBoxIntersect (obj_ptr->bbox, drawWinBBox))
X            DrawObj (drawWindow, obj_ptr);
X      }
X
X   if (topObj == NULL)
X   {
X      DrawPaperBoundary ();
X      RedrawGridLines ();
X   }
X
X   fclose (fp);
X   SetCurDir (file_name);
X   *curSymDir = '\0';
X   curFileDefined = TRUE;
X
X   if (strcmp (saved_cur_dir, curDir) != 0 && DirInSymPath ("."))
X      UpdateSymInfo ();
X
X   sprintf (s, "Current file is '%s'.", file_name);
X   Msg (s);
X
X   RedrawTitleWindow ();
X}
X
Xvoid DumpPatFill (FP, Fill, CellSize, BBox, Blanks)
X   FILE		* FP;
X   int		Fill, CellSize;
X   struct BBRec	BBox;
X   char		* Blanks;
X{
X   int	ltx, lty, rbx, rby;
X
X   ltx = ((BBox.ltx % CellSize) == 0) ? BBox.ltx :
X         ((BBox.ltx > 0) ? ((int)(BBox.ltx / CellSize))*CellSize :
X         ((int)(BBox.ltx / CellSize)-1)*CellSize);
X   lty = ((BBox.lty % CellSize) == 0) ? BBox.lty :
X         ((BBox.lty > 0) ? ((int)(BBox.lty / CellSize))*CellSize :
X         ((int)(BBox.lty / CellSize)-1)*CellSize);
X   rbx = ((BBox.rbx % CellSize) == 0) ? BBox.rbx :
X         ((BBox.rbx > 0) ? ((int)(BBox.rbx / CellSize)+1)*CellSize :
X         ((int)(BBox.rbx / CellSize))*CellSize);
X   rby = ((BBox.rby % CellSize) == 0) ? BBox.rby :
X         ((BBox.rby > 0) ? ((int)(BBox.rby / CellSize)+1)*CellSize :
X         ((int)(BBox.rby / CellSize))*CellSize);
X
X   fprintf (FP, "%spat%1d %1d %1d %1d %1d %1d patfill\n",
X         Blanks, Fill, CellSize, ltx, lty, rbx-ltx, rby-lty);
X}
X
Xvoid DumpSymOutline (FP, ObjPtr)
X   FILE				* FP;
X   register struct ObjRec	* ObjPtr;
X{
X   int  ltx, lty, rbx, rby;
X
X   ltx = ObjPtr->obbox.ltx - QUARTER_INCH + 1;
X   lty = ObjPtr->obbox.lty - QUARTER_INCH + 1;
X   rbx = ObjPtr->obbox.rbx + QUARTER_INCH - 1;
X   rby = ObjPtr->obbox.rby + QUARTER_INCH - 1;
X
X   fprintf (FP, "gsave\n");
X   fprintf (FP, "   0 setgray\n");
X   fprintf (FP, "   [4 4] 0 setdash\n");
X   fprintf (FP, "   newpath\n   %1d %1d moveto\n", ltx, lty);
X   fprintf (FP, "      %1d %1d lineto\n", rbx, lty);
X   fprintf (FP, "      %1d %1d lineto\n", rbx, rby);
X   fprintf (FP, "      %1d %1d lineto\n", ltx, rby);
X   fprintf (FP, "   closepath stroke\n");
X   fprintf (FP, "grestore\n");
X}
X
Xvoid DumpAttrs (FP, AttrPtr, PRTGIF)
X   FILE				* FP;
X   register struct AttrRec	* AttrPtr;
X   int				PRTGIF;
X{
X   for ( ; AttrPtr != NULL; AttrPtr = AttrPtr->prev)
X      if (AttrPtr->shown)
X         DumpTextObj (FP, AttrPtr->obj, PRTGIF);
X}
X
Xvoid DumpAllObj (FP, ObjPtr, PRTGIF)
X   FILE				* FP;
X   register struct ObjRec	* ObjPtr;
X   int				PRTGIF;
X{
X   register struct ObjRec	* obj_ptr;
X
X   switch (ObjPtr->type)
X   {
X      case OBJ_POLY:
X         DumpPolyObj (FP, ObjPtr);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_BOX:
X         DumpBoxObj (FP, ObjPtr);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_OVAL:
X         DumpOvalObj (FP, ObjPtr);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_TEXT: DumpTextObj (FP, ObjPtr, PRTGIF); break;
X      case OBJ_POLYGON:
X         DumpPolygonObj (FP, ObjPtr);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_ARC:
X         DumpArcObj (FP, ObjPtr);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_RCBOX:
X         DumpRCBoxObj (FP, ObjPtr);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_XBM:
X         DumpXBmObj (FP, ObjPtr, PRTGIF);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         break;
X      case OBJ_SYM:
X      case OBJ_ICON:
X      case OBJ_GROUP:
X         obj_ptr = ObjPtr->detail.r->last;
X         for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X            DumpAllObj (FP, obj_ptr, PRTGIF);
X         DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
X         if (ObjPtr->type == OBJ_SYM) DumpSymOutline (FP, ObjPtr);
X         break;
X   }
X}
X
Xvoid DumpBBox (fp)
X   FILE	* fp;
X{
X   register struct ObjRec	* obj_ptr;
X   int				ltx, lty, rbx, rby;
X   double			llx1, lly1, urx1, ury1;
X   double			real_ps_dots_per_inch = 0.0;
X
X   if ((obj_ptr = topObj) == NULL)
X   {
X      fprintf (fp, "%%%%BoundingBox: 0 0 0 0\n");
X      printf ("Warning:  The PostScript bounding box is empty!\n");
X      Msg ("Warning:  The PostScript bounding box is empty!\n");
X      return;
X   }
X
X   ltx = obj_ptr->bbox.ltx; lty = obj_ptr->bbox.lty;
X   rbx = obj_ptr->bbox.rbx; rby = obj_ptr->bbox.rby;
X
X   for (obj_ptr = topObj->next; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X   {
X      if (obj_ptr->bbox.ltx < ltx) ltx = obj_ptr->bbox.ltx;
X      if (obj_ptr->bbox.lty < lty) lty = obj_ptr->bbox.lty;
X      if (obj_ptr->bbox.rbx > rbx) rbx = obj_ptr->bbox.rbx;
X      if (obj_ptr->bbox.rby > rby) rby = obj_ptr->bbox.rby;
X   }
X
X   switch (pageStyle)
X   {
X      case PORTRAIT: real_ps_dots_per_inch = psDotsPerInch; break;
X      case LANDSCAPE: real_ps_dots_per_inch = psDotsPerInch; break;
X      case HIGHPORT: real_ps_dots_per_inch = psDotsPerInch/2.0; break;
X      case HIGHLAND: real_ps_dots_per_inch = psDotsPerInch/2.0; break;
X      case SLIDEPORT: real_ps_dots_per_inch = psDotsPerInch*2.0; break;
X      case SLIDELAND: real_ps_dots_per_inch = psDotsPerInch*2.0; break;
X   }
X
X   llx1 = 1.0*ltx*real_ps_dots_per_inch/(PIX_PER_INCH);
X   lly1 = -1.0*rby*real_ps_dots_per_inch/(PIX_PER_INCH);
X   urx1 = 1.0*rbx*real_ps_dots_per_inch/(PIX_PER_INCH);
X   ury1 = -1.0*lty*real_ps_dots_per_inch/(PIX_PER_INCH);
X
X   fprintf (fp,"%%%%BoundingBox: %.3f %.3f %.3f %.3f\n",llx1,lly1,urx1,ury1);
X}
X
Xstatic
Xvoid GenDump (PRTGIF, FileName)
X   int	PRTGIF;
X   char	* FileName;
X{
X   register struct ObjRec	* obj_ptr;
X   char				cmd[MAXSTRING+1], tmp_str[MAXSTRING+1];
X   char				tmp_file[MAXSTRING+1], ps_file[MAXSTRING+1];
X   char				message[MAXSTRING+1];
X   int				i, len;
X   FILE				* fp, * fps;
X
X   if (botObj == NULL) { Msg ("No object to print."); return; }
X
X   if (!PRTGIF) Msg ("Generating print file ...");
X
X   if (whereToPrint == XBM_FILE)
X   {
X      if (!curFileDefined)
X      {
X         if (colorDump)
X            Dialog ("No current file.  Can not generate X11 pitmap output!",
X                  cmd);
X         else
X            Dialog ("No current file.  Can not generate X11 bitmap output!",
X                  cmd);
X      }
X      else
X         DumpXBitmapFile ();
X      return;
X   }
X
X   strcpy (tmp_file, "/tmp/TgifXXXXXX");
X   mktemp (tmp_file);
X   unlink (tmp_file);
X
X   if ((fp = fopen (tmp_file, "w")) == NULL)
X   {
X      if (PRTGIF)
X         printf ("Can not create '%s', print aborted.", tmp_file);
X      else
X      {
X         sprintf (tmp_str, "Can not create '%s', print aborted.", tmp_file);
X         Msg (tmp_str);
X      }
X      return;
X   }
X
X   if (PRTGIF) printf ("Writing to '%s' ...\n", tmp_file);
X
X   fprintf (fp, "%%!\n");
X   DumpBBox (fp);
X   sprintf(ps_file, "%s/.psmac", drawPath);
X   if ((fps = fopen (ps_file, "r")) == NULL) 
X   {
X      if (PRTGIF)
X         printf ("Can not find '%s', print aborted.\n", ps_file);
X      else
X      {
X         sprintf (message, "Can not find '%s', print aborted.", ps_file);
X         Msg (message);
X      }
X      fclose (fp);
X      unlink (tmp_file);
X      return;
X   }
X   while (fgets (tmp_str, MAXSTRING, fps) != NULL) /* copy the header file */
X      fputs (tmp_str, fp);
X   fclose (fps);
X
X   fprintf (fp, "gsave\n\n");
X   switch (pageStyle)
X   {
X      case LANDSCAPE:
X      case HIGHLAND:
X      case SLIDELAND: fprintf (fp, "90 rotate\n"); break;
X   }
X   switch (whereToPrint)
X   {
X      case PRINTER:
X      case PS_FILE:
X         fprintf (fp, "%1d %s mul %1d %s mul translate\n", psDotsPerInch,
X               psXOffStr[pageStyle], psDotsPerInch, psYOffStr[pageStyle]);
X         break;
X      case LATEX_FIG: break;
X   }
X
X   fprintf (fp, "%s -%s scale\n\n",
X         psScaleStr[pageStyle], psScaleStr[pageStyle]);
X
X   for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X      DumpAllObj (fp, obj_ptr, PRTGIF);
X
X   fprintf (fp, "grestore\n\n");
X   switch (whereToPrint)
X   {
X      case PRINTER:
X      case PS_FILE: fprintf (fp, "showpage\n"); break;
X      case LATEX_FIG: break;
X   }
X   fclose (fp);
X
X   switch (whereToPrint)
X   {
X      case PRINTER:
X         if (PRTGIF)
X         {
X            if (lastFile)
X               sprintf (cmd, "%s %s 2>&1", printCommand, tmp_file);
X            else
X               sprintf (cmd, "%s -h %s 2>&1", printCommand, tmp_file);
X         }
X         else
X         {
X            sprintf (cmd, "%s %s 2>&1", printCommand, tmp_file);
X            sprintf (message, "Printing with '%s' command.", printCommand);
X            Msg (message);
X         }
X         break;
X      case LATEX_FIG:
X         if (PRTGIF)
X            sprintf (ps_file, "%s.%s", FileName, EPSF_FILE_EXT);
X         else
X         {
X            if (!curFileDefined)
X            {
X               Dialog ("No current file.  Can not generate LaTeX output!", cmd);
X               unlink (tmp_file);
X               return;
X            }
X            sprintf (ps_file, "%s/%s", curDir, curFileName);
X            len = strlen (ps_file);
X            for (i = len-1; ps_file[i] != '.'; i--) ;
X            sprintf (&ps_file[i], ".%s", EPSF_FILE_EXT);
X            sprintf (cmd, "Printing into '%s'.", ps_file);
X            Msg (cmd);
X         }
X         sprintf (cmd, "cat %s 1> %s 2>&1; chmod %s %s", tmp_file, ps_file,
X               PSFILE_MOD, ps_file);
X         break;
X      case PS_FILE:
X         if (PRTGIF)
X            sprintf (ps_file, "%s.%s", FileName, PS_FILE_EXT);
X         else
X         {
X            if (!curFileDefined)
X            {
X               Dialog ("No current file.  Can not generate PostScript output!",
X                  cmd);
X               unlink (tmp_file);
X               return;
X            }
X            sprintf (ps_file, "%s/%s", curDir, curFileName);
X            len = strlen (ps_file);
X            for (i = len-1; ps_file[i] != '.'; i--) ;
X            sprintf (&ps_file[i], ".%s", PS_FILE_EXT);
X            sprintf (cmd, "Printing into '%s'.", ps_file);
X            Msg (cmd);
X         }
X         sprintf (cmd, "cat %s 1> %s 2>&1; chmod %s %s", tmp_file, ps_file,
X               PSFILE_MOD, ps_file);
X         break;
X   }
X
X   if ((fp = popen (cmd, "r")) == NULL)
X   {
X      if (PRTGIF)
X         printf ("Can not execute '%s', print aborted.\n", cmd);
X      else
X      {
X         sprintf (message, "Can not execute '%s', print aborted.", cmd);
X         Msg (message);
X      }
X      unlink (tmp_file);
X      return;
X   }
X   while (fgets(tmp_str, MAXSTRING, fp) != NULL)
X   {
X      if (PRTGIF)
X         printf ("%s", tmp_str);
X      else
X         Msg (tmp_str);
X      sleep (5);
X   }
X   switch (whereToPrint)
X   {
X      case PRINTER:
X         if (PRTGIF)
X            printf ("'%s' printed.\n\n", tmp_file);
X         else
X            Msg ("Print completed.");
X         break;
X      case PS_FILE:
X         if (PRTGIF)
X            printf ("PostScript file printed into '%s'.\n\n", ps_file);
X         else
X         {
X            sprintf (message, "PostScript file printed into '%s'.", ps_file);
X            Msg (message);
X         }
X         break;
X      case LATEX_FIG:
X         if (PRTGIF)
X            printf ("LaTeX figure printed into '%s'.\n\n", ps_file);
X         else
X         {
X            sprintf (message, "LaTeX figure printed into '%s'.", ps_file);
X            Msg (message);
X         }
X         break;
X   }
X   pclose (fp);
X   unlink (tmp_file);
X}
X
Xvoid Dump (PRTGIF, FileName)
X   int	PRTGIF;
X   char	* FileName;
X{
X   char	* c_ptr;
X   int	len;
X
X   if (PRTGIF)
X   {
X      len = strlen (FileName);
X      if (len >= 4 && strcmp (&FileName[len-4], ".obj") == 0)
X         FileName[len-4] = '\0';
X   }
X
X   if (whereToPrint == PRINTER && !PRTGIF)
X   {
X      if ((c_ptr = XGetDefault (mainDisplay, "Tgif", "PrintCommand")) != NULL)
X         strcpy (printCommand, c_ptr);
X      else
X         strcpy (printCommand, "lpr");
X   }
X   GenDump (PRTGIF, FileName);
X}
X
Xvoid PrintWithCommand (PRTGIF, FileName)
X   int	PRTGIF;
X   char	* FileName;
X{
X   if (whereToPrint == PRINTER)
X   {
X      Dialog ("Please Enter Print Command Name:", printCommand);
X      if (*printCommand == '\0') return;
X   }
X   GenDump (PRTGIF, FileName);
X}
X
Xvoid NewProc ()
X{
X   if (fileModified)
X   {
X      switch (YesNoCancel ("File modified, save file before clear? [ync](y)"))
X      {
X         case CONFIRM_YES: SaveFile (); break;
X         case CONFIRM_NO: TieLooseEnds (); break;
X         case CONFIRM_CANCEL: return;
X      }
X      SetFileModified (FALSE);
X   }
X   CleanUpDrawingWindow ();
X   ClearFileInfo ();
X   ClearAndRedrawDrawWindow ();
X   Msg ("Editing no file.");
X   objId = 0;
X   RedrawTitleWindow ();
X}
X
Xvoid OpenProc ()
X{
X   if (fileModified)
X   {
X      switch (YesNoCancel ("File modified, save file before open? [ync](y)"))
X      {
X         case CONFIRM_YES: SaveFile (); break;
X         case CONFIRM_NO: break;
X         case CONFIRM_CANCEL: return;
X      }
X   }
X   LoadFile ();
X}
X
X#define FILE_NEW 0
X#define FILE_OPEN 1
X#define FILE_SAVE 2
X#define FILE_SAVENEW 3
X#define FILE_IMPORT 4
X#define FILE_IMPORTXBM 5
X#define FILE_DOMAIN 6
X#define FILE_DUMP 7
X#define FILE_USR_DUMP 8
X#define FILE_SOLVE 9
X#define FILE_SIMULATE 10
X#define FILE_PROBE 11
X#define FILE_ANIMATE 12
X#define FILE_ESCAPE 13
X#define FILE_QUIT 14
X
X#define FILEMENUENTRIES 15
X
Xchar * fileMenuStr[] =
X      { "New            ^N",
X        "Open           ^O",
X        "Save           ^S",
X        "SaveNew       ^#S",
X        "Import         #P",
X        "ImportXBitmap ^#P",
X        "ChangeDomain   ^C",
X        "Print          ^P",
X        "PrintWithCmd   ^-",
X        "Solve          #S",
X        "Simulate       #Y",
X        "Probe          #B",
X        "Animate        ^Z",
X        "Escape         #X",
X        "Quit           ^Q"
X      };
X
Xint QuitProc ()
X{
X   if (fileModified)
X   {
X      switch (YesNoCancel ("File modified, save file before quit? [ync](y)"))
X      {
X         case CONFIRM_YES: SaveFile (); break;
X         case CONFIRM_NO: break;
X         case CONFIRM_CANCEL: return (INVALID);
X      }
X   }
X   if (AncesterModified ())
X   {
X      switch (YesNoCancel ("Ancester file modified, still quitting? [ync](y)"))
X      {
X         case CONFIRM_YES: return (FILE_QUIT);
X         case CONFIRM_NO: return (INVALID);
X         case CONFIRM_CANCEL: return (INVALID);
X      }
X   }
X   return (FILE_QUIT);
X}
X
Xint SolveProc ()
X{
X   switch (SaveTmpFile ("tmpmodel"))
X   {
X      case OBJ_FILE_SAVED: return (FILE_SOLVE);
X      case SYM_FILE_SAVED: return (INVALID);
X      case INVALID: return (INVALID);
X   }
X}
X
Xint SimulateProc ()
X{
X   switch (SaveTmpFile ("tmpmodel"))
X   {
X      case OBJ_FILE_SAVED: return (FILE_SIMULATE);
X      case SYM_FILE_SAVED: return (INVALID);
X      case INVALID: return (INVALID);
X   }
X}
X
Xint ProbeProc ()
X{
X   switch (SaveTmpFile ("tmpmodel"))
X   {
X      case OBJ_FILE_SAVED: return (FILE_PROBE);
X      case SYM_FILE_SAVED: return (INVALID);
X      case INVALID: return (INVALID);
X   }
X}
X
Xint AnimateProc ()
X{
X   switch (SaveTmpFile ("tmpmodel"))
X   {
X      case OBJ_FILE_SAVED: return (FILE_ANIMATE);
X      case SYM_FILE_SAVED: return (INVALID);
X      case INVALID: return (INVALID);
X   }
X}
X
Xint EscapeProc ()
X{
X   return (FILE_ESCAPE);
X}
X
Xint FileMenu (X, Y)
X   int	X, Y;
X{
X   register int index;
X   int		* fore_colors, * valid;
X
X   DefaultColorArrays (FILEMENUENTRIES, &fore_colors, &valid);
X   index = TextMenuLoop (X, Y, fileMenuStr, FILEMENUENTRIES, fore_colors,
X         valid, SINGLECOLOR);
X   switch (index)
X   {
X      case FILE_NEW: NewProc (); break;
X      case FILE_OPEN: OpenProc (); break;
X      case FILE_SAVE: SaveFile (); break;
X      case FILE_SAVENEW: SaveNewFile (); break;
X      case FILE_IMPORT: ImportFile (); break;
X      case FILE_IMPORTXBM: ImportXBitmapFile (); break;
X      case FILE_DOMAIN: ChangeDomain (); break;
X      case FILE_DUMP: Dump (FALSE, ""); break;
X      case FILE_USR_DUMP: PrintWithCommand (FALSE, ""); break;
X      case FILE_SOLVE: return (SolveProc ());
X      case FILE_SIMULATE: return (SimulateProc ());
X      case FILE_PROBE: return (ProbeProc ());
X      case FILE_ANIMATE: return (AnimateProc ());
X      case FILE_ESCAPE: return (EscapeProc ());
X      case FILE_QUIT: return (QuitProc ());
X   }
X   return (INVALID);
X}
X
Xvoid CleanUpFiles ()
X{
X   ClearFileInfo ();
X   fileModified = FALSE;
X}
X
Xvoid EmergencySave ()
X{
X   if (exitNormally) return;
X
X   signal (SIGHUP, SIG_DFL);
X   signal (SIGFPE, SIG_DFL);
X   signal (SIGBUS, SIG_DFL);
X   signal (SIGSEGV, SIG_DFL);
X
X   switch (SaveTmpFile ("EmergencySave"))
X   {
X      case OBJ_FILE_SAVED:
X         fprintf (stderr, "Saved to EmergencySave.obj.\n");
X         break;
X      case SYM_FILE_SAVED:
X         fprintf (stderr, "Saved to EmergencySave.sym.\n");
X         break;
X      case INVALID:
X         fprintf (stderr, "Unable to save working file.\n");
X         break;
X   }
X   exitNormally = TRUE;
X   exit (0);
X}
X
Xint EmergencySaveForX (dsp, ev)
X   Display	* dsp;
X   XErrorEvent	* ev;
X{
X   if (exitNormally) return (0);
X
X   signal (SIGHUP, SIG_DFL);
X   signal (SIGFPE, SIG_DFL);
X   signal (SIGBUS, SIG_DFL);
X   signal (SIGSEGV, SIG_DFL);
X
X   switch (SaveTmpFile ("EmergencySave"))
X   {
X      case OBJ_FILE_SAVED:
X         fprintf (stderr, "Saved to EmergencySave.obj.\n");
X         break;
X      case SYM_FILE_SAVED:
X         fprintf (stderr, "Saved to EmergencySave.sym.\n");
X         break;
X      case INVALID:
X         fprintf (stderr, "Unable to save working file.\n");
X         break;
X   }
X   exitNormally = TRUE;
X   return (-1);
X}
END_OF_FILE
if test 41175 -ne `wc -c <'file.c'`; then
    echo shar: \"'file.c'\" unpacked with wrong size!
fi
# end of 'file.c'
fi
echo shar: End of archive 4 \(of 23\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 23 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
---------------------------------> 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