[comp.sources.x] v12i024: tgif, Part08/23

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

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

---------------------------------> 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 8 (of 23)."
# Contents:  names.c obj.c oval.c
# Wrapped by william@oahu on Wed Mar  6 09:57:22 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'names.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'names.c'\"
else
echo shar: Extracting \"'names.c'\" \(46854 characters\)
sed "s/^X//" >'names.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/names.c,v 2.0 91/03/05 12:47:39 william Exp $";
X#endif
X
X#include <sys/types.h>
X#include <sys/dir.h>
X#include <sys/stat.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "const.h"
X#include "types.h"
X
X#include "box.e"
X#include "button.e"
X#include "cursor.e"
X#include "file.e"
X#include "font.e"
X#include "mainloop.e"
X#include "raster.e"
X#include "scroll.e"
X#include "setup.e"
X
X#include "xbm/uparrow.xbm"
X#include "xbm/downarrow.xbm"
X
X#define ITEM_DSPED 10
X#define ITEM_LEN 30
X#define ROW_HEIGHT (defaultFontHeight+1)
X#define BUTTON_OK 0
X#define BUTTON_SETDIR 1
X#define BUTTON_CANCEL 2
X#define MAXBUTTONS 3
X
Xtypedef struct _DspList {
X   char			itemstr[MAXPATHLENGTH+1];
X   char			pathstr[MAXPATHLENGTH+1];
X   int			directory;
X   struct _DspList	* next;
X} DspList;
X
Xextern char	* getenv ();
X
Xchar	curDomainName[MAXPATHLENGTH];
Xchar	curDomainPath[MAXPATHLENGTH];
Xchar	curDir[MAXPATHLENGTH];
Xchar	curImportDir[MAXPATHLENGTH];
Xchar	curSymDir[MAXPATHLENGTH];
X
Xstatic Window		nameBaseWin;
Xstatic Window		nameDspWin;
Xstatic Window		nameScrollWin;
Xstatic int		nameEntries;
Xstatic char		* * nameDspPtr;
Xstatic int		nameFirst;
Xstatic int		nameMarked;
Xstatic struct BBRec	buttonBBox[MAXBUTTONS];
Xstatic int		numButtons = 2;
Xstatic char		buttonStr[MAXBUTTONS][8];
X
Xstatic int	nameDspH;		/* height of display area */
Xstatic int	nameDspW;		/* width of display area */
Xstatic int	nameDspWinH;		/* height of display window */
Xstatic int	nameDspWinW;		/* width of display window */
Xstatic int	nameScrollAreaH;	/* heighr of the grey scroll area */
X
Xstatic int	doubleClickInterval;
X
Xstatic GC	nameGC;
Xstatic GC	revNameGC;
X
Xstatic DspList	* symbolList = NULL;
Xstatic int	numSymbols;
Xstatic DspList	* dirList = NULL;
Xstatic int	numDirEntries;
X
Xstatic DspList	* topOfSymLinkList = NULL;
Xstatic DspList	* topOfDirLinkList = NULL;
X
Xstatic
Xchar * ReadPath (path_str, dir_str)
X   char * path_str, * dir_str;
X{
X   register char        * s1, * s2;
X
X   s1 = path_str;
X   if (*s1 == '~')
X   {
X      strcpy (dir_str, homeDir);
X      s2 = &dir_str[strlen(dir_str)];
X      s1++;
X   }
X   else
X      s2 = dir_str;
X
X   for ( ; *s1 != '\0' && *s1 != ':'; s1++)
X      if (*s1 == '\\')
X         strcpy (s1, s1+1);
X      else
X         *s2++ = *s1;
X
X   *s2 = '\0';
X   if (*s1 == ':') s1++;
X   return (s1);
X}
X
Xvoid ParseSymPath (path_str)
X   char * path_str;
X{
X   register char        * s;
X   register int         i;
X   char                 dir_str[MAXPATHLENGTH];
X
X   for (i = 0, s = path_str; *s != '\0'; )
X   {
X      s = ReadPath (s, dir_str);
X      if (dir_str != '\0') i++;
X   }
X   symPath = (char * *) calloc (i, sizeof (char *));
X   symPathNumEntries = i;
X   for (i = 0, s = path_str; *s != '\0'; )
X   {
X      s = ReadPath (s, dir_str);
X      if (dir_str != '\0')
X      {
X         symPath[i] = (char *) calloc (MAXPATHLENGTH, sizeof (char));
X         strcpy (symPath[i], dir_str);
X         i++;
X      }
X   }
X   strcpy (curDomainPath, path_str);
X}
X
Xstatic
XDspList * SymbolListing ()
X{
X   int			len, path_index, count = 0, reject;
X   char			path[MAXPATHLENGTH];
X   DspList		* dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1;
X   DIR			* dirp;
X   struct direct	* d;
X
X   head_ptr = tail_ptr = NULL;
X   for (path_index = 0; path_index < symPathNumEntries; path_index++)
X   {
X      strcpy (path, symPath[path_index]);
X      if (strcmp (".", path) == 0) strcpy (path, curDir);
X
X      if ((dirp = opendir (path)) == NULL)
X         continue;
X
X      while ((d = readdir (dirp)) != NULL)
X      {
X         len = strlen (d->d_name);
X         if (len > 4 && (strcmp (".sym", &d->d_name[len-4]) == 0))
X            d->d_name[len-4] = '\0';
X         else
X            continue;
X
X         if (head_ptr == NULL)
X         {
X            head_ptr = tail_ptr = (DspList *) calloc (1, sizeof(DspList));
X            strcpy (head_ptr->itemstr, d->d_name);
X            strcpy (head_ptr->pathstr, path);
X         }
X         else
X         {
X            p1 = NULL;
X            reject = FALSE;
X            for (p = head_ptr; p != NULL; p = p->next)
X            {
X               if (strcmp (d->d_name, p->itemstr) == 0)
X               {
X                  reject = TRUE;
X                  break;
X               }
X               else if (LargerStr (d->d_name, p->itemstr))
X                  p1 = p;
X               else
X               {
X                  dsp_ptr = (DspList *) calloc (1, sizeof(DspList));
X                  strcpy (dsp_ptr->itemstr, d->d_name);
X                  strcpy (dsp_ptr->pathstr, path);
X                  break;
X               }
X            }
X            if (reject) continue;
X   
X            dsp_ptr = (DspList *) calloc (1, sizeof(DspList));
X            dsp_ptr->next = p;
X            strcpy (dsp_ptr->itemstr, d->d_name);
X            strcpy (dsp_ptr->pathstr, path);
X
X            if (p == NULL)
X            {  /* dsp_ptr has the largest element */
X               tail_ptr->next = dsp_ptr;
X               tail_ptr = dsp_ptr;
X            }
X            else if (p1 == NULL)
X               head_ptr = dsp_ptr;
X            else
X               p1->next = dsp_ptr;
X         }
X         count++;
X      }
X      closedir (dirp);
X   }
X   numSymbols = count;
X   return (head_ptr);
X}
X
Xstatic
Xvoid BuildSymbolList ()
X{
X   register int		i;
X   register DspList	* dsp_ptr;
X
X   if (symbolList != NULL) cfree (symbolList);
X
X   symbolList = (DspList *) calloc (numSymbols, sizeof (DspList));
X   dsp_ptr = topOfSymLinkList;
X   for (i = 0; i < numSymbols; i++, dsp_ptr = dsp_ptr->next)
X   {
X      strcpy (symbolList[i].itemstr, dsp_ptr->itemstr);
X      strcpy (symbolList[i].pathstr, dsp_ptr->pathstr);
X      symbolList[i].next = &symbolList[i+1];
X      cfree (dsp_ptr);
X   }
X   symbolList[numSymbols-1].next = NULL;
X   topOfSymLinkList = NULL;
X}
X
Xstatic
XDspList * DirListing (Path, ExtStr)
X   char	* Path, * ExtStr;
X{
X   DspList		* dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1;
X   DIR			* dirp;
X   struct direct	* d;
X   int			len, ext_len, count = 0;
X   char			path[MAXPATHLENGTH], s[MAXPATHLENGTH];
X   char			ext_str[MAXPATHLENGTH];
X   struct stat		stat_buf;
X
X   if (*Path == '\0')
X   {
X      strcpy (path, "/");
X      if ((dirp = opendir (path)) == NULL) return (NULL);
X   }
X   else
X   {
X      strcpy (path, Path);
X      if ((dirp = opendir (path)) == NULL) return (NULL);
X      strcat (path, "/");
X   }
X
X   sprintf (ext_str, ".%s", ExtStr);
X   ext_len = strlen (ext_str);
X
X   head_ptr = tail_ptr = NULL;
X
X   while ((d = readdir (dirp)) != NULL)
X   {
X      len = strlen (d->d_name);
X      if (len > ext_len && (strcmp (ext_str, &d->d_name[len-ext_len]) == 0))
X      {
X         d->d_name[len-ext_len] = '\0';
X         dsp_ptr = (DspList *) calloc (1, sizeof(DspList));
X         dsp_ptr->directory = FALSE;
X         strcpy (dsp_ptr->itemstr, d->d_name);
X      }
X      else if (strcmp (d->d_name, ".") == 0)
X         continue;
X      else
X      {
X         sprintf (s, "%s%s", path, d->d_name);
X         stat (s, &stat_buf);
X         if (stat_buf.st_mode & S_IFDIR)
X         {
X            dsp_ptr = (DspList *) calloc (1, sizeof(DspList));
X            dsp_ptr->directory = TRUE;
X            strcat (d->d_name, "/");
X            strcpy (dsp_ptr->itemstr, d->d_name);
X         }
X         else
X            continue;
X      }
X      if (head_ptr == NULL)
X         head_ptr = tail_ptr = dsp_ptr;
X      else
X      {
X         p1 = NULL;
X         for (p = head_ptr; p != NULL; p = p->next)
X            if (LargerStr (d->d_name, p->itemstr))
X               p1 = p;
X            else
X               break;
X
X         dsp_ptr->next = p;
X         if (p == NULL)
X         {  /* dsp_ptr has the largest element */
X            tail_ptr->next = dsp_ptr;
X            tail_ptr = dsp_ptr;
X         }
X         else if (p1 == NULL)
X            head_ptr = dsp_ptr;
X         else
X            p1->next = dsp_ptr;
X      }
X      count++;
X   }
X
X   closedir (dirp);
X   numDirEntries = count;
X   return (head_ptr);
X}
X
Xstatic
Xvoid BuildDirList ()
X{
X   register int		i;
X   register DspList	* dsp_ptr;
X
X   if (topOfDirLinkList != NULL)
X   {
X      if (dirList != NULL) cfree (dirList);
X
X      dirList = (DspList *) calloc (numDirEntries, sizeof (DspList));
X      dsp_ptr = topOfDirLinkList;
X      for (i = 0; i < numDirEntries; i++, dsp_ptr = dsp_ptr->next)
X      {
X         strcpy (dirList[i].itemstr, dsp_ptr->itemstr);
X         strcpy (dirList[i].pathstr, dsp_ptr->pathstr);
X         dirList[i].directory = dsp_ptr->directory;
X         dirList[i].next = &dirList[i+1];
X         cfree (dsp_ptr);
X      }
X      dirList[numDirEntries-1].next = NULL;
X      topOfDirLinkList = NULL;
X   }
X}
X
Xvoid InitNames ()
X{
X   int		default_found = FALSE;
X   char		* c_ptr, domain_str[20], sym_path[80];
X   XGCValues	values;
X
X   values.foreground = myFgPixel;
X   values.background = myBgPixel;
X   values.fill_style = FillSolid;
X   values.font = defaultFontPtr->fid;
X   nameGC = XCreateGC (mainDisplay, rootWindow,
X         GCForeground | GCBackground | GCFillStyle | GCFont, &values);
X
X   values.foreground = myBgPixel;
X   values.background = myFgPixel;
X   revNameGC = XCreateGC (mainDisplay, rootWindow,
X         GCForeground | GCBackground | GCFillStyle | GCFont, &values);
X
X   nameDspW = ITEM_LEN * defaultFontWidth;
X   nameDspH = ITEM_DSPED * ROW_HEIGHT;
X   nameDspWinW = nameDspW + 2 * brdrW;
X   nameDspWinH = nameDspH + 2 * brdrW;
X   nameScrollAreaH = nameDspH - 2 * uparrow_height;
X
X   *curDomainName = '\0';
X   *curDomainPath = '\0';
X   *curSymDir = '\0';
X   strcpy (curDir, bootDir);
X   strcpy (curImportDir, bootDir);
X
X   if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "DoubleClickInterval")) !=
X         NULL)
X      doubleClickInterval = atoi (c_ptr);
X   else
X      doubleClickInterval = 300;
X
X   if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "DefaultDomain")) != NULL)
X   {
X      sprintf (domain_str, "Domain%s", c_ptr);
X      if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, domain_str)) != NULL)
X      {
X         if (*c_ptr != '\0')
X         {
X            strcpy (curDomainName, c_ptr);
X            sprintf (sym_path, "TGIF_%s", c_ptr);
X            default_found = TRUE;
X         }
X      }
X   }
X
X   if (!default_found || (c_ptr = getenv (sym_path)) == NULL)
X      ParseSymPath (".");
X   else
X      if (strlen (c_ptr) >= MAXPATHLENGTH-1)
X         ParseSymPath (".");
X      else 
X         ParseSymPath (c_ptr);
X   if ((topOfSymLinkList = SymbolListing ()) != NULL) BuildSymbolList ();
X}
X
Xvoid UpdateDirInfo ()
X{
X   if ((topOfDirLinkList = DirListing (curDir, "obj")) != NULL) BuildDirList ();
X}
X
Xvoid UpdateSymInfo ()
X{
X   if ((topOfSymLinkList = SymbolListing ()) != NULL) BuildSymbolList ();
X}
X
Xvoid CleanUpNames ()
X{
X   XFreeGC (mainDisplay, nameGC);
X   XFreeGC (mainDisplay, revNameGC);
X
X   if (symbolList != NULL) cfree (symbolList);
X   if (dirList != NULL) cfree (dirList);
X}
X
Xstatic
Xvoid RedrawNameScrollWin ()
X{
X   double        frac, start_frac;
X   int          block_h, block_start;
X   XGCValues	values;
X   XEvent	ev;
X
X   XSync (mainDisplay, FALSE);
X   while (XCheckWindowEvent (mainDisplay, vSBarWindow, ExposureMask, &ev)) ;
X
X   start_frac = (nameEntries > 0) ?
X         (double)((double)(nameFirst)/(double)(nameEntries)) : (double)(0);
X   block_start = (int)(nameScrollAreaH * start_frac); /* starting pixel */
X
X   if (nameEntries > ITEM_DSPED)
X      frac = (double)((double)ITEM_DSPED / (double)(nameEntries));
X   else
X      frac = 1.0;
X
X   block_h = (int)(nameScrollAreaH * frac); /* number of pixels */
X
X   values.foreground = myBgPixel;
X   values.background = myFgPixel;
X   values.function = GXcopy;
X   values.fill_style = FillSolid;
X   XChangeGC (mainDisplay, scrollGC,
X         GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
X   XFillRectangle (mainDisplay, nameScrollWin, scrollGC, 0, scrollBarW,
X         scrollBarW, nameScrollAreaH);
X
X   values.foreground = myFgPixel;
X   values.background = myBgPixel;
X   values.fill_style = FillOpaqueStippled;
X   values.stipple = patPixmap[SCROLLPAT];
X   XChangeGC (mainDisplay, scrollGC,
X         GCForeground | GCBackground | GCFillStyle | GCStipple, &values);
X   XFillRectangle (mainDisplay, nameScrollWin, scrollGC, 0,
X         scrollBarW+block_start, scrollBarW, block_h);
X
X   scrollImage->data = upData;
X   XPutImage (mainDisplay, nameScrollWin, scrollGC, scrollImage, 0, 0, 0, 0,
X         scrollBarW, scrollBarW);
X   scrollImage->data = downData;
X   XPutImage (mainDisplay, nameScrollWin, scrollGC, scrollImage, 0, 0,
X         0, scrollBarW+nameScrollAreaH, scrollBarW, scrollBarW);
X}
X
Xstatic
Xvoid RedrawDspWindow ()
X{
X   register int	i;
X   int		top, len, end;
X
X   top = defaultFontAsc+1;
X
X   if (nameFirst+ITEM_DSPED > nameEntries)
X      end = nameEntries;
X   else
X      end = nameFirst + ITEM_DSPED;
X
X   XFillRectangle (mainDisplay, nameDspWin, revNameGC, 0, 0,
X         ITEM_LEN*defaultFontWidth, ITEM_DSPED*ROW_HEIGHT);
X
X   for (i = nameFirst; i < end; i++)
X   {
X      len = strlen (nameDspPtr[i]);
X      if (i == nameMarked)
X      {
X         XFillRectangle (mainDisplay, nameDspWin, nameGC,
X               0, (i-nameFirst)*ROW_HEIGHT, ITEM_LEN*defaultFontWidth,
X               ROW_HEIGHT);
X         XDrawString (mainDisplay, nameDspWin, revNameGC,
X               0, (i-nameFirst)*ROW_HEIGHT+top, nameDspPtr[i], len);
X      }
X      else
X      {
X         XFillRectangle (mainDisplay, nameDspWin, revNameGC,
X               0, (i-nameFirst)*ROW_HEIGHT, ITEM_LEN*defaultFontWidth,
X               ROW_HEIGHT);
X         XDrawString (mainDisplay, nameDspWin, nameGC,
X               0, (i-nameFirst)*ROW_HEIGHT+top, nameDspPtr[i], len);
X      }
X   }
X}
X
Xstatic
Xvoid RedrawNamePath (Path, X, Y)
X   char	* Path;
X   int	X, Y;
X{
X   int	len = strlen (Path), cursor_x, cursor_y;
X   char	* c_ptr;
X
X   cursor_y = Y-defaultFontAsc;
X
X   XClearArea (mainDisplay, nameBaseWin, X, Y-defaultFontAsc,
X         ITEM_LEN*defaultFontWidth+4, defaultFontHeight+4, False);
X   XDrawRectangle (mainDisplay, nameBaseWin, nameGC, X, cursor_y-2,
X         ITEM_LEN*defaultFontWidth+8, defaultFontHeight+4);
X
X   if (len > ITEM_LEN)
X   {
X      c_ptr = &(Path[len-ITEM_LEN]);
X      len = ITEM_LEN;
X   }
X   else
X      c_ptr = Path;
X
X   cursor_x = X+2+len*defaultFontWidth;
X   XDrawString (mainDisplay, nameBaseWin, nameGC, X+2, Y, c_ptr, len);
X   XDrawLine (mainDisplay, nameBaseWin, nameGC, cursor_x,
X         cursor_y, cursor_x, cursor_y+defaultFontHeight);
X}
X
Xstatic
Xvoid RedrawNameBaseWindow (Str, Path, str_start, path_start, button_start, W, H)
X   char	* Str, * Path;
X   int	str_start, path_start, button_start, W, H;
X{
X   int	i, top = defaultFontAsc+2, left;
X
X   XDrawRectangle (mainDisplay, nameBaseWin, nameGC, 0, 0, W-1, H-1);
X   XDrawString (mainDisplay, nameBaseWin, nameGC, str_start,
X         ROW_HEIGHT+top, Str, strlen(Str));
X   RedrawNamePath (Path, path_start, 3*ROW_HEIGHT+top);
X
X   left = button_start;
X   for (i = 0; i < numButtons; i++)
X   {
X      buttonBBox[i].lty = (ITEM_DSPED+6) * ROW_HEIGHT;
X      buttonBBox[i].ltx = left;
X      DisplayButton (nameBaseWin, buttonStr[i], 8, &(buttonBBox[i]),
X            BUTTON_NORMAL);
X      left = buttonBBox[i].rbx + 1 + defaultFontWidth;
X   }
X}
X
Xstatic
Xchar * * MakeNameDspItemArray (Entries, DLPtr)
X   int		Entries;
X   DspList	* DLPtr;
X{
X   register int	i, j, len;
X   char		* * dsp_ptr, * c_ptr;
X
X   if (Entries == 0) return (NULL);
X
X   dsp_ptr = (char * *) calloc (Entries, sizeof(char *));
X   c_ptr = (char *) calloc (Entries*MAXPATHLENGTH, sizeof(char));
X   for (i = 0; i < Entries; i++, DLPtr = DLPtr->next)
X   {
X      dsp_ptr[i] = c_ptr;
X      len = strlen (DLPtr->itemstr);
X      if (!DLPtr->directory)
X      {
X         for (j = len; j >= 0 && DLPtr->itemstr[j] != '/'; j--) ;
X         if (j >= 0)
X            strcpy (c_ptr, (&(DLPtr->itemstr[j]))+1);
X         else
X            strcpy (c_ptr, DLPtr->itemstr);
X      }
X      else
X         strcpy (c_ptr, DLPtr->itemstr);
X
X      c_ptr += MAXPATHLENGTH;
X   }
X   return (dsp_ptr);
X}
X
Xstatic
Xint GetNameEntryNum (RowOffset)
X   int		RowOffset;
X{
X   register int	index;
X
X   index = nameFirst + RowOffset;
X   if (index >= nameEntries) return (INVALID);
X   return (index);
X}
X
Xstatic
Xvoid NameScrollHandler (button_ev)
X   XButtonEvent	* button_ev;
X{
X   double	frac, start_frac;
X   int		block_h, block_start;
X
X   if (button_ev->y < scrollBarW)
X   {
X      /* clicked in the uparrow */
X      if (nameFirst != 0)
X      {
X         nameFirst--;
X         RedrawNameScrollWin ();
X         RedrawDspWindow ();
X         return;
X      }
X   }
X   else if (button_ev->y >= scrollBarW+nameScrollAreaH)
X   {
X      /* clicked in the downarrow */
X      if (nameEntries <= ITEM_DSPED) return;
X
X      if (nameFirst+ITEM_DSPED != nameEntries)
X      {
X         nameFirst++;
X         RedrawNameScrollWin ();
X         RedrawDspWindow ();
X         return;
X      }
X   }
X   else /* clicked in the middle region */
X   {
X      if (nameEntries <= ITEM_DSPED) return;
X
X      frac = (double)((double)ITEM_DSPED / (double)(nameEntries));
X      block_h = (int)(nameScrollAreaH * frac);
X      block_start = button_ev->y - scrollBarW;
X      start_frac = (double)((double)(block_start)/(double)(nameScrollAreaH));
X      if (block_start+block_h >= nameScrollAreaH)
X      {
X         nameFirst = nameEntries - ITEM_DSPED;
X         RedrawNameScrollWin ();
X         RedrawDspWindow ();
X         return;
X      }
X      else
X      {
X         nameFirst = (int)(nameEntries * start_frac);
X         RedrawNameScrollWin ();
X         RedrawDspWindow ();
X         return;
X      }
X   }
X}
X
Xstatic Time	lastClickTime;
Xstatic int	justClicked;
Xstatic int	lastNameMarked;
X
Xstatic
Xint NameDspHandler (button_ev)
X   XButtonEvent	* button_ev;
X{
X   int	row_offset, len, top;
X   Time	click_time;
X
X   top = defaultFontAsc+1;
X
X   row_offset = (int)(button_ev->y / ROW_HEIGHT);
X
X   if (nameMarked != INVALID &&
X         nameMarked >= nameFirst && nameMarked < nameFirst+ITEM_DSPED)
X   {
X      len = strlen (nameDspPtr[nameMarked]);
X      XFillRectangle (mainDisplay, nameDspWin, revNameGC, 0,
X            (nameMarked - nameFirst)*ROW_HEIGHT,
X            ITEM_LEN*defaultFontWidth, ROW_HEIGHT);
X      XDrawString (mainDisplay, nameDspWin, nameGC, 0,
X            (nameMarked - nameFirst)*ROW_HEIGHT+top,
X            nameDspPtr[nameMarked], len);
X   }
X
X   nameMarked = GetNameEntryNum (row_offset);
X   if (nameMarked != INVALID)
X   {
X      len = strlen (nameDspPtr[nameMarked]);
X      XFillRectangle (mainDisplay, nameDspWin, nameGC, 0,
X            (nameMarked - nameFirst)*ROW_HEIGHT,
X            ITEM_LEN*defaultFontWidth, ROW_HEIGHT);
X      XDrawString (mainDisplay, nameDspWin, revNameGC, 0,
X            (nameMarked - nameFirst)*ROW_HEIGHT+top,
X            nameDspPtr[nameMarked], len);
X   }
X
X   click_time = button_ev->time;
X   if (justClicked && nameMarked != INVALID && lastNameMarked == nameMarked &&
X         (click_time-lastClickTime) < doubleClickInterval)
X      return (TRUE);
X
X   justClicked = TRUE;
X   lastClickTime = click_time;
X   lastNameMarked = nameMarked;
X   return (INVALID);
X}
X
Xstatic char * okCancelStr[] = { "OK", "CANCEL" };
X
Xstatic
Xint LargerStr (S1, S2)
X   register char	* S1, * S2;
X   /* returns TRUE if S1 > S2 */
X{
X   while (*S1 == *S2 && *S1 != '\0' && *S2 != '\0') { S1++; S2++; }
X
X   return (*S1 > *S2);
X}
X
Xstatic
Xint DirNames (TopStr, ExtStr, SelStr, JustSetDir)
X   char	* TopStr, * ExtStr, * SelStr;
X   int	*JustSetDir;
X{
X   int			button_widths, str_width, graph_width;
X   int			str_start, button_start, graph_start, index = 0;
X   int			dsp_w, dsp_h, w, h, i, exposure = 0;
X   int			button_selected = INVALID, change_to_root;
X   int			faking_dot_dot;
X   XEvent		input;
X   int			looping = TRUE, changing, name_index, pop_from_root;
X   char			buf[80], name[MAXPATHLENGTH], full_name[MAXPATHLENGTH];
X   char			dir_name[MAXPATHLENGTH], sel_str[MAXPATHLENGTH];
X   char			saved_dir_name[MAXPATHLENGTH], saved_name[MAXSTRING];
X   XKeyEvent		* key_ev;
X   XButtonEvent		* button_ev;
X   KeySym		key_sym;
X   XComposeStatus	c_stat;
X   XSetWindowAttributes	win_attrs;
X   int			win_x, win_y;
X   DspList		* dsp_ptr;
X
X   dsp_w = DisplayWidth (mainDisplay, mainScreen);
X   dsp_h = DisplayHeight (mainDisplay, mainScreen);
X
X   button_widths = ButtonWidth("OK", 8) + ButtonWidth("CANCEL", 8) +
X         ButtonWidth("SETDIR", 8) + defaultFontWidth;
X   numButtons = 3;
X   strcpy (buttonStr[0], "OK");
X   strcpy (buttonStr[1], "SETDIR");
X   strcpy (buttonStr[2], "CANCEL");
X
X   str_width = defaultFontWidth * strlen (TopStr);
X   graph_width = nameDspWinW + scrollBarW + 2 * brdrW;
X
X   if (str_width > graph_width)
X   {
X      w = str_width + 4 * defaultFontWidth;
X      str_start = 2 * defaultFontWidth;
X      graph_start = (w - graph_width) / 2;
X   }
X   else
X   {
X      w = graph_width + 4 * defaultFontWidth;
X      str_start = (w - str_width) / 2;
X      graph_start = 2 * defaultFontWidth;
X   }
X   button_start = (w - button_widths) / 2;
X   h = (8 + ITEM_DSPED) * ROW_HEIGHT;
X
X   win_x = (w > dsp_w) ? 0 : (dsp_w - w)/2;
X   win_y = (h > dsp_h) ? 0 : (dsp_h - h)/3;
X
X   if ((nameBaseWin = XCreateSimpleWindow (mainDisplay, rootWindow,
X         win_x, win_y, w, h, brdrW, myBorderPixel, myBgPixel)) == 0)
X   { printf ("Could not create desired popup window!\n"); exit (-1); }
X
X   XDefineCursor (mainDisplay, nameBaseWin, defaultCursor);
X
X   if ((nameDspWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, graph_start,
X         5*ROW_HEIGHT, nameDspW, nameDspH, brdrW, myBorderPixel,
X         myBgPixel)) == 0)
X   { printf ("Could not create desired popup window!\n"); exit (-1); }
X
X   if ((nameScrollWin = XCreateSimpleWindow (mainDisplay, nameBaseWin,
X         graph_start+nameDspWinW, 5*ROW_HEIGHT, scrollBarW, nameDspH,
X         brdrW, myBorderPixel, myBgPixel)) == 0)
X   { printf ("Could not create desired popup scroll window!\n"); exit (-1); }
X
X   win_attrs.save_under = True;
X   XChangeWindowAttributes (mainDisplay, nameBaseWin, CWSaveUnder, &win_attrs);
X
X   XSetTransientForHint (mainDisplay, nameBaseWin, mainWindow);
X
X   XMapWindow (mainDisplay, nameBaseWin);
X   XSelectInput (mainDisplay, nameBaseWin,
X         KeyPressMask | ButtonPressMask | ExposureMask);
X
X   XMapWindow (mainDisplay, nameDspWin);
X   XSelectInput (mainDisplay, nameDspWin,
X         KeyPressMask | ButtonPressMask | ExposureMask);
X
X   XMapWindow (mainDisplay, nameScrollWin);
X   XSelectInput (mainDisplay, nameScrollWin,
X         KeyPressMask | ButtonPressMask | ExposureMask);
X
X   if (importingFile)
X      strcpy (dir_name, curImportDir);
X   else
X      strcpy (dir_name, curDir);
X
X   dsp_ptr = topOfDirLinkList;
X   for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr);
X   topOfDirLinkList = NULL;
X
X   Msg ("Generating list of file names, please wait ...");
X   if ((topOfDirLinkList = DirListing (dir_name, ExtStr)) == NULL)
X   {
X      *sel_str = '\0';
X      looping = FALSE;
X   }
X
X   justClicked = FALSE;
X   *saved_dir_name = '\0';
X   faking_dot_dot = FALSE;
X   while (looping)
X   {
X      nameEntries = numDirEntries;
X      if (topOfDirLinkList == NULL)
X         nameDspPtr = MakeNameDspItemArray (nameEntries, dirList);
X      else
X         nameDspPtr = MakeNameDspItemArray (nameEntries, topOfDirLinkList);
X      nameFirst = 0;
X      nameMarked = 0;
X
X      if (faking_dot_dot)
X      {
X         name_index = strlen (saved_name);
X         for (i = 0; i < nameEntries; i++)
X            if (strncmp (nameDspPtr[i], saved_name, name_index) == 0)
X            {
X               strcpy (name, saved_name);
X               if (i >= ITEM_DSPED)
X               {
X                  if (i < nameEntries-ITEM_DSPED)
X                     nameFirst = i;
X                  else
X                     nameFirst = nameEntries-ITEM_DSPED;
X               }
X               nameMarked = i;
X               break;
X            }
X
X         if (i == nameEntries)
X         {
X            name[0] = '\0';
X            name_index = 0;
X         }
X      }
X      else
X      {
X         name[0] = '\0';
X         name_index = 0;
X      }
X
X      sprintf (full_name, "%s/%s", dir_name, name);
X
X      if (exposure >= 3)
X      {
X         XClearWindow (mainDisplay, nameBaseWin);
X         XClearWindow (mainDisplay, nameDspWin);
X         XClearWindow (mainDisplay, nameScrollWin);
X         RedrawNameBaseWindow (TopStr, full_name, str_start, graph_start,
X               button_start, w, h);
X         RedrawNameScrollWin ();
X         RedrawDspWindow ();
X      }
X
X      changing = TRUE;
X      change_to_root = FALSE;
X      pop_from_root = FALSE;
X      faking_dot_dot = FALSE;
X      while (changing)
X      {
X         XNextEvent (mainDisplay, &input);
X         if (input.type == Expose)
X         {
X            if (input.xany.window == nameBaseWin)
X            {
X               RedrawNameBaseWindow (TopStr, full_name, str_start, graph_start,
X                     button_start, w, h);
X               exposure++;
X            }
X            else if (input.xany.window == nameScrollWin)
X            {
X               RedrawNameScrollWin ();
X               exposure++;
X            }
X            else if (input.xany.window == nameDspWin)
X            {
X               RedrawDspWindow ();
X               exposure++;
X            }
X
X            continue;
X         }
X         else if (input.type == KeyPress)
X         {
X            key_ev = &(input.xkey);
X            XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
X
X            if ((buf[0]=='\r' && (key_sym & 0xff)=='\r') ||
X                (buf[0]=='\n' && (key_sym & 0xff)=='\n'))
X            {
X               changing = FALSE;
X               index = nameMarked;
X               button_selected = BUTTON_OK;
X            }
X            else if (buf[0]=='\033' && (key_sym & 0xff)=='\033')
X            {
X               looping = FALSE;
X               changing = FALSE;
X               index = INVALID;
X               button_selected = BUTTON_CANCEL;
X            }
X            else if ((buf[0]=='\b' && (key_sym & 0xff)=='\b') ||
X                  (buf[0]=='\b' && (key_sym & 0xff)=='h') ||
X                  (buf[0]=='\177' && (key_sym & 0x7f)=='\177'))
X            {
X               if (name_index != 0)
X               {
X                  name[--name_index] = '\0';
X
X                  sprintf (full_name, "%s/%s", dir_name, name);
X
X                  for (i = 0; i < nameEntries; i++)
X                     if (strncmp (nameDspPtr[i], name, name_index) == 0)
X                        break;
X
X                  if (i < nameEntries)
X                  {
X                     if (i < nameFirst)
X                        nameFirst = i;
X                     else if (i >= nameFirst+ITEM_DSPED)
X                     {
X                        if (i < nameEntries-ITEM_DSPED)
X                           nameFirst = i;
X                        else
X                           nameFirst = nameEntries-ITEM_DSPED;
X                     }
X                     nameMarked = i;
X                     RedrawNamePath (full_name, graph_start,
X                           3*ROW_HEIGHT+defaultFontAsc+2);
X                     RedrawNameScrollWin ();
X                     RedrawDspWindow ();
X                  }
X               }
X               else if (*dir_name == '\0' && *saved_dir_name != '\0')
X               {
X                  changing = FALSE;
X                  pop_from_root = TRUE;
X                  index = INVALID;
X                  break;
X               }
X               else
X               {  /* fake as if "../" is selected */
X                  strcpy (name, "../");
X                  name_index = strlen (name);
X                  for (i = 0; i < nameEntries; i++)
X                     if (strncmp (nameDspPtr[i], name, name_index) == 0)
X                        break;
X                  if (i != nameEntries)
X                  {
X                     changing = FALSE;
X                     faking_dot_dot = TRUE;
X                     index = nameMarked = i;
X                  }
X               }
X            }
X            else if (key_sym>='\040' && key_sym<='\177')
X            {
X               if (buf[0] == '$')
X               {
X                  i = (nameEntries == 0) ? 0 : nameEntries-1;
X                  strcpy (name, nameDspPtr[i]);
X               }
X               else if (name_index == 0 && buf[0] == '/')
X               {
X                  if (*saved_dir_name == '\0')
X                     strcpy (saved_dir_name, dir_name);
X                  changing = FALSE;
X                  change_to_root = TRUE;
X                  index = INVALID;
X                  break;
X               }
X               else
X               {
X                  name[name_index++] = buf[0];
X                  name[name_index] = '\0';
X                  for (i = 0; i < nameEntries; i++)
X                     if (strncmp (nameDspPtr[i], name, name_index) == 0)
X                        break;
X               }
X
X               if (i < nameEntries)
X               {
X                  if (buf[0] == '/')
X                  {
X                     changing = FALSE;
X                     index = nameMarked = i;
X                  }
X                  else
X                  {
X                     if (i < nameFirst)
X                        nameFirst = i;
X                     else if (i >= nameFirst+ITEM_DSPED)
X                     {
X                        if (i < nameEntries-ITEM_DSPED)
X                           nameFirst = i;
X                        else
X                           nameFirst = nameEntries-ITEM_DSPED;
X                     }
X                     nameMarked = i;
X
X                     sprintf (full_name, "%s/%s", dir_name, name);
X
X                     RedrawNamePath (full_name, graph_start,
X                           3*ROW_HEIGHT+defaultFontAsc+2);
X                     RedrawNameScrollWin ();
X                     RedrawDspWindow ();
X                  }
X               }
X               else
X                  name[--name_index] = '\0';
X            }
X         }
X         else if (input.type == ButtonPress)
X         {
X            button_ev = &(input.xbutton);
X            if (button_ev->window == nameBaseWin)
X            {
X               if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[0]))
X               {
X                  changing = FALSE;
X                  index = nameMarked;
X                  button_selected = BUTTON_OK;
X               }
X               else if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[1]))
X               {
X                  looping = FALSE;
X                  changing = FALSE;
X                  index = INVALID;
X                  button_selected = BUTTON_SETDIR;
X               }
X               else if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[2]))
X               {
X                  looping = FALSE;
X                  changing = FALSE;
X                  index = INVALID;
X                  button_selected = BUTTON_CANCEL;
X               }
X            }
X            else if (button_ev->window == nameScrollWin)
X               NameScrollHandler (button_ev);
X            else if (button_ev->window == nameDspWin)
X            {
X               if (NameDspHandler (button_ev) != INVALID)
X               {
X                  changing = FALSE;
X                  index = nameMarked;
X               }
X               else if (nameMarked != INVALID)
X               {
X                  strcpy (name, nameDspPtr[nameMarked]);
X                  sprintf (full_name, "%s/%s", dir_name, name);
X                  RedrawNamePath (full_name, graph_start,
X                        3*ROW_HEIGHT+defaultFontAsc+2);
X               }
X            }
X         }
X      }
X
X      if (index != INVALID) strcpy (sel_str, nameDspPtr[index]);
X
X      if (nameDspPtr != NULL)
X      {
X         cfree (*nameDspPtr);
X         cfree (nameDspPtr);
X      }
X
X      if (index == INVALID && !change_to_root && !pop_from_root) break;
X
X      if (change_to_root)
X         *dir_name = '\0';
X      else if (pop_from_root)
X      {
X         strcpy (dir_name, saved_dir_name);
X         *saved_dir_name = '\0';
X      }
X      else if (sel_str[strlen(sel_str)-1] == '/')
X      {
X         sel_str[strlen(sel_str)-1] = '\0';
X         if (strcmp (sel_str, "..") == 0)
X         {
X            for (i = strlen(dir_name)-1; i>=0 && dir_name[i]!='/'; i--) ;
X            if (i < 0)
X            {
X               strcpy (saved_name, dir_name);
X               dir_name[0] = '\0';
X            }
X            else
X            {
X               strcpy (saved_name, &dir_name[i+1]);
X               dir_name[i] = '\0';
X            }
X         }
X         else
X         {
X            strcat (dir_name, "/");
X            strcat (dir_name, sel_str);
X         }
X      }
X      else
X         break;
X
X      dsp_ptr = topOfDirLinkList;
X      for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr);
X      topOfDirLinkList = NULL;
X
X      Msg ("Generating list of file names, please wait ...");
X      if ((topOfDirLinkList = DirListing (dir_name, ExtStr)) == NULL)
X      {
X         *sel_str = '\0';
X         break;
X      }
X      if (importingFile)
X         Msg ("Click on 'SETDIR' to set importing directory.");
X      else
X         Msg ("Click on 'SETDIR' to set current directory.");
X   }
X
X   DisplayButton (nameBaseWin, buttonStr[button_selected], 8,
X         &buttonBBox[button_selected], BUTTON_INVERT);
X   if (button_selected == BUTTON_SETDIR)
X   {
X      sprintf (SelStr, "%s", dir_name);
X      *JustSetDir = TRUE;
X   }
X   else
X   {
X      sprintf (SelStr, "%s/%s", dir_name, sel_str);
X      *JustSetDir = FALSE;
X   }
X
X   XDestroyWindow (mainDisplay, nameBaseWin);
X   XSync (mainDisplay, FALSE);
X   while (XCheckMaskEvent (mainDisplay, ExposureMask, &input)) ;
X   return (index);
X}
X
Xstatic
Xint ChooseAName (TopStr, SelStr)
X   char	* TopStr, * SelStr;
X{
X   int			button_widths, str_width, graph_width;
X   int			str_start, button_start, graph_start, index = 0;
X   int			dsp_w, dsp_h, w, h, i, button_selected = INVALID;
X   XEvent		input;
X   int			changing = TRUE, name_index;
X   char			buf[80], name[MAXPATHLENGTH];
X   XKeyEvent		* key_ev;
X   XButtonEvent		* button_ev;
X   KeySym		key_sym;
X   XComposeStatus	c_stat;
X   XSetWindowAttributes	win_attrs;
X   int			win_x, win_y;
X
X   dsp_w = DisplayWidth (mainDisplay, mainScreen);
X   dsp_h = DisplayHeight (mainDisplay, mainScreen);
X
X   button_widths = ButtonWidth("OK", 8) + ButtonWidth("CANCEL", 8) +
X         defaultFontWidth;
X   numButtons = 2;
X   strcpy (buttonStr[0], "OK");
X   strcpy (buttonStr[1], "CANCEL");
X
X   str_width = defaultFontWidth * strlen (TopStr);
X   graph_width = nameDspWinW + scrollBarW + 2 * brdrW;
X
X   if (str_width > graph_width)
X   {
X      w = str_width + 4 * defaultFontWidth;
X      str_start = 2 * defaultFontWidth;
X      graph_start = (w - graph_width) / 2;
X   }
X   else
X   {
X      w = graph_width + 4 * defaultFontWidth;
X      str_start = (w - str_width) / 2;
X      graph_start = 2 * defaultFontWidth;
X   }
X   button_start = (w - button_widths) / 2;
X   h = (8 + ITEM_DSPED) * ROW_HEIGHT;
X
X   win_x = (w > dsp_w) ? 0 : (dsp_w - w)/2;
X   win_y = (h > dsp_h) ? 0 : (dsp_h - h)/3;
X
X   if ((nameBaseWin = XCreateSimpleWindow (mainDisplay, rootWindow,
X         win_x, win_y, w, h, brdrW, myBorderPixel, myBgPixel)) == 0)
X   { printf ("Could not create desired popup window!\n"); exit (-1); }
X
X   XDefineCursor (mainDisplay, nameBaseWin, defaultCursor);
X
X   if ((nameDspWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, graph_start,
X         5*ROW_HEIGHT, nameDspW, nameDspH, brdrW, myBorderPixel,
X         myBgPixel)) == 0)
X   { printf ("Could not create desired popup window!\n"); exit (-1); }
X
X   if ((nameScrollWin = XCreateSimpleWindow (mainDisplay, nameBaseWin,
X         graph_start+nameDspWinW, 5*ROW_HEIGHT, scrollBarW, nameDspH,
X         brdrW, myBorderPixel, myBgPixel)) == 0)
X   { printf ("Could not create desired popup scroll window!\n"); exit (-1); }
X
X   win_attrs.save_under = True;
X   XChangeWindowAttributes (mainDisplay, nameBaseWin, CWSaveUnder, &win_attrs);
X
X   XSetTransientForHint (mainDisplay, nameBaseWin, mainWindow);
X
X   XMapWindow (mainDisplay, nameBaseWin);
X   XSelectInput (mainDisplay, nameBaseWin,
X         KeyPressMask | ButtonPressMask | ExposureMask);
X
X   XMapWindow (mainDisplay, nameDspWin);
X   XSelectInput (mainDisplay, nameDspWin,
X         KeyPressMask | ButtonPressMask | ExposureMask);
X
X   XMapWindow (mainDisplay, nameScrollWin);
X   XSelectInput (mainDisplay, nameScrollWin,
X         KeyPressMask | ButtonPressMask | ExposureMask);
X
X   justClicked = FALSE;
X
X   Msg ("");
X
X   name[0] = '\0';
X   name_index = 0;
X   nameMarked = INVALID;
X
X   while (changing)
X   {
X      XNextEvent (mainDisplay, &input);
X      if (input.type == Expose)
X      {
X         if (input.xany.window == nameBaseWin)
X            RedrawNameBaseWindow (TopStr, name, str_start, graph_start,
X                  button_start, w, h);
X         else if (input.xany.window == nameScrollWin)
X            RedrawNameScrollWin ();
X         else if (input.xany.window == nameDspWin)
X            RedrawDspWindow ();
X
X         continue;
X      }
X      else if (input.type == KeyPress)
X      {
X         key_ev = &(input.xkey);
X         XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
X
X         if ((buf[0]=='\r' && (key_sym & 0xff)=='\r') ||
X             (buf[0]=='\n' && (key_sym & 0xff)=='\n'))
X         {
X            changing = FALSE;
X            index = nameMarked;
X            button_selected = BUTTON_OK;
X         }
X         else if (buf[0]=='\033' && (key_sym & 0xff)=='\033')
X         {
X            changing = FALSE;
X            index = INVALID;
X            button_selected = 1;
X         }
X         else if (buf[0] == '\b' || buf[0] == '\177')
X         {
X            if (name_index != 0)
X            {
X               name[--name_index] = '\0';
X               for (i = 0; i < nameEntries; i++)
X                  if (strncmp (nameDspPtr[i], name, name_index) == 0)
X                     break;
X
X               if (i < nameEntries)
X               {
X                  if (i < nameFirst)
X                     nameFirst = i;
X                  else if (i >= nameFirst+ITEM_DSPED)
X                  {
X                     if (i < nameEntries-ITEM_DSPED)
X                        nameFirst = i;
X                     else
X                        nameFirst = nameEntries-ITEM_DSPED;
X                  }
X                  nameMarked = i;
X                  RedrawNamePath (name, graph_start,
X                        3*ROW_HEIGHT+defaultFontAsc+2);
X                  RedrawNameScrollWin ();
X                  RedrawDspWindow ();
X               }
X            }
X         }
X         else if (key_sym>='\040' && key_sym<='\177')
X         {
X            if (buf[0] == '$')
X            {
X               i = (nameEntries == 0) ? 0 : nameEntries-1;
X               strcpy (name, nameDspPtr[i]);
X            }
X            else
X            {
X               name[name_index++] = buf[0];
X               name[name_index] = '\0';
X               for (i = 0; i < nameEntries; i++)
X                  if (strncmp (nameDspPtr[i], name, name_index) == 0)
X                     break;
X            }
X
X            if (i < nameEntries)
X            {
X               if (i < nameFirst)
X                  nameFirst = i;
X               else if (i >= nameFirst+ITEM_DSPED)
X               {
X                  if (i < nameEntries-ITEM_DSPED)
X                     nameFirst = i;
X                  else
X                     nameFirst = nameEntries-ITEM_DSPED;
X               }
X               nameMarked = i;
X
X               RedrawNamePath (name, graph_start,
X                     3*ROW_HEIGHT+defaultFontAsc+2);
X               RedrawNameScrollWin ();
X               RedrawDspWindow ();
X            }
X            else
X               name[--name_index] = '\0';
X         }
X      }
X      else if (input.type == ButtonPress)
X      {
X         button_ev = &(input.xbutton);
X         if (button_ev->window == nameBaseWin)
X         {
X            if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[0]))
X            {
X               changing = FALSE;
X               index = nameMarked;
X               button_selected = BUTTON_OK;
X            }
X            else if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[1]))
X            {
X               changing = FALSE;
X               index = INVALID;
X               button_selected = 1;
X            }
X         }
X         else if (button_ev->window == nameScrollWin)
X            NameScrollHandler (button_ev);
X         else if (button_ev->window == nameDspWin)
X         {
X            if (NameDspHandler (button_ev) != INVALID)
X            {
X               changing = FALSE;
X               index = nameMarked;
X            }
X            else if (nameMarked != INVALID)
X            {
X               strcpy (name, nameDspPtr[nameMarked]);
X               name_index = strlen (name);
X               RedrawNamePath (name, graph_start,
X                     3*ROW_HEIGHT+defaultFontAsc+2);
X            }
X         }
X      }
X   }
X
X   DisplayButton (nameBaseWin, buttonStr[button_selected], 8,
X         &buttonBBox[button_selected], BUTTON_INVERT);
X
X   XDestroyWindow (mainDisplay, nameBaseWin);
X   XSync (mainDisplay, FALSE);
X   while (XCheckMaskEvent (mainDisplay, ExposureMask, &input)) ;
X   return (index);
X}
X
Xint SelectFileName (MsgStr, SelStr)
X   char	* MsgStr, * SelStr;
X{
X   int		index = INVALID, saved_num_dir_entries, just_set_dir;
X   DspList	* dsp_ptr;
X   char		saved_cur_dir[MAXPATHLENGTH];
X
X   strcpy (saved_cur_dir, curDir);
X   saved_num_dir_entries = numDirEntries;
X   if ((index = DirNames (MsgStr, "obj", SelStr, &just_set_dir)) == INVALID)
X   {
X      if (just_set_dir)
X      {
X         strcpy (curDir, SelStr);
X         BuildDirList ();
X         if (strcmp (saved_cur_dir, curDir) != 0 && DirInSymPath ("."))
X            UpdateSymInfo ();
X         RedrawTitleWindow ();
X         Msg ("");
X      }
X      else
X      {
X         numDirEntries = saved_num_dir_entries;
X         dsp_ptr = topOfDirLinkList;
X         for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr);
X         topOfDirLinkList = NULL;
X      }
X      *SelStr = '\0';
X      return (INVALID);
X   }
X   BuildDirList ();
X   Msg ("");
X   return (index);
X}
X
Xint SelectFileNameToImport (MsgStr, ExtStr, SelStr)
X   char	* MsgStr, * ExtStr, * SelStr;
X{
X   int		index = INVALID, saved_num_dir_entries, just_set_dir;
X   DspList	* dsp_ptr;
X   char		msg[MAXPATHLENGTH];
X
X   saved_num_dir_entries = numDirEntries;
X   if ((index = DirNames (MsgStr, ExtStr, SelStr, &just_set_dir)) == INVALID)
X   {
X      if (just_set_dir)
X      {
X         strcpy (curImportDir, SelStr);
X         sprintf (msg, "Changing importing directory to %s.", curImportDir);
X      }
X      *SelStr = '\0';
X   }
X   else
X      Msg ("");
X
X   numDirEntries = saved_num_dir_entries;
X   dsp_ptr = topOfDirLinkList;
X   for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr);
X   topOfDirLinkList = NULL;
X
X   return (index);
X}
X
Xint SelectSymbolName (SelSymName, PathName)
X   char	* SelSymName, * PathName;
X{
X   register int	index = INVALID;
X   char		s[MAXPATHLENGTH], msg[MAXSTRING];
X
X   sprintf (s,
X         "Generating a list of symbol names in '%s' domain, please wait ...",
X         curDomainName);
X   Msg (s);
X
X   nameEntries = numSymbols;
X   nameDspPtr = MakeNameDspItemArray (nameEntries, symbolList);
X   nameFirst = 0;
X   nameMarked = 0;
X
X   sprintf (msg, "Please select a symbol to INSTANTIATE in the '%s' domain ...",
X         curDomainName);
X   if ((index = ChooseAName (msg, SelSymName)) == INVALID)
X   {
X      *SelSymName = '\0';
X      *PathName = '\0';
X   }
X   else
X   {
X      strcpy (SelSymName, nameDspPtr[index]);
X      strcpy (PathName, symbolList[index].pathstr);
X   }
X   if (nameDspPtr != NULL)
X   {
X      cfree (*nameDspPtr);
X      cfree (nameDspPtr);
X   }
X
X   Msg ("");
X   return (index);
X}
X
Xint GetSymbolPath (SymName, PathName)
X   char	* SymName, * PathName;
X{
X   register int	i;
X
X   for (i = 0; i < numSymbols; i++)
X      if (strcmp (SymName, symbolList[i].itemstr) == 0)
X      {
X         strcpy (PathName, symbolList[i].pathstr);
X         return (TRUE);
X      }
X   return (FALSE);
X}
X
Xint NameInCurDir (FileName)
X   char	* FileName;
X{
X   register int	i;
X
X   for (i = 0; i < numDirEntries; i++)
X      if (dirList[i].directory && strcmp (FileName, dirList[i].itemstr) == 0)
X         return (TRUE);
X
X   return (FALSE);
X}
X
Xint DirInSymPath (DirName)
X   char	* DirName;
X{
X   register int	i;
X
X   for (i = 0; i < symPathNumEntries; i++)
X      if (strcmp (DirName, symPath[i]) == 0)
X         return (TRUE);
X
X   return (FALSE);
X}
X
Xstatic
XDspList * DomainListing (Entries)
X   int	* Entries;
X{
X   register int	i;
X   char		s[MAXSTRING], * c_ptr;
X   DspList	* dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1;
X
X   if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "MaxDomains")) == NULL)
X      return (NULL);
X
X   *Entries = atoi (c_ptr);
X
X   head_ptr = tail_ptr = NULL;
X   for (i = 0; i < *Entries; i++)
X   {
X      sprintf (s, "Domain%1d", i);
X      if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, s)) == NULL)
X      {
X         for ( ; head_ptr != NULL; head_ptr = head_ptr->next) cfree (head_ptr);
X         return (NULL);
X      }
X
X      dsp_ptr = (DspList *) calloc (1, sizeof(DspList));
X      strcpy (dsp_ptr->itemstr, c_ptr);
X      if (head_ptr == NULL)
X         head_ptr = tail_ptr = dsp_ptr;
X      else
X      {
X         p1 = NULL;
X         for (p = head_ptr; p != NULL; p = p->next)
X            if (LargerStr (dsp_ptr->itemstr, p->itemstr))
X               p1 = p;
X            else
X               break;
X
X         dsp_ptr->next = p;
X         if (p == NULL)
X         {  /* dsp_ptr has the largest element */
X            tail_ptr->next = dsp_ptr;
X            tail_ptr = dsp_ptr;
X         }
X         else if (p1 == NULL)
X            head_ptr = dsp_ptr;
X         else
X            p1->next = dsp_ptr;
X      }
X   }
X   return (head_ptr);
X}
X
Xint SelectDomain (SelStr)
X   char	* SelStr;
X{
X   int		index;
X   char		s[MAXPATHLENGTH];
X   DspList	* dsp_ptr;
X
X   Msg ("Generating list of domain names, please wait ...");
X
X   if ((dsp_ptr = DomainListing (&nameEntries)) == NULL)
X   {
X      Msg ("No domain names found.");
X      *SelStr = '\0';
X      return (INVALID);
X   }
X
X   nameDspPtr = MakeNameDspItemArray (nameEntries, dsp_ptr);
X   nameFirst = 0;
X   nameMarked = 0;
X
X   if ((index = ChooseAName ("Please select a new DOMAIN ...", "")) == INVALID)
X      *SelStr = '\0';
X   else
X      strcpy (SelStr, nameDspPtr[index]);
X
X   for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr);
X   if (nameDspPtr != NULL)
X   {
X      cfree (*nameDspPtr);
X      cfree (nameDspPtr);
X   }
X
X   s[0] = '\0';
X   Msg (s);
X
X   return (index);
X}
X
Xvoid SetCurDir (FileName)
X   char	* FileName;
X{
X   register int	i;
X   char		file_name[MAXPATHLENGTH];
X
X   strcpy (file_name, FileName);
X
X   for (i = strlen(file_name)-1; i>=0 && file_name[i]!='/'; i--) ;
X
X   if (i < 0)
X   {
X      TwoLineMsg ("Error:  No '/' found in SetCurDir ().",
X                  "        curDir set to '.'.");
X      strcpy (curDir, ".");
X      strcpy (curFileName, FileName);
X   }
X   else
X   {
X      strcpy (curFileName, &file_name[i+1]);
X      file_name[i] = '\0';
X      strcpy (curDir, file_name);
X   }
X}
END_OF_FILE
if test 46854 -ne `wc -c <'names.c'`; then
    echo shar: \"'names.c'\" unpacked with wrong size!
fi
# end of 'names.c'
fi
if test -f 'obj.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'obj.c'\"
else
echo shar: Extracting \"'obj.c'\" \(7861 characters\)
sed "s/^X//" >'obj.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/obj.c,v 2.0 91/03/05 12:47:46 william Exp $";
X#endif
X
X#include <X11/Xlib.h>
X#include "const.h"
X#include "types.h"
X
X#include "arc.e"
X#include "attr.e"
X#include "box.e"
X#include "group.e"
X#include "oval.e"
X#include "poly.e"
X#include "polygon.e"
X#include "rcbox.e"
X#include "setup.e"
X#include "spline.e"
X#include "text.e"
X#include "xbitmap.e"
X
Xstruct ObjRec	* topObj = NULL, * botObj = NULL;
X
Xvoid AddObj (PrevPtr, NextPtr, ObjPtr)
X   struct ObjRec	* PrevPtr, * NextPtr, * ObjPtr;
X   /* add ObjPtr between PrevPtr and NextPtr */
X{
X   ObjPtr->prev = PrevPtr;
X   ObjPtr->next = NextPtr;
X
X   if (PrevPtr == NULL)
X      topObj = ObjPtr;
X   else
X      PrevPtr->next = ObjPtr;
X
X   if (NextPtr == NULL)
X      botObj = ObjPtr;
X   else
X      NextPtr->prev = ObjPtr;
X}
X
Xvoid UnlinkObj (ObjPtr)
X   struct ObjRec	*ObjPtr;
X{
X   if (topObj == ObjPtr)
X      topObj = ObjPtr->next;
X   else
X      ObjPtr->prev->next = ObjPtr->next;
X
X   if (botObj == ObjPtr)
X      botObj = ObjPtr->prev;
X   else
X      ObjPtr->next->prev = ObjPtr->prev;
X}
X
Xvoid FreeObj (ObjPtr)
X   register struct ObjRec	* ObjPtr;
X{
X   switch (ObjPtr->type)
X   {
X      case OBJ_POLY: DelAllAttrs(ObjPtr->fattr); FreePolyObj (ObjPtr); break;
X      case OBJ_BOX: DelAllAttrs(ObjPtr->fattr); FreeBoxObj (ObjPtr); break;
X      case OBJ_OVAL: DelAllAttrs(ObjPtr->fattr); FreeOvalObj (ObjPtr); break;
X      case OBJ_TEXT: FreeTextObj (ObjPtr); break;
X      case OBJ_POLYGON: DelAllAttrs(ObjPtr->fattr); FreePolygonObj (ObjPtr);
X         break;
X      case OBJ_ARC: DelAllAttrs(ObjPtr->fattr); FreeArcObj (ObjPtr); break;
X      case OBJ_RCBOX: DelAllAttrs(ObjPtr->fattr); FreeRCBoxObj (ObjPtr); break;
X      case OBJ_XBM: DelAllAttrs(ObjPtr->fattr); FreeXBmObj (ObjPtr); break;
X      case OBJ_SYM:
X      case OBJ_ICON:
X      case OBJ_GROUP: DelAllAttrs(ObjPtr->fattr); FreeGroupObj (ObjPtr); break;
X   }
X}
X
Xvoid DelObj (ObjPtr)
X   struct ObjRec	*ObjPtr;
X{
X   if (topObj == ObjPtr)
X      topObj = ObjPtr->next;
X   else
X      ObjPtr->prev->next = ObjPtr->next;
X
X   if (botObj == ObjPtr)
X      botObj = ObjPtr->prev;
X   else
X      ObjPtr->next->prev = ObjPtr->prev;
X
X   FreeObj (ObjPtr);
X}
X
Xvoid DelAllObj ()
X{
X   register struct ObjRec	* ptr;
X
X   if (topObj == NULL) return;
X
X   for (ptr = topObj; ptr != NULL; ptr = ptr->next)
X      FreeObj (ptr);
X
X   topObj = botObj = NULL;
X}
X
Xvoid AdjObjBBox (ObjPtr)
X   struct ObjRec        * ObjPtr;
X{
X   register int			w = 0;
X   register struct ObjRec	* obj_ptr;
X   register struct AttrRec	* attr_ptr;
X   int				ltx, lty, rbx, rby;
X   int				oltx, olty, orbx, orby;
X
X   switch (ObjPtr->type)
X   {
X      case OBJ_POLY: w = arrowHeadH[ObjPtr->detail.p->width]; break;
X      case OBJ_POLYGON: w = widthOfLine[ObjPtr->detail.g->width]; break;
X      case OBJ_BOX: w = widthOfLine[ObjPtr->detail.b->width]; break;
X      case OBJ_OVAL: w = widthOfLine[ObjPtr->detail.o->width]; break;
X      case OBJ_ARC: w = widthOfLine[ObjPtr->detail.a->width]; break;
X      case OBJ_RCBOX: w = widthOfLine[ObjPtr->detail.rcb->width]; break;
X      case OBJ_XBM: break;
X
X      case OBJ_SYM:
X      case OBJ_GROUP:
X      case OBJ_ICON:
X         obj_ptr = ObjPtr->detail.r->last;
X         ltx = obj_ptr->bbox.ltx; lty = obj_ptr->bbox.lty;
X         rbx = obj_ptr->bbox.rbx; rby = obj_ptr->bbox.rby;
X         oltx = obj_ptr->obbox.ltx; olty = obj_ptr->obbox.lty;
X         orbx = obj_ptr->obbox.rbx; orby = obj_ptr->obbox.rby;
X         for (obj_ptr = obj_ptr->prev; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
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            if (obj_ptr->obbox.ltx < oltx) oltx = obj_ptr->obbox.ltx;
X            if (obj_ptr->obbox.lty < olty) olty = obj_ptr->obbox.lty;
X            if (obj_ptr->obbox.rbx > orbx) orbx = obj_ptr->obbox.rbx;
X            if (obj_ptr->obbox.rby > orby) orby = obj_ptr->obbox.rby;
X         }
X         ObjPtr->bbox.ltx = ltx; ObjPtr->bbox.lty = lty;
X         ObjPtr->bbox.rbx = rbx; ObjPtr->bbox.rby = rby;
X         ObjPtr->obbox.ltx = oltx; ObjPtr->obbox.lty = olty;
X         ObjPtr->obbox.rbx = orbx; ObjPtr->obbox.rby = orby;
X         break;
X   }
X   switch (ObjPtr->type)
X   {
X      case OBJ_POLY:
X      case OBJ_POLYGON:
X      case OBJ_BOX:
X      case OBJ_OVAL:
X      case OBJ_ARC:
X      case OBJ_RCBOX:
X      case OBJ_XBM:
X         ObjPtr->bbox.ltx = ObjPtr->obbox.ltx - w;
X         ObjPtr->bbox.lty = ObjPtr->obbox.lty - w;
X         ObjPtr->bbox.rbx = ObjPtr->obbox.rbx + w;
X         ObjPtr->bbox.rby = ObjPtr->obbox.rby + w;
X         break;
X      case OBJ_TEXT:
X         ObjPtr->bbox.ltx = ObjPtr->obbox.ltx - 2;
X         ObjPtr->bbox.lty = ObjPtr->obbox.lty - 2;
X         ObjPtr->bbox.rbx = ObjPtr->obbox.rbx + 2;
X         ObjPtr->bbox.rby = ObjPtr->obbox.rby + 2;
X         break;
X   }
X
X   attr_ptr = ObjPtr->fattr;
X
X   ltx = ObjPtr->bbox.ltx;
X   lty = ObjPtr->bbox.lty;
X   rbx = ObjPtr->bbox.rbx;
X   rby = ObjPtr->bbox.rby;
X   for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
X   {
X      if (attr_ptr->shown)
X      {
X         if (attr_ptr->obj->bbox.ltx < ltx) ltx = attr_ptr->obj->bbox.ltx;
X         if (attr_ptr->obj->bbox.lty < lty) lty = attr_ptr->obj->bbox.lty;
X         if (attr_ptr->obj->bbox.rbx > rbx) rbx = attr_ptr->obj->bbox.rbx;
X         if (attr_ptr->obj->bbox.rby > rby) rby = attr_ptr->obj->bbox.rby;
X      }
X   }
X   ObjPtr->bbox.ltx = ltx;
X   ObjPtr->bbox.lty = lty;
X   ObjPtr->bbox.rbx = rbx;
X   ObjPtr->bbox.rby = rby;
X
X   if (ObjPtr->type == OBJ_SYM)
X   {
X      if (ObjPtr->obbox.ltx-QUARTER_INCH < ObjPtr->bbox.ltx)
X         ObjPtr->bbox.ltx = ObjPtr->obbox.ltx - QUARTER_INCH;
X      if (ObjPtr->obbox.lty-QUARTER_INCH < ObjPtr->bbox.lty)
X         ObjPtr->bbox.lty = ObjPtr->obbox.lty - QUARTER_INCH;
X      if (ObjPtr->obbox.rbx+QUARTER_INCH > ObjPtr->bbox.rbx)
X         ObjPtr->bbox.rbx = ObjPtr->obbox.rbx + QUARTER_INCH;
X      if (ObjPtr->obbox.rby+QUARTER_INCH > ObjPtr->bbox.rby)
X         ObjPtr->bbox.rby = ObjPtr->obbox.rby + QUARTER_INCH;
X   }
X}
X
Xstatic
Xvoid AdjObjSplineVs (ObjPtr)
X   struct ObjRec	* ObjPtr;
X{
X   register struct ObjRec	* ptr;
X
X   switch (ObjPtr->type)
X   {
X      case OBJ_POLY:
X         if (ObjPtr->detail.p->curved)
X         {
X            cfree (ObjPtr->detail.p->svlist);
X            ObjPtr->detail.p->svlist = MakeSplinePolyVertex (
X                  &(ObjPtr->detail.p->sn), drawOrigX, drawOrigY,
X                  ObjPtr->detail.p->n, ObjPtr->detail.p->vlist);
X         }
X         break;
X      case OBJ_POLYGON:
X         if (ObjPtr->detail.g->curved)
X         {
X            cfree (ObjPtr->detail.g->svlist);
X            ObjPtr->detail.g->svlist = MakeSplinePolygonVertex (
X                  &(ObjPtr->detail.g->sn), drawOrigX, drawOrigY,
X                  ObjPtr->detail.g->n, ObjPtr->detail.g->vlist);
X         }
X         break;
X      case OBJ_SYM:
X      case OBJ_ICON:
X      case OBJ_GROUP:
X         for (ptr = ObjPtr->detail.r->first; ptr != NULL; ptr = ptr->next)
X            AdjObjSplineVs (ptr);
X         break;
X   }
X}
X
Xvoid AdjSplineVs ()
X{
X   register struct ObjRec	* obj_ptr, * ptr;
X
X   if (topObj == NULL) return;
X
X   for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X      switch (obj_ptr->type)
X      {
X         case OBJ_POLY:
X         case OBJ_POLYGON:
X            AdjObjSplineVs (obj_ptr);
X            break;
X         case OBJ_SYM:
X         case OBJ_ICON:
X         case OBJ_GROUP:
X            for (ptr = obj_ptr->detail.r->first; ptr != NULL; ptr = ptr->next)
X               AdjObjSplineVs (ptr);
X            break;
X      }
X}
END_OF_FILE
if test 7861 -ne `wc -c <'obj.c'`; then
    echo shar: \"'obj.c'\" unpacked with wrong size!
fi
# end of 'obj.c'
fi
if test -f 'oval.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'oval.c'\"
else
echo shar: Extracting \"'oval.c'\" \(12774 characters\)
sed "s/^X//" >'oval.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/oval.c,v 2.0 91/03/05 12:47:48 william Exp $";
X#endif
X
X#include <math.h>
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include "const.h"
X#include "types.h"
X
X#include "color.e"
X#include "cursor.e"
X#include "file.e"
X#include "grid.e"
X#include "obj.e"
X#include "pattern.e"
X#include "poly.e"
X#include "raster.e"
X#include "ruler.e"
X#include "select.e"
X#include "setup.e"
X
Xint	ovalDrawn = FALSE;
X
Xvoid MyOval (window, gc, bbox)
X   Window	window;
X   GC		gc;
X   struct BBRec	bbox;
X{
X   register int		ltx, lty, w, h;
X
X   if (bbox.ltx > bbox.rbx)
X   {
X      ltx = bbox.rbx; w = bbox.ltx - ltx;
X   }
X   else
X   {
X      ltx = bbox.ltx; w = bbox.rbx - ltx;
X   }
X
X   if (bbox.lty > bbox.rby)
X   {
X      lty = bbox.rby; h = bbox.lty - lty;
X   }
X   else
X   {
X      lty = bbox.lty; h = bbox.rby - lty;
X   }
X
X   XDrawArc (mainDisplay, window, gc, ltx, lty, w, h, 0, 360*64);
X}
X 
Xvoid DumpOvalObj (FP, ObjPtr)
X   FILE			* FP;
X   struct ObjRec	* ObjPtr;
X{
X   int	ltx, lty, rbx, rby, xc, yc, a, b, i;
X   int	fill, width, pen, dash, color_index;
X
X   ltx = ObjPtr->obbox.ltx; lty = ObjPtr->obbox.lty;
X   rbx = ObjPtr->obbox.rbx; rby = ObjPtr->obbox.rby;
X   a = (rbx - ltx) / 2; xc = ltx + a;
X   b = (rby - lty) / 2; yc = lty + b;
X
X   fill = ObjPtr->detail.o->fill;
X   width = ObjPtr->detail.o->width;
X   pen = ObjPtr->detail.o->pen;
X   dash = ObjPtr->detail.o->dash;
X
X   if (fill == NONEPAT && pen == NONEPAT) return;
X
X   color_index = ObjPtr->color;
X   if (colorDump)
X      fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n",
X            ((float)tgifColors[color_index].red/maxRGB),
X            ((float)tgifColors[color_index].green/maxRGB),
X            ((float)tgifColors[color_index].blue/maxRGB));
X
X   switch (fill)
X   {
X      case NONEPAT: break;
X      case SOLIDPAT:
X         /* solid black oval */
X         fprintf (FP, "newpath %1d %1d %1d %1d ellipse fill\n", xc, yc, a, b);
X         break;
X      case BACKPAT:
X         /* solid white oval */
X         fprintf (FP, "newpath %1d %1d %1d %1d ellipse\n", xc, yc, a, b);
X         fprintf (FP, "closepath 1 setgray fill\n");
X         if (colorDump)
X            fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n",
X                  ((float)tgifColors[color_index].red/maxRGB),
X                  ((float)tgifColors[color_index].green/maxRGB),
X                  ((float)tgifColors[color_index].blue/maxRGB));
X         else
X            fprintf (FP, "0 setgray\n");
X         break;
X      default:
X         /* patterned */
X         fprintf (FP, "gsave\n");
X         if (colorDump)
X         {
X            fprintf (FP, "   newpath %1d %1d %1d %1d ellipse\n", xc, yc, a, b);
X            fprintf (FP, "   closepath eoclip\n");
X            DumpPatFill (FP, fill, 8, ObjPtr->bbox, "   ");
X         }
X         else
X         {
X            fprintf (FP, "   pat%1d 8 1 0 72 300 32 div div setpattern\n",fill);
X            fprintf (FP, "   newpath %1d %1d %1d %1d ellipse fill\n",
X                  xc, yc, a, b);
X         }
X         fprintf (FP, "grestore\n");
X         break;
X   }
X
X   fprintf (FP, "%1d setlinewidth\n", widthOfLine[width]);
X   if (dash != 0)
X   {
X      fprintf (FP, "[");
X      for (i = 0; i < dashListLength[dash]-1; i++)
X         fprintf (FP, "%1d ", (int)(dashList[dash][i]));
X      fprintf (FP, "%1d] 0 setdash\n",
X            (int)(dashList[dash][dashListLength[dash]-1]));
X   }
X
X   switch (pen)
X   {
X      case NONEPAT: break;
X      case SOLIDPAT:
X         fprintf (FP, "newpath %1d %1d %1d %1d ellipse stroke\n", xc, yc, a, b);
X         break;
X      case BACKPAT:
X         fprintf (FP, "newpath %1d %1d %1d %1d ellipse\n", xc, yc, a, b);
X         fprintf (FP, "closepath 1 setgray stroke 0 setgray\n");
X         break;
X      default:
X         fprintf (FP, "gsave\n");
X         if (colorDump)
X         {
X            fprintf (FP, "   newpath %1d %1d %1d %1d ellipse\n", xc, yc, a, b);
X            fprintf (FP, "   strokepath clip\n");
X            DumpPatFill (FP, pen, 8, ObjPtr->bbox, "   ");
X         }
X         else
X         {
X            fprintf (FP, "   pat%1d 8 1 0 72 300 32 div div setpattern\n", pen);
X            fprintf (FP, "   newpath %1d %1d %1d %1d ellipse stroke\n",
X                  xc, yc, a, b);
X         }
X         fprintf (FP, "grestore\n");
X         break;
X   }
X   if (dash != 0) fprintf (FP, "[] 0 setdash\n");
X   fprintf (FP, "1 setlinewidth\n\n");
X}
X 
Xvoid DrawOvalObj (window, XOff, YOff, ObjPtr)
X   Window		window;
X   int			XOff, YOff;
X   struct ObjRec	* ObjPtr;
X{
X   int			fill, width, pen, dash, pixel, real_x_off, real_y_off;
X   struct BBRec		bbox;
X   XGCValues		values;
X
X   real_x_off = (XOff >> zoomScale) << zoomScale;
X   real_y_off = (YOff >> zoomScale) << zoomScale;
X   bbox.ltx = (ObjPtr->obbox.ltx - real_x_off) >> zoomScale;
X   bbox.lty = (ObjPtr->obbox.lty - real_y_off) >> zoomScale;
X   bbox.rbx = (ObjPtr->obbox.rbx - real_x_off) >> zoomScale;
X   bbox.rby = (ObjPtr->obbox.rby - real_y_off) >> zoomScale;
X
X   fill = ObjPtr->detail.o->fill;
X   width = ObjPtr->detail.o->width;
X   pen = ObjPtr->detail.o->pen;
X   dash = ObjPtr->detail.o->dash;
X   pixel = colorPixels[ObjPtr->color];
X
X   if (fill != 0)
X   {
X      values.foreground = (fill == 2) ? myBgPixel : pixel;
X      values.function = GXcopy;
X      values.fill_style = FillOpaqueStippled;
X      values.stipple = patPixmap[fill];
X      XChangeGC (mainDisplay, drawGC,
X            GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
X      XFillArc (mainDisplay, window, drawGC, bbox.ltx, bbox.lty,
X            bbox.rbx-bbox.ltx, bbox.rby-bbox.lty, 0, 360*64);
X   }
X   if (pen != 0)
X   {
X      values.foreground = (pen == 2) ? myBgPixel : pixel;
X      values.function = GXcopy;
X      values.fill_style = FillOpaqueStippled;
X      values.stipple = patPixmap[pen];
X      values.line_width = widthOfLine[width] >> zoomScale;
X      if (dash != 0)
X      {
X         XSetDashes (mainDisplay, drawGC, 0, dashList[dash],
X               dashListLength[dash]);
X         values.line_style = LineOnOffDash;
X      }
X      else
X         values.line_style = LineSolid;
X      XChangeGC (mainDisplay, drawGC,
X            GCForeground | GCFunction | GCFillStyle | GCStipple | GCLineWidth |
X            GCLineStyle, &values);
X      XDrawArc (mainDisplay, window, drawGC, bbox.ltx, bbox.lty,
X            bbox.rbx-bbox.ltx, bbox.rby-bbox.lty, 0, 360*64);
X   }
X}
X
Xstatic
Xvoid CreateOvalObj (BBox)
X   struct BBRec	BBox;
X{
X   struct OvalRec	* oval_ptr;
X   struct ObjRec	* obj_ptr;
X   int			w;
X
X   oval_ptr = (struct OvalRec *) calloc (1, sizeof(struct OvalRec));
X   oval_ptr->fill = objFill;
X   oval_ptr->width = lineWidth;
X   oval_ptr->pen = penPat;
X   oval_ptr->dash = curDash;
X
X   obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X
X   obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x =
X         (BBox.ltx << zoomScale) + drawOrigX;
X   obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y =
X         (BBox.lty << zoomScale) + drawOrigY;
X   obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = (BBox.rbx << zoomScale) + drawOrigX;
X   obj_ptr->bbox.rby = obj_ptr->obbox.rby = (BBox.rby << zoomScale) + drawOrigY;
X   w = widthOfLine[lineWidth];
X   obj_ptr->bbox.ltx -= w;
X   obj_ptr->bbox.lty -= w;
X   obj_ptr->bbox.rbx += w;
X   obj_ptr->bbox.rby += w;
X   obj_ptr->type = OBJ_OVAL;
X   obj_ptr->color = colorIndex;
X   obj_ptr->id = objId++;
X   obj_ptr->dirty = FALSE;
X   obj_ptr->detail.o = oval_ptr;
X   obj_ptr->fattr = obj_ptr->lattr = NULL;
X   AddObj (NULL, topObj, obj_ptr);
X}
X 
Xstatic
Xvoid ContinueOval (OrigX, OrigY)
X   int	OrigX, OrigY;
X{
X   int 		end_x, end_y, grid_x, grid_y;
X   int 		done = FALSE;
X   int		pixel, xor_pixel;
X   struct BBRec	bbox;
X   XGCValues	values;
X   XEvent	input;
X   XMotionEvent	* motion_ev;
X
X   bbox.ltx = bbox.rbx = OrigX;
X   bbox.lty = bbox.rby = OrigY;
X
X   pixel = colorPixels[colorIndex];
X   xor_pixel = xorColorPixels[colorIndex];
X
X   values.foreground = xor_pixel;
X   values.function = GXxor;
X   values.fill_style = FillSolid;
X   values.line_width = 0;
X   values.line_style = LineSolid;
X   XChangeGC (mainDisplay, drawGC,
X         GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCLineStyle,
X         &values);
X
X   grid_x = end_x = OrigX;
X   grid_y = end_y = OrigY; 
X   XGrabPointer (mainDisplay, drawWindow, FALSE,
X         PointerMotionMask | ButtonReleaseMask,
X         GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
X   
X   while (!done)
X   {
X      XNextEvent (mainDisplay, &input);
X      if (input.type == ButtonRelease)
X      {
X         XUngrabPointer (mainDisplay, CurrentTime);
X         MyOval (drawWindow, drawGC, bbox);
X         done = TRUE;
X      }
X      else if (input.type == MotionNotify)
X      {
X         motion_ev = &(input.xmotion);
X         end_x = motion_ev->x;
X         end_y = motion_ev->y;
X         GridXY (end_x, end_y, &grid_x, &grid_y);
X         if (grid_x != bbox.rbx || grid_y != bbox.rby)
X         {
X            MyOval (drawWindow, drawGC, bbox);
X            bbox.rbx = grid_x;
X            bbox.rby = grid_y;
X            MyOval (drawWindow, drawGC, bbox);
X         }
X         MarkRulers (grid_x, grid_y);
X      }
X   }
X   if (OrigX != grid_x && OrigY != grid_y)
X   {
X      if (bbox.ltx > bbox.rbx)
X      {
X         end_x = bbox.ltx; bbox.ltx = bbox.rbx; bbox.rbx = end_x;
X      }
X      if (bbox.lty > bbox.rby)
X      {
X         end_y = bbox.lty; bbox.lty = bbox.rby; bbox.rby = end_y;
X      }
X      CreateOvalObj (bbox);
X      DrawOvalObj (drawWindow, drawOrigX, drawOrigY, topObj);
X      ovalDrawn = TRUE;
X      SetFileModified (TRUE);
X   }
X}
X
Xvoid DrawOval (input)
X   XEvent	* input;
X{
X   XButtonEvent	* button_ev;
X   int		mouse_x, mouse_y, grid_x, grid_y;
X
X   if (input->type != ButtonPress) return;
X
X   button_ev = &(input->xbutton);
X   if (button_ev->button == Button1)
X   {
X      mouse_x = button_ev->x;
X      mouse_y = button_ev->y;
X      GridXY (mouse_x, mouse_y, &grid_x, &grid_y);
X      ContinueOval (grid_x, grid_y);
X   }
X}
X
Xvoid SaveOvalObj (FP, ObjPtr)
X   FILE			* FP;
X   struct ObjRec	* ObjPtr;
X{
X   fprintf (FP, "oval('%s',", colorMenuItems[ObjPtr->color]);
X   fprintf (FP, "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,", ObjPtr->obbox.ltx,
X         ObjPtr->obbox.lty, ObjPtr->obbox.rbx, ObjPtr->obbox.rby,
X         ObjPtr->detail.o->fill, ObjPtr->detail.o->width,
X         ObjPtr->detail.o->pen, ObjPtr->id, ObjPtr->detail.o->dash);
X   SaveAttrs (FP, ObjPtr->lattr);
X   fprintf (FP, ")");
X}
X
Xvoid ReadOvalObj (Inbuf, ObjPtr)
X   char			* Inbuf;
X   struct ObjRec	* * ObjPtr;
X{
X   struct OvalRec	* oval_ptr;
X   char			color_str[20], * s;
X   int			ltx, lty, rbx, rby, fill, width, pen, dash, w;
X
X   * ObjPtr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X   s = FindChar ('(', Inbuf);
X   s = ParseStr (s, ',', color_str);
X   oval_ptr = (struct OvalRec *) calloc (1, sizeof(struct OvalRec));
X
X   if (fileVersion <= 5)
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d",
X            &ltx, &lty, &rbx, &rby, &fill, &width, &pen);
X      switch (width)
X      {
X         case 1: width = 3; break;
X         case 2: width = 6; break;
X      }
X      (*ObjPtr)->id = objId++;
X      dash = 0;
X   }
X   else if (fileVersion <= 7)
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d",
X            &ltx, &lty, &rbx, &rby, &fill, &width, &pen);
X      (*ObjPtr)->id = objId++;
X      dash = 0;
X   }
X   else if (fileVersion <= 8)
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d",
X            &ltx, &lty, &rbx, &rby, &fill, &width, &pen, &((*ObjPtr)->id));
X      if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1;
X      dash = 0;
X   }
X   else
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d",
X            &ltx, &lty, &rbx, &rby, &fill, &width, &pen, &((*ObjPtr)->id),
X            &dash);
X      if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1;
X   }
X
X   oval_ptr->fill = fill;
X   oval_ptr->width = width;
X   oval_ptr->pen = pen;
X   oval_ptr->dash = dash;
X   (*ObjPtr)->x = ltx;
X   (*ObjPtr)->y = lty;
X   (*ObjPtr)->color = FindColorIndex (color_str);
X   (*ObjPtr)->dirty = FALSE;
X   (*ObjPtr)->type = OBJ_OVAL;
X   (*ObjPtr)->obbox.ltx = ltx;
X   (*ObjPtr)->obbox.lty = lty;
X   (*ObjPtr)->obbox.rbx = rbx;
X   (*ObjPtr)->obbox.rby = rby;
X   if (width == 0)
X   {
X      (*ObjPtr)->bbox.ltx = ltx;
X      (*ObjPtr)->bbox.lty = lty;
X      (*ObjPtr)->bbox.rbx = rbx;
X      (*ObjPtr)->bbox.rby = rby;
X   }
X   else
X   {
X      w = widthOfLine[width];
X      (*ObjPtr)->bbox.ltx = ltx - w;
X      (*ObjPtr)->bbox.lty = lty - w;
X      (*ObjPtr)->bbox.rbx = rbx + w;
X      (*ObjPtr)->bbox.rby = rby + w;
X   }
X   (*ObjPtr)->detail.o = oval_ptr;
X}
X
Xvoid FreeOvalObj (ObjPtr)
X   struct ObjRec	* ObjPtr;
X{
X   cfree (ObjPtr->detail.o);
X   cfree (ObjPtr);
X}
END_OF_FILE
if test 12774 -ne `wc -c <'oval.c'`; then
    echo shar: \"'oval.c'\" unpacked with wrong size!
fi
# end of 'oval.c'
fi
echo shar: End of archive 8 \(of 23\).
cp /dev/null ark8isdone
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