X Desktop Manager

Edward J. Groenendaal eddyg at syma.sussex.ac.uk
Thu Apr 18 06:47:32 AEST 1991


---- Cut Here and unpack ----
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#	Packed Wed Apr 17 21:39:53 BST 1991 by tsuna!eddyg
#	from directory /tsuna/home/ug/cs88/eddyg/usr/xdtm
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
#	Run the following text with /bin/sh to create:
#	  code/appman.c
#	  code/buttons.c
#	  code/dialogs.c
#	  code/dirman.c
#	  code/display.c
#	  code/fileman.c
#	  code/info.c
#	  code/lexical.l
#	  code/listoption.c
#	  code/main.c
#	  code/map.c
#	  code/menus.c
#	  code/menus.h
#	  code/newfile.c
#	  code/parse.c
#	  code/parse.h
#	  code/parser.y
#	  code/patchlevel.h
#	  code/quit.c
#	  code/scroll_hack.c
#	  code/strstr.c
#	  code/xdtm.h
#	  code/README
#	  code/Imakefile
#	  code/Makefile
#	  code/help
#	  code/Xdtm
#	  icons/eddy/ccode.icon
#	  icons/eddy/core.icon
#	  icons/eddy/dotdot.icon
#	  icons/eddy/elisp.icon
#	  icons/eddy/elispc.icon
#	  icons/eddy/file.icon
#	  icons/eddy/folder.icon
#	  icons/eddy/hcode.icon
#	  icons/eddy/icon.icon
#	  icons/eddy/lcode.icon
#	  icons/eddy/lib.icon
#	  icons/eddy/make.icon
#	  icons/eddy/makefile.icon
#	  icons/eddy/manpage.icon
#	  icons/eddy/ocode.icon
#	  icons/eddy/prog.icon
#	  icons/eddy/text.icon
#	  icons/eddy/x.icon
#	  icons/eddy/xdtm.icon
#	  icons/eddy/ycode.icon
#	  icons/eddy/z.icon
#	  icons/alix/airballoon.icon
#	  icons/alix/alien.icon
#	  icons/alix/bat.icon
#	  icons/alix/candle.icon
#	  icons/alix/clock.icon
#	  icons/alix/cup.icon
#	  icons/alix/dragon.icon
#	  icons/alix/drawingA.icon
#	  icons/alix/drawingB.icon
#	  icons/alix/emacs.icon
#	  icons/alix/fish.icon
#	  icons/alix/flower.icon
#	  icons/alix/ghost.icon
#	  icons/alix/gun.icon
#	  icons/alix/hat.icon
#	  icons/alix/hedgehog.icon
#	  icons/alix/mermaid.icon
#	  icons/alix/monster.icon
#	  icons/alix/piccy.icon
#	  icons/alix/snail.icon
#	  icons/alix/wordc.icon
#	  xdtmrc
#	  code/bitmaps/Copy.Button
#	  code/bitmaps/Copy.Cursor
#	  code/bitmaps/Copy.Mask
#	  code/bitmaps/EmptyTick
#	  code/bitmaps/Grey.Mask
#	  code/bitmaps/Move.Button
#	  code/bitmaps/Move.Cursor
#	  code/bitmaps/Move.Mask
#	  code/bitmaps/Tick
#	  code/bitmaps/Trash.Button
#	  code/bitmaps/file.icon
#	  code/bitmaps/folder.icon
#	  code/Xedw/DefIcon.icon
#	  code/Xedw/Imakefile
#	  code/Xedw/Makefile
#	  code/Xedw/XedwForm.c
#	  code/Xedw/XedwForm.h
#	  code/Xedw/XedwFormP.h
#	  code/Xedw/XedwList.c
#	  code/Xedw/XedwList.h
#	  code/Xedw/XedwListP.h
#	  code/Xedw/XedwTree.c
#	  code/Xedw/XedwTree.h
#	  code/Xedw/XedwTreeP.h
#
if test -r s2_seq_.tmp
then echo "Must unpack archives in sequence!"
     next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
     exit 1; fi
echo "creating directories"
mkdir code
mkdir code/bitmaps
mkdir code/Xedw
mkdir icons
mkdir icons/eddy
mkdir icons/alix
echo "x - extracting code/appman.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > code/appman.c &&
X/*****************************************************************************
X ** File          : appman.c                                                **
X ** Purpose       : Application Manager                                     **
X ** Author        : Edward Groenendaal                                      **
X ** Date          : 19th Feb 1991                                           **
X ** Documentation : Xedw Design Folder                                      **
X ** Related Files : menus.c                                                 **
X *****************************************************************************/
X
X#include "xdtm.h"
X
X#include <X11/Xaw/MenuButton.h> /* Needed for selection menu */
X#include <X11/Xaw/SimpleMenu.h>
X#include <X11/Xaw/Viewport.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Label.h>
X#include <sys/types.h>		/* For opening and closing file descriptors */
X#include <sys/stat.h>		/* For opening and closing file descriptors */
X/* #include <fcntl.h>		For opening and closing file descriptors */
X#include <sys/file.h>		/* For access(2) */
X#include <string.h>
X#include "menus.h"		/* For the use of Trash, Copy, and Move */
X#include "parse.h"              /* For access to AppSelection */
X#include "Xedw/XedwList.h"
X#include "Xedw/XedwForm.h"
X
X/* Include button bitmaps */
X#include "bitmaps/Trash.Button"
X#include "bitmaps/Copy.Button"
X#include "bitmaps/Move.Button"
X
X/* Include Cursor bitmaps */
X#include "bitmaps/Copy.Cursor"
X#include "bitmaps/Copy.Mask"
X#include "bitmaps/Move.Cursor"
X#include "bitmaps/Move.Mask"
X
Xpublic  Mode     mode;
Xpublic  Boolean  buttonSensitive;
Xpublic  Widget   trashButton, copyButton, moveButton;
Xprivate XedwListReturnStruct *return_list;
Xpublic  Widget   appManager;
Xpublic  Widget   selectionMenu;
Xprivate Widget   appManagerView;
Xprivate Widget   appManagerButton;
Xprivate Widget   buttonForm;
Xprivate Cursor   copyCursor, moveCursor;
Xpublic  Cardinal appman_selection;
Xprivate String   srcdir, dstdir;
Xprivate String  *patharray;
Xprivate String   path;
Xprivate Cardinal pathsize; 
X
X#ifdef SYSV
Xextern char *strstr(char *, char *);
X#endif
X
X
Xvoid createAppManagerWidgets(Widget topForm)
X{
X  private void button_selected(Widget, Cardinal, caddr_t);
X  private void program_selected(Widget, caddr_t, caddr_t);
X  Arg arglist[8], *newlist;
X  Pixmap trash, copy, move;
X  Cardinal i, t;
X  XtTranslations appManTranslations;
X
X  static char defaultTranslations[] =
X    		"<Btn1Down>:    Set()\n\
X		 <Btn1Up>:      Unset()\n\
X	         <Btn1Up>(2):   Notify() Unset()";
X  
X  /* Application Manager Selector */
X
X  i = 0;
X  XtSetArg(arglist[i], XtNfromVert,         menuBar); i++;
X  XtSetArg(arglist[i], XtNrubberWidth,        False); i++;
X  XtSetArg(arglist[i], XtNrubberHeight,       False); i++;
X  XtSetArg(arglist[i], XtNmenuName, "selectionMenu"); i++;
X  newlist = XtMergeArgLists(arglist, i, chain_position, chain_size);
X  appManagerButton  =   XtCreateManagedWidget("appManagerButton",
X					      menuButtonWidgetClass,
X					      topForm,
X					      newlist, i + chain_size);
X  XtFree(newlist);
X
X
X  selectionMenu    =   XtCreatePopupShell("selectionMenu",
X					  simpleMenuWidgetClass,
X					  appManagerButton,
X					  NULL, 0);
X
X
X  /* Application Manager */
X  
X  i = 0;
X  XtSetArg(arglist[i], XtNfromVert,      appManagerButton);   i++;
X  XtSetArg(arglist[i], XtNforceBars,                 True);   i++;
X  XtSetArg(arglist[i], XtNallowVert,                 True);   i++;
X  XtSetArg(arglist[i], XtNrubberWidth,              False);   i++;
X  XtSetArg(arglist[i], XtNwidthLinked,   appManagerButton);   i++;
X  newlist = XtMergeArgLists(arglist, i, chain_position, chain_size);
X  appManagerView      =   XtCreateManagedWidget("appManagerView",
X						viewportWidgetClass,
X						topForm,
X						newlist, i + chain_size);
X  XtFree(newlist);
X  
X  i = 0;
X  XtSetArg(arglist[i], XtNdefaultColumns,  1); i++;
X  XtSetArg(arglist[i], XtNforceColumns, True); i++;
X  XtSetArg(arglist[i], XtNshowIcons,    True); i++;
X  appManager          =   XtCreateManagedWidget("appManager",
X						xedwListWidgetClass,
X						appManagerView,
X						arglist, i);
X
X  /* Action Buttons */
X
X  buttonSensitive = False;
X
X  i = 0;
X  XtSetArg(arglist[i], XtNfromVert,    appManagerView);   i++;
X  XtSetArg(arglist[i], XtNrubberWidth,          False);   i++;
X  XtSetArg(arglist[i], XtNrubberHeight,         False);   i++;
X  XtSetArg(arglist[i], XtNtop,          XtChainBottom);   i++;
X  XtSetArg(arglist[i], XtNwidthLinked, appManagerView);   i++;
X  XtSetArg(arglist[i], XtNborderWidth,              0);   i++;
X  XtSetArg(arglist[i], XtNdefaultDistance,          0);   i++;
X  buttonForm          =   XtCreateManagedWidget("buttonForm",
X						xedwFormWidgetClass,
X						topForm,
X						arglist, i);
X
X  trash = XCreateBitmapFromData(XtDisplay(topForm),
X				RootWindowOfScreen(XtScreen(topForm)),
X				trash_bits,
X				trash_width, trash_height);
X
X  i = 0;
X  XtSetArg(arglist[i], XtNhighlightThickness,       1);   i++;  
X  XtSetArg(arglist[i], XtNsensitive,            False);   i++;
X  XtSetArg(arglist[i], XtNbitmap,               trash);   i++;
X  trashButton	      =	  XtCreateManagedWidget("trashButton",
X						commandWidgetClass,
X						buttonForm,
X						arglist, i);
X
X
X  move = XCreateBitmapFromData(XtDisplay(topForm),
X				RootWindowOfScreen(XtScreen(topForm)),
X				move_bits,
X				move_width, move_height);
X
X  i = t = i-1;
X  XtSetArg(arglist[i], XtNfromHoriz,      trashButton);   i++;
X  XtSetArg(arglist[i], XtNhorizDistance,            6);   i++;
X  XtSetArg(arglist[i], XtNbitmap,                move);   i++;
X  moveButton	      =   XtCreateManagedWidget("moveButton",
X						commandWidgetClass,
X						buttonForm,
X						arglist, i);
X
X  copy = XCreateBitmapFromData(XtDisplay(topForm),
X				RootWindowOfScreen(XtScreen(topForm)),
X				copy_bits,
X				copy_width, copy_height);
X
X  i = t;
X  XtSetArg(arglist[i], XtNfromHoriz,        moveButton);   i++;
X  XtSetArg(arglist[i], XtNhorizDistance,             6);   i++;
X  XtSetArg(arglist[i], XtNbitmap,                 copy);   i++;
X  copyButton          =   XtCreateManagedWidget("copyButton",
X						commandWidgetClass,
X						buttonForm,
X						arglist, i);
X
X
X  XtAddCallback(trashButton, XtNcallback, button_selected, Trash);
X  XtAddCallback(copyButton, XtNcallback, button_selected, Copy);
X  XtAddCallback(moveButton, XtNcallback, button_selected, Move);
X  
X  XtAddCallback(appManager, XtNcallback, program_selected, 0);
X  appManTranslations = XtParseTranslationTable(defaultTranslations);
X  XtUninstallTranslations(appManager);
X  XtOverrideTranslations(appManager, appManTranslations);
X}
X
Xpublic void initAppManager(Widget w)
X{
X  extern int count_chr(String, char);
X  public void selectionChange(Widget, Cardinal, caddr_t);
X  Pixmap cursor, mask;
X  XColor foreground, background;
X  Colormap def_cmap;
X  String pathptr;
X  Cardinal n;
X
X  /* set selection in label */
X  selectionChange(w, 0, NULL);
X
X  /* get the copy and move cursors */
X
X  def_cmap = DefaultColormapOfScreen(XtScreen(w));
X
X  XParseColor(XtDisplay(w), def_cmap, "Black", &foreground);
X  XParseColor(XtDisplay(w), def_cmap, "White", &background);
X  XAllocColor(XtDisplay(w), def_cmap, &foreground);
X  XAllocColor(XtDisplay(w), def_cmap, &background);
X
X  cursor = XCreateBitmapFromData(XtDisplay(w),
X				 RootWindowOfScreen(XtScreen(w)),
X				 CopyC_bits,
X				 CopyC_width, CopyC_height);
X
X  mask   = XCreateBitmapFromData(XtDisplay(w),
X				 RootWindowOfScreen(XtScreen(w)),
X				 CopyM_bits,
X				 CopyM_width, CopyM_height);
X
X  copyCursor = XCreatePixmapCursor(XtDisplay(w), 
X				   cursor, mask,
X				   &foreground, &background,
X				   CopyC_x_hot, CopyC_y_hot);
X
X  XFreePixmap(XtDisplay(w), cursor);
X  XFreePixmap(XtDisplay(w), mask);
X
X
X  cursor = XCreateBitmapFromData(XtDisplay(w),
X				       RootWindowOfScreen(XtScreen(w)),
X				       MoveC_bits,
X				       MoveC_width, MoveC_height);
X
X  mask   = XCreateBitmapFromData(XtDisplay(w),
X				       RootWindowOfScreen(XtScreen(w)),
X				       MoveM_bits,
X				       MoveM_width, MoveM_height);
X
X  moveCursor = XCreatePixmapCursor(XtDisplay(w), 
X				   cursor, mask,
X				   &foreground, &background,
X				   MoveC_x_hot, MoveC_y_hot);
X
X  XFreePixmap(XtDisplay(w), cursor);
X  XFreePixmap(XtDisplay(w), mask);
X
X  mode = NormalMode;
X
X  /* Get path and put it into patharray */
X  if ((path = (String) getenv("PATH")) == NULL) {
X    fprintf(stderr, "Warning: PATH environment variable not set\n");
X  } else path = XtNewString(path);
X  
X  patharray = (String*) XtMalloc ((count_chr(path, ':')+1) * sizeof(String));
X
X  /* Extract the directories from the path into the path array */
X  
X  n = 0;
X
X  pathptr = strtok(path, ":");
X  while (pathptr != NULL) {
X    if (*pathptr == '/')
X      patharray[n++] = pathptr;
X    else 
X      fprintf(stderr, "Warning: Directory '%s' in PATH not fully qualified\n",
X	      pathptr);
X    pathptr = strtok(NULL, ":");
X  }
X  
X  pathsize = n;
X}
X
Xpublic void button_selected(Widget w, Cardinal type, caddr_t call_data)
X{
X  extern void button_dialog(Cardinal, XedwListReturnStruct *);
X  extern void changestate(Boolean);
X  extern void setCursor(Cursor);
X  extern String getfilename(String);
X  extern String cwd;
X  extern Cursor left_ptr;
X  extern Widget directoryManager;
X  extern Boolean buttonSensitive;
X  static Boolean copyfirst = True;
X  static Boolean movefirst = True;
X  XedwListReturnStruct *tmp;
X
X  /* Get list of currently highlighted items */
X  if (movefirst == True && copyfirst == True) {
X    return_list = XedwListShowCurrent(directoryManager);
X    /* extract filenames from rest of data */
X    tmp = return_list;
X    while (tmp != NULL) {
X      tmp->string = getfilename(tmp->string);
X      tmp = tmp->next;
X    }
X  }
X  
X  /* if non empty call dialog */
X  if (!(return_list->xedwList_index == XDTM_LIST_NONE &&
X      movefirst == True && copyfirst == True)) {
X    switch(type) {
X    case Trash:
X      changestate(False);
X      button_dialog(type, return_list);
X      break;
X    case Copy:
X      if (copyfirst == True) {
X	/* deselect all */
X	XedwListUnhighlight(directoryManager, XedwAll);
X	setCursor(copyCursor);
X	mode = CopyMode;
X	changestate(False);
X	srcdir = XtNewString(cwd);
X	copyfirst = False;
X      } else {
X	setCursor(left_ptr);
X	mode = NormalMode;
X	buttonSensitive = True; /* hack to force buttons insensitive */
X	changestate(False);
X	dstdir = XtNewString(cwd);
X	button_dialog(type, return_list);
X	copyfirst = True;
X      }
X      break;
X    case Move:
X      if (movefirst == True) {
X	/* deselect all */
X	XedwListUnhighlight(directoryManager, XedwAll);
X	setCursor(moveCursor);
X	mode = MoveMode;
X	changestate(False);
X	srcdir = XtNewString(cwd);
X	movefirst = False;
X      } else {
X	setCursor(left_ptr);
X	mode = NormalMode;
X	buttonSensitive = True; /* hack to force buttons insensitive */
X	changestate(False);
X	dstdir = XtNewString(cwd);
X	button_dialog(type, return_list);
X	movefirst = True;
X      }
X      break;
X    }
X  }
X  else
X    XBell(XtDisplay(w), 100);
X
X}
X
Xpublic void trashQueryResult(Widget w, Boolean delete, caddr_t call_data)
X{
X  public int  execute(String, String, String, Boolean);
X  extern void destroy_button_dialog(void);
X  extern void changestate(Boolean);
X  extern void setCursor(Cursor);
X  extern Boolean directoryManagerNewDirectory(String);
X  extern void query_dialog(String, Boolean);
X  extern Cursor busy, left_ptr;
X  extern String cwd;
X  private void freeReturnStruct(void);
X  String rmstring;
X  int status;
X  XedwListReturnStruct *tmp;
X
X  setCursor(busy);
X
X  /* destroy dialog */
X  destroy_button_dialog();
X
X  if (delete == True) {
X    /* delete files */
X
X    /* I can't be bothered writing my own remove routine so I'll call
X     * 'rm(1)' via execute instead.
X     */
X    rmstring = XtNewString("rm -fr");
X    tmp = return_list;
X    while (tmp != NULL) {
X      rmstring = (String) XtRealloc (rmstring, sizeof(char) * 
X				     (strlen(rmstring) +
X				      strlen(tmp->string) + 4));
X      sprintf(rmstring, "%s '%s'", rmstring, tmp->string);
X      tmp = tmp->next;
X    }
X    if ((status = execute(NULL, "rm", rmstring, True)) != 0) {
X      XBell(XtDisplay(w), 100);
X      query_dialog("Can't remove file", False);
X    }
X    XtFree(rmstring);
X    /* refresh directory (clear highlights as a side effect) */
X    directoryManagerNewDirectory(cwd);
X  } else {
X    /* leave list highlighted, make buttons sensitive again */
X    changestate(True);
X  }
X
X  /* free memory for list */
X  setCursor(left_ptr);
X  freeReturnStruct();
X
X}
X
Xpublic void copyQueryResult(Widget w, Boolean copy, caddr_t call_data)
X{
X  extern void destroy_button_dialog(void);
X  extern void changestate(Boolean);
X  extern void setCursor(Cursor);
X  extern void query_dialog(String, Boolean);
X  extern Boolean directoryManagerNewDirectory(String);
X  extern Cursor busy, left_ptr;
X  private void freeReturnStruct(void);
X  public int execute(String, String, String, Boolean);
X  extern String cwd;
X  String copystring;
X  int status;
X  Cardinal srclen, dstlen;
X  XedwListReturnStruct *tmp;
X
X  destroy_button_dialog();
X
X  setCursor(busy);
X
X  if (copy == True) {
X    /* copy files */
X    
X    /* I can't be bothered writing my own copy routine so I'll call
X     * 'cp(1)' via execute instead.
X     */
X    srclen = strlen(srcdir);
X    dstlen = strlen(dstdir);
X    copystring = XtNewString("cp -r");
X    tmp = return_list;
X    while (tmp != NULL) {
X      copystring = (String) XtRealloc (copystring, sizeof(char) * 
X				       (strlen(copystring) +
X					strlen(tmp->string) +
X					srclen + 4));
X      sprintf(copystring, "%s '%s/%s'", copystring, srcdir, tmp->string);
X      tmp = tmp->next;
X    }
X    copystring = (String) XtRealloc (copystring, sizeof(char) *
X				     (strlen(copystring) +
X				      dstlen + 4));
X
X    sprintf(copystring, "%s '%s'", copystring, dstdir);
X    if ((status = execute(NULL, "cp", copystring, True)) != 0) {
X      XBell(XtDisplay(w), 100);
X      query_dialog("Can't copy file!", False);
X    }
X    XtFree(copystring);
X    /* refresh directory (clear highlights as a side effect) */
X    directoryManagerNewDirectory(cwd);
X  } else {
X    changestate(True);
X  }
X
X    
X  XtFree(srcdir);
X  XtFree(dstdir);
X  setCursor(left_ptr);
X  freeReturnStruct();
X}
X
Xpublic void moveQueryResult(Widget w, Boolean move, caddr_t call_data)
X{
X  extern void destroy_button_dialog(void);
X  extern void changestate(Boolean);
X  extern void setCursor(Cursor);
X  extern Boolean directoryManagerNewDirectory(String);
X  extern void query_dialog(String, Boolean);
X  extern Cursor busy, left_ptr;
X  private void freeReturnStruct(void);
X  public int execute(String, String, String, Boolean);
X  extern String cwd;
X  String movestring;
X  Cardinal srclen, dstlen;
X  int status;
X  XedwListReturnStruct *tmp;
X
X  destroy_button_dialog();
X
X  setCursor(busy);
X
X  if (move == True) {
X    /* move files */
X    
X    /* I can't be bothered writing my own move routine so I'll call
X     * 'mv(1)' via execute instead.
X     */
X    srclen = strlen(srcdir);
X    dstlen = strlen(dstdir);
X    movestring = XtNewString("mv -f - ");
X    tmp = return_list;
X    while (tmp != NULL) {
X      movestring = (String) XtRealloc (movestring, sizeof(char) * 
X				       (strlen(movestring) +
X					strlen(tmp->string) +
X					srclen + 4));
X      sprintf(movestring, "%s '%s/%s'", movestring, srcdir, tmp->string);
X      tmp = tmp->next;
X    }
X    movestring = (String) XtRealloc (movestring, sizeof(char) *
X				     (strlen(movestring) +
X				      dstlen + 4));
X
X    sprintf(movestring, "%s '%s'", movestring, dstdir);
X    if ((status = execute(NULL, "mv", movestring, True)) != 0) {
X      XBell(XtDisplay(w), 100);
X      query_dialog("Can't move file!", False);
X    }
X    XtFree(movestring);
X    /* refresh directory (clear highlights as a side effect) */
X    directoryManagerNewDirectory(cwd);
X  } else {
X    changestate(True);
X  }
X    
X  XtFree(srcdir);
X  XtFree(dstdir);
X  setCursor(left_ptr);
X  freeReturnStruct();
X}
X
Xprivate void freeReturnStruct(void)
X{
X  /* Deallocate memory for the current list return structure.
X   */
X
X  XedwListReturnStruct *tmp;
X
X  while(return_list != NULL) {
X    tmp = return_list;
X    return_list = return_list->next;
X    XtFree(tmp->string);
X    XtFree(tmp);
X  }
X}
X  
Xpublic void selectionChange(Widget w, Cardinal selection, caddr_t crap)
X{
X  extern AppSelection **appselections;
X  extern Cardinal selectionindex;
X  XedwList **list;
X  Arg arglist[1];
X  Cardinal i;
X
X  appman_selection = selection;
X  i = 0;
X  XtSetArg(arglist[i], XtNlabel, appselections[appman_selection]->name); i++;
X  XtSetValues(appManagerButton, arglist, i);
X
X  /* Change contents of AppManager to that of the new selection */
X  list = (XedwList**) appselections[appman_selection]->list;
X
X  XedwListChange(appManager, list, appselections[appman_selection]->number,
X		 0, True);
X
X  /* Reset scrollbar to top */
X  setscroll(appManagerView, 0.0);
X}
X
Xprivate void program_selected(Widget w, caddr_t client, caddr_t call)
X{
X  public int execute(String, String, String, Boolean);
X  public String build_arguments(String, SelOptions);
X  extern void setCursor(Cursor);
X  extern Cursor busy;
X  extern AppSelection **appselections;
X  XedwListReturnStruct *list;
X  AppProgram *node;
X  String program, filename;
X  Cardinal index;
X
X  setCursor(busy);
X  /* Get the index of the program double clicked */
X  list = XedwListShowCurrent(w);
X  index = list->xedwList_index;
X  node = appselections[appman_selection]->list[index];
X  program = XtNewString(node->program);
X  
X  /* extract filename from program */
X  filename = XtNewString(program);
X  filename = strtok(filename, " ");
X  
X  XtFree(list);
X  
X  /* check to see if there are any highlighted files to add as arguments, 
X   * if so check to see where the insertion point is, if no insertion 
X   * point then append arguments.
X   */
X
X  program = build_arguments(program, node->options);
X
X  
X  /* execute program */
X
X  execute(NULL, filename, program, False);
X  setCursor(NULL);
X
X}
X
Xpublic int execute(String fullname, String filename, 
X		    String args, Boolean cwait)
X{
X  typedef enum {ready, quote, normal, quoteready} QModes;
X
X  QModes mode;
X  Cardinal i, n, arglen;
X  int result, pid, fd;
X  int status = 0;
X  String newargs[MAXARGS], strptr;
X  
X  if (fullname == NULL) {
X    /* Find program */
X    result = -1;
X    for (i = 0; i < pathsize && result != 0; i++) {
X      /* append filename to path */
X      fullname = (String) XtRealloc (fullname, ((strlen(patharray[i])+
X						 strlen(filename) + 3)
X						* sizeof(char)));
X      strcpy(fullname, patharray[i]);
X      strcat(fullname, "/");
X      strcat(fullname, filename);
X
X      result = access(fullname, X_OK); /* Does file exist, Is file executable ? */
X    }
X    
X    if (result != 0) {
X      fprintf(stderr, "Warning: Command '%s' not found in PATH\n", filename);
X      return;
X    }
X  } 
X
X  /* split the args string into a NULL terminated array of strings .
X   * If a string of characters is enclosed within quotes, it is counted
X   * as a single argument.
X   */
X
X  n = 0;
X  mode = ready;
X  arglen = strlen(args);
X  for (i = 0; i < arglen; i++) {
X    switch (*(args+i)) {
X    case '\'':
X      if (mode == normal || mode == ready) {
X	/* start a new arg on the next normal chr */
X	mode = quoteready;
X      } else if (mode == quote || mode == quoteready) {
X	/* close current quote */
X	*(args+i) = '\0';
X	mode = ready;
X      }
X      break;
X    case ' ':
X    case '\t':
X      if (mode == normal) {
X	/* terminate current arg */
X	*(args+i) = '\0';
X	mode = ready;
X      }
X      break;
X    default:
X      if (mode == ready || mode == quoteready) {
X	/* start a new arg */
X	if (n == MAXARGS-1) {
X	  fprintf(stderr, "Error: Only %d arguments allowed"
X		  " to a command.\n", MAXARGS);
X	} else {
X	  newargs[n++] = args+i;
X	  if (mode == ready)
X	    mode = normal;
X	  else
X	    mode = quote;
X	}
X      }
X      break;
X    }
X  }
X	
X  newargs[n] = NULL;
X
X  if ((pid = fork()) == -1) 
X    fprintf(stderr, "Warning: unable to fork\n");
X  else 
X    if (pid == 0) {
X      /* Child */
X
X      /* Take standard input from /dev/null. This presents any child process
X       * with an immediate end-of-file when read.
X       * Also redirect standard output to /dev/null, but leave standard error
X       * associated with xdtm so we can see error messages on the console.
X       * (unless cwait is set, in whiich case stderr is redirected as well)
X       */
X      
X      if (close(0) == -1) 
X	fprintf(stderr, "Warning: can't close childs file descriptors\n");
X      else 
X	if (open("/dev/null", O_RDONLY, 0) == -1)
X	  fprintf(stderr, "Warning: can't open /dev/null as new input"
X		  " for child\n");
X      
X      if (close(1) == -1) 
X	fprintf(stderr, "Warning: can't close childs file descriptors\n");
X      else 
X	if (open("/dev/null", O_WRONLY, 0) == -1)
X	  fprintf(stderr, "Warning: can't open /dev/null as new output"
X		  " for child\n");
X
X      if (cwait) 
X	if (close(2) == -1) 
X	  fprintf(stderr, "Warning: can't close childs file descriptors\n");
X	else 
X	  if (open("/dev/null", O_WRONLY, 0) == -1)
X	    fprintf(stderr, "Warning: can't open /dev/null as new error output"
X		    " for child\n");
X
X      /* close all opened file descriptors (except stdin, stderr, stdout) */
X      for (fd = 3; fd < 20; fd++)
X	(void) close(fd); 
X
X      execv(fullname, newargs);
X
X      fprintf(stderr, "Warning: Exec on '%s' failed.\n", fullname);
X      exit(0);
X    } else {
X      /* Parent */
X      
X      /* If cwait is True then wait for the child to finish, then
X       * set status to it's return value.
X       */
X      if (cwait) {
X	wait(&status);
X	status = (status >> 8);
X      }
X    }
X
X  return(status);
X}
X
Xpublic String build_arguments(String program, SelOptions options)
X{
X  extern void changestate(Boolean);
X  extern String getfilename(String);
X  extern Widget directoryManager;
X  XedwListReturnStruct *list, *tmplist;
X  String ptr, tmpptr, arguments;
X
X  list = XedwListShowCurrent(directoryManager);
X
X  arguments = NULL;
X  if (options != N_SEL) {
X    while (list != NULL) {
X      arguments = XtRealloc (arguments, sizeof(char) * 
X			     (((arguments == NULL) ? 0 : strlen(arguments)) + 
X			      strlen(getfilename(list->string)) + 4));
X      strcat(arguments, " ");
X      strcat(arguments, getfilename(list->string));
X      tmplist = list;
X      list = list->next;
X      XtFree(tmplist);
X    }
X    /* insert the arguments into the program string */
X    program = XtRealloc (program, sizeof(char) * (strlen(program) + 
X						  strlen(arguments) + 4));
X    
X    if ((ptr = strstr(program, "!@")) != NULL) {
X      /* replace !@ with arguments */
X      tmpptr = XtNewString(ptr+2);
X      *ptr = '\0';
X      strcat(program, arguments);
X      strcat(program, tmpptr);
X      XtFree(tmpptr);
X    } else {
X      /* append arguments to program */
X      strcat(program, arguments);
X    }
X    XtFree(arguments);
X  } 
X
X  XedwListUnhighlight(directoryManager, XedwAll);
X  changestate(False); 
X
X  return(program);
X}
SHAR_EOF
chmod 0644 code/appman.c || echo "restore of code/appman.c fails"
echo "x - extracting code/buttons.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > code/buttons.c &&
X/*****************************************************************************
X ** File          : buttons.c                                               **
X ** Purpose       : Initialise and Realise button dialogs                   **
X ** Author        : Edward Groenendaal                                      **
X ** Date          : April 1991                                              **
X ** Documentation : Xdtm Design Folder                                      **
X ** Related Files :                                                         **
X *****************************************************************************/
X
X#include "xdtm.h"
X#include "menus.h"
X
X#include <X11/Shell.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Viewport.h>
X#include "Xedw/XedwForm.h"
X#include "Xedw/XedwList.h"
X
Xextern void realize_dialog(Widget);
X
X/* Widgets */
X
Xprivate Widget buttonpopup; 	/* For conformation of move/copy/trash buttons */
Xprivate Widget buttonform;
Xprivate Widget buttonlabel1;
Xprivate Widget buttonlabel2;
Xprivate Widget buttonyes;
Xprivate Widget buttonno;
Xprivate Widget fileview;
Xprivate Widget filelist;
X
Xpublic void init_button(Widget top)
X{
X  Arg arglist[5];
X  Cardinal i;
X  XtTranslations translations;
X  Dimension height, space;
X  XFontStruct *font;
X
X  buttonpopup  =   XtCreatePopupShell("buttonpopup",
X				      transientShellWidgetClass,
X				      top,
X				      NULL, 0);
X
X
X  buttonform    =   XtCreateManagedWidget("buttonform",
X				      xedwFormWidgetClass,
X				      buttonpopup,
X				      NULL, 0);
X
X  i = 0;
X  XtSetArg(arglist[i], XtNjustify, XtJustifyCenter);  i++;
X  XtSetArg(arglist[i], XtNfullWidth,          True);  i++;
X  XtSetArg(arglist[i], XtNborderWidth,           0); i++;
X  buttonlabel1  =   XtCreateManagedWidget("buttonlabel1",
X					  labelWidgetClass,
X					  buttonform,
X					  arglist, i);
X
X  i = 3;
X  XtSetArg(arglist[i], XtNfromVert,   buttonlabel1);  i++; 
X  buttonlabel2  =   XtCreateManagedWidget("buttonlabel2",
X					  labelWidgetClass,
X					  buttonform,
X					  arglist, i);
X
X  i = 0;
X  XtSetArg(arglist[i], XtNfromVert, buttonlabel2);  i++; 
X  XtSetArg(arglist[i], XtNfullWidth,        True);  i++;
X  XtSetArg(arglist[i], XtNforceBars,        True);  i++;
X  XtSetArg(arglist[i], XtNallowVert,        True);  i++;
X  fileview = XtCreateManagedWidget("fileview",
X				   viewportWidgetClass,
X				   buttonform,
X				   arglist, i);
X
X  translations = XtParseTranslationTable("");
X  i = 0;
X  XtSetArg(arglist[i], XtNdefaultColumns,  1); i++;
X  XtSetArg(arglist[i], XtNforceColumns, True); i++;
X  XtSetArg(arglist[i], XtNrowSpacing,      4); i++;
X  XtSetArg(arglist[i], XtNtranslations, translations); i++;
X  filelist = XtCreateManagedWidget("filelist",
X				   xedwListWidgetClass,
X				   fileview,
X				   arglist, i);
X
X
X  /* Get font height from filelist, then set fileview to be 5 times that
X   * size.
X   */
X
X  i = 0;
X  XtSetArg(arglist[i], XtNfont, &font); i++;
X  XtSetArg(arglist[i], XtNrowSpacing, &space); i++;
X  XtGetValues(filelist, arglist, i);
X
X  height = (font->max_bounds.ascent +
X           font->max_bounds.descent +
X	   space) * 5;
X
X  i = 0;
X  XtSetArg(arglist[i], XtNheight, height); i++;
X  XtSetValues(fileview, arglist, i);
X
X
X  i = 0;
X  XtSetArg(arglist[i], XtNfromVert,       fileview);  i++; 
X  XtSetArg(arglist[i], XtNjustify, XtJustifyCenter);  i++;
X  buttonno   =   XtCreateManagedWidget("buttonyes",
X				       commandWidgetClass,
X				       buttonform,
X				       arglist, i);
X 
X  i = 2;
X  XtSetArg(arglist[i], XtNfromHoriz,   buttonno);  i++;
X  XtSetArg(arglist[i], XtNwidthLinked, buttonno);  i++;
X  buttonyes  =   XtCreateManagedWidget("buttonyes",
X				       commandWidgetClass,
X				       buttonform,
X				       arglist, i);
X
X}
X
X
Xpublic void button_dialog(Cardinal type, XedwListReturnStruct *list)
X{
X  private int buttoniconcmp(XedwList **, XedwList **);
X  extern String getfilename(String);
X  extern void setscroll(Widget, float);
X
X  XedwListReturnStruct *tmp;
X  XedwList **buttonlist;
X  Arg arglist[5];
X  Cardinal i, n;
X  private String CancelButtonLabel = "Cancel";
X
X  /* Count items in linked list */
X  n = 0;
X  tmp = list;
X  while (tmp != NULL) {
X    tmp = tmp->next;
X    n++;
X  }
X
X  /* Allocate an array of XedwList* of that size */
X  buttonlist = (XedwList**) XtMalloc (sizeof(XedwList*) * (n+1));
X
X  /* Put Strings from linked list into array, using NULL icons */
X  for (i = 0; i < n; i++) {
X    buttonlist[i] = XtNew(XedwList);
X    buttonlist[i]->string = list->string;
X    list = list->next;
X  }
X  buttonlist[i] = NULL;
X
X  /* Sort the list */
X  qsort((char*)buttonlist, n, sizeof(buttonlist[0]), buttoniconcmp);
X
X  /* Reset view to top */
X
X  setscroll(fileview, 0.0);
X
X  switch (type) {
X  case Trash:
X    {
X      extern void trashQueryResult(Widget, Boolean, caddr_t);
X      private String TrashLabel1       = "Delete these files";
X      private String TrashLabel2       = "from current directory?";
X      private String TrashButtonLabel  = "Delete";
X
X      /* label */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, TrashLabel1);  i++;
X      XtSetValues(buttonlabel1, arglist, i);
X    
X      /* label2 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel,       TrashLabel2);  i++; 
X      XtSetValues(buttonlabel2, arglist, i);
X      
X      /* file list */
X      i = 0;
X      XtSetArg(arglist[i], XtNlongest,           0); i++;
X      XtSetArg(arglist[i], XtNnumberStrings,     0); i++;
X      XtSetArg(arglist[i], XtNxedwList, buttonlist); i++;
X      XtSetValues(filelist, arglist, i);
X
X      /* button1 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, CancelButtonLabel);  i++;
X      XtSetValues(buttonno, arglist, i);
X      
X      /* button2 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel,   TrashButtonLabel);  i++;
X      XtSetValues(buttonyes, arglist, i);
X      
X      XtAddCallback(buttonno, XtNcallback, trashQueryResult, False);
X      XtAddCallback(buttonyes, XtNcallback, trashQueryResult, True);
X      realize_dialog(buttonpopup);
X      break;
X    }
X  case Copy:
X    {
X      extern void copyQueryResult(Widget, Boolean, caddr_t);
X      private String CopyLabel1       = "Copy these files";
X      private String CopyLabel2       = "to current directory?";
X      private String CopyButtonLabel  = "Copy";
X
X      /* label */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, CopyLabel1);  i++;
X      XtSetValues(buttonlabel1, arglist, i);
X    
X      /* label2 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, CopyLabel2);  i++; 
X      XtSetValues(buttonlabel2, arglist, i);
X      
X      /* file list */
X      i = 0;
X      XtSetArg(arglist[i], XtNlongest,           0); i++;
X      XtSetArg(arglist[i], XtNnumberStrings,     0); i++;
X      XtSetArg(arglist[i], XtNxedwList, buttonlist); i++;
X      XtSetValues(filelist, arglist, i);
X
X      /* button1 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, CancelButtonLabel);  i++;
X      XtSetValues(buttonno, arglist, i);
X      
X      /* button2 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, CopyButtonLabel);  i++;
X      XtSetValues(buttonyes, arglist, i);
X      
X      XtAddCallback(buttonno, XtNcallback,  copyQueryResult, False);
X      XtAddCallback(buttonyes, XtNcallback, copyQueryResult, True);
X      realize_dialog(buttonpopup);
X      break;
X    }
X  case Move:
X    {
X      extern void moveQueryResult(Widget, Boolean, caddr_t);
X      private String MoveLabel1       = "Move these files";
X      private String MoveLabel2       = "to current directory?";
X      private String MoveButtonLabel  = "Move";
X
X      /* label */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, MoveLabel1);  i++;
X      XtSetValues(buttonlabel1, arglist, i);
X    
X      /* label2 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, MoveLabel2);  i++; 
X      XtSetValues(buttonlabel2, arglist, i);
X      
X      /* file list */
X      i = 0;
X      XtSetArg(arglist[i], XtNlongest,           0); i++;
X      XtSetArg(arglist[i], XtNnumberStrings,     0); i++;
X      XtSetArg(arglist[i], XtNxedwList, buttonlist); i++;
X      XtSetValues(filelist, arglist, i);
X
X      /* button1 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, CancelButtonLabel);  i++;
X      XtSetValues(buttonno, arglist, i);
X      
X      /* button2 */
X      i = 0;
X      XtSetArg(arglist[i], XtNlabel, MoveButtonLabel);  i++;
X      XtSetValues(buttonyes, arglist, i);
X      
X      XtAddCallback(buttonno, XtNcallback,  moveQueryResult, False);
X      XtAddCallback(buttonyes, XtNcallback, moveQueryResult, True);
X      realize_dialog(buttonpopup);
X      break;
X    }
X
X  default:
X    fprintf(stderr, "Unrecognised button dialog request\n");
X    break;
X  }
X
X  /* deallocate memory for newlist */
X
X}
X
Xpublic void destroy_button_dialog(void)
X{
X  XtPopdown(buttonpopup);
X  
X  XtRemoveAllCallbacks(buttonyes, XtNcallback);
X  XtRemoveAllCallbacks(buttonno, XtNcallback);
X
X}
X
Xprivate int buttoniconcmp(XedwList **ip1, XedwList **ip2)
X{
X  /* compare the strings of 2 XedwList's */
X
X  return (strcmp((*ip1)->string, 
X		 (*ip2)->string));
X}
SHAR_EOF
chmod 0644 code/buttons.c || echo "restore of code/buttons.c fails"
echo "x - extracting code/dialogs.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > code/dialogs.c &&
X/* v0.2 */
X/***********************************************************************************
X ** File          : dialogs.c                                                     **
X ** Purpose       : Initialise and Realise dialogs                                **
X ** Author        : Edward Groenendaal                                            **
X ** Date          : 18th Feb 1991                                                 **
X ** Documentation : Xdtm Design Folder                                            **
X ** Related Files : quit.c buttons.c listoption.c map.c select.c display.c        **
X **                 newfile.c							  **
X ***********************************************************************************/
X
X/* dialog box's provided: Quit    - Quit (yes/no)
X *			  Button  - Do action to these files (yes/no)
X *                        Longl   - Select options on Long Listing
X *                        Map     - Map program x over selected files OR
X *                        Select  - Select files using RE x.
X *			  Query   - Display file?
X * 			  Display - Display a file.
X *           		  Newfile - Ask for filename, create empty file. 
X *			  Info    - Give info about a file.
X *
X * Create instances of popup shells and forms, plus one of each of the 'core' dialog
X */
X
X#include "xdtm.h"
X
Xpublic void createDialogWidgets(Widget top)
X{
X
X  extern void init_quit(Widget);
X  extern void init_button(Widget);
X  extern void init_listoption(Widget);
X  extern void init_map(Widget);
X  extern void init_query(Widget);
X  extern void init_display(Widget);
X  extern void init_newfile(Widget);
X  extern void init_info(Widget);
X
X  init_quit(top);
X  init_button(top);
X  init_listoption(top);
X  init_map(top);
X  init_query(top);
X  init_display(top);
X  init_newfile(top);
X  init_info(top);
X 				 
X}
X
Xpublic void realize_dialog(Widget popup)
X{
X  extern Widget topLevel;
X  Position x,y;
X  Dimension appWidth, appHeight, qWidth, qHeight;
X  XtGeometryResult result;
X  XtWidgetGeometry answer, question;
X  Arg arglist[2];
X  Cardinal i;
X  
X  /* You dont know the dimensions of a widget for certain until it is
X   * realized, therefore realize the dialog.
X   * NOTE: XtRealizeWidget returns without an error if widget is already
X   *       realized, hence no check via XtIsRealized.
X   */
X
X  XtRealizeWidget(popup);
X
X  /* Get dimensions of application */
X  i = 0;
X  XtSetArg(arglist[i], XtNwidth,  &appWidth);    i++;
X  XtSetArg(arglist[i], XtNheight, &appHeight);   i++;
X  XtGetValues(topLevel, arglist, i);
X
X  /* Get dimensions of quit popup */
X  i = 0;
X  XtSetArg(arglist[i], XtNwidth,  &qWidth);    i++;
X  XtSetArg(arglist[i], XtNheight, &qHeight);   i++;
X  XtGetValues(popup, arglist, i);
X
X  /* Translate application coordinates to screen coordinates */
X  XtTranslateCoords(topLevel,
X		    (Position) ((appWidth/2)-(qWidth/2)),
X		    (Position) ((appHeight/2)-(qHeight/2)),
X		    &x, &y);
X
X  /* move popup shell to that position */
X  i = 0;
X  XtSetArg(arglist[i], XtNx, x);  i++;
X  XtSetArg(arglist[i], XtNy, y);  i++;
X  XtSetValues(popup, arglist, i);
X
X  XtPopup(popup, XtGrabNonexclusive);
X  
X}
SHAR_EOF
chmod 0644 code/dialogs.c || echo "restore of code/dialogs.c fails"
echo "x - extracting code/dirman.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > code/dirman.c &&
X/* v0.3 */
X/*****************************************************************************
X ** File          : dirman.c                                                **
X ** Purpose       : Directory Manager                                       **
X ** Author        : Edward Groenendaal                                      **
X ** Date          : 18th Feb 1990                                           **
X ** Documentation : Xedw Design Folder                                      **
X ** Related Files :                                                         **
X *****************************************************************************/
X
X/* Include the application header file */
X#include "xdtm.h"
X
X/* Include the local header files */
X#include <sys/types.h>
X#include <dirent.h>
X#include <sys/stat.h>
X#include <sys/param.h>
X#include <X11/Xaw/AsciiText.h>
X
X#include "menus.h"
X#include "Xedw/XedwList.h"
X#include "Xedw/XedwForm.h"
X
X#define LISTSIZE    128
X#define LISTINCR    64
X
Xpublic void   changestate(Boolean);        /* Change sensitivity */
Xpublic String getfilename(String);	   /* extract filename */
X
Xpublic Widget directoryManager;
Xpublic String cwd;			 /* current working directory */
Xpublic Cardinal icon_list_size = 0;
Xpublic Cardinal icon_list_max_size = LISTSIZE;
Xpublic XedwList **icon_list;
X
X/* local copies of the menu panes which are to be made insensitive when
X * no there is no current selection.
X */
Xprivate Widget duplicatemenu, getinfomenu, trashmenu, 
X               copymenu, movemenu, mapmenu;
X
Xpublic void createDirectoryManagerWidgets(Widget view)
X{
X  public  void selection_made(Widget, caddr_t, caddr_t);
X  private void DoubleClick(Widget, XButtonEvent*);
X  private void GoUp(Widget, XButtonEvent*);
X  private void SelectAll(Widget, XButtonEvent*);
X  private void Refresh(Widget, XButtonEvent*);
X
X  extern AppData app_data;
X  extern Icon_mode current_mode;
X  Cardinal i;
X  Arg arglist[6];
X  XtTranslations dirManTranslations;
X
X  static XtActionsRec actions[] = {
X    {"DoubleClick", DoubleClick},
X    {"GoUp",        GoUp},
X    {"SelectAll",   SelectAll},
X    {"Refresh",     Refresh},
X    {NULL, NULL}
X  };
X
X  static char defaultTranslations[] =
X             "<Btn1Up>(2):     DoubleClick()\n\
X              <Key>u:          GoUp()\n\
X              <Key>a:          SelectAll()\n\
X	      Ctrl<Key>L:      Refresh()";
X  
X  i = 0;
X  switch (current_mode.mode) {
X  case Icons:
X    XtSetArg(arglist[i], XtNshowIcons, True); i++;
X    break;
X  case Short:
X    XtSetArg(arglist[i], XtNshowIcons,   False); i++;
X    XtSetArg(arglist[i], XtNrowSpacing, 5); i++;
X    break;
X  case Long:
X    XtSetArg(arglist[i], XtNshowIcons,   False); i++;
X    XtSetArg(arglist[i], XtNrowSpacing,      5); i++;
X    XtSetArg(arglist[i], XtNforceColumns, True); i++;
X    XtSetArg(arglist[i], XtNdefaultColumns,  1); i++;    
X  }
X  XtSetArg(arglist[i], XtNfont, app_data.dm_font); i++;    
X  XtSetArg(arglist[i], XtNmSelections,      True); i++;
X  directoryManager    =   XtCreateManagedWidget("directoryManager",
X						xedwListWidgetClass,
X						view,
X						arglist, i);
X
X  XtAddCallback(directoryManager, XtNcallback, selection_made, 0);
X  XtAddActions(actions, XtNumber(actions));
X  dirManTranslations = XtParseTranslationTable(defaultTranslations);
X  XtAugmentTranslations(directoryManager, dirManTranslations);
X}
X
Xpublic Boolean directoryManagerNewDirectory(String newpath)
X{
X  extern Boolean getIconType(String, String, XedwList*);
X  extern void setCursor(Cursor);
X  extern void setscroll(Widget, float);
X  private int iconcmp(XedwList*, XedwList*);
X
X  extern Icon_mode current_mode;
X  extern Cursor busy;
X  extern Widget dirSelector;
X  extern Widget directoryManagerView;
X  Arg args[1];
X  XedwList temp;
X  DIR *dirp;
X  struct dirent *dp;
X  Cardinal i = 0, n;
X  Boolean result = False;
X
X  /* create a new one */
X  if ((dirp = opendir(newpath)) != NULL && chdir(newpath) == 0) {
X
X    /* set cursor to busy */
X    setCursor(busy);
X
X    /* Trash old list */
X    for(i=0; i < icon_list_size; i++) {
X      XtFree(icon_list[i]->string);
X      XtFree(icon_list[i]);
X    }
X
X    i = 0;
X    while ((dp = readdir(dirp)) != NULL) {
X      if (i == icon_list_max_size) {
X	icon_list_max_size += LISTINCR;
X	icon_list = (XedwList**) XtRealloc(icon_list,
X					   sizeof(XedwList*) * 
X					   icon_list_max_size);
X      } else 
X	if (getIconType(dp->d_name, newpath, &temp)) {
X	  icon_list[i] = XtNew(XedwList);
X	  icon_list[i]->string = temp.string;
X	  icon_list[i]->icon   = temp.icon;
X	  i++;
X	}
X    }
X    icon_list[i] = NULL;
X    icon_list_size = i;
X    qsort((char*)icon_list, icon_list_size, sizeof(icon_list[0]), iconcmp);
X    XedwListChange(directoryManager, icon_list, icon_list_size, 0, True);
X    setscroll(directoryManagerView, 0.0);
X    closedir(dirp);
X    result = True;
X    /* Change entry in the directory selector */
X    XtSetArg(args[0], XtNstring, newpath); 
X    XtSetValues(dirSelector, args, 1);
X    /* reset cursor */
X    setCursor(NULL);
X  } else XBell(XtDisplay(directoryManager), 100);
X  return(result);
X}
X
X
Xprivate int iconcmp(XedwList **ip1, XedwList **ip2)
X{
X  /* compare the strings of 2 XedwList's */
X
X  return (strcmp(getfilename((*ip1)->string), 
X		 getfilename((*ip2)->string)));
X}
X
Xpublic void initDirectoryManager(void)
X{
X  extern Boolean buttonSensitive;
X  extern Widget menuBar;
X  char tmpcwd[MAXPATHLEN];
X
X  /* Initialise the icon list */
X  icon_list = (XedwList**) XtMalloc(sizeof(XedwList*) * LISTSIZE);
X
X  /* Set the starting directory */
X  if (getwd(tmpcwd) != NULL) 
X    cwd = XtNewString(tmpcwd);
X  else
X    if ((cwd = (char*) getenv("HOME")) == NULL) 
X      cwd = XtNewString("/");
X    else
X      cwd = XtNewString(cwd);
X
X  /* Get the id's of the menu widgets which are to be toggled with the
X   * buttons. Note: This relies on the menus being created first, which
X   * they are.
X   */
X  if ((duplicatemenu = 
X       XtNameToWidget(menuBar, "fileMenuButton.fileMenu.duplicate")) == NULL) {
X    fprintf(stderr, "Directorymanager: Can't find duplicate menu widget\n");
X    exit(2);
X  }
X  if ((getinfomenu = 
X       XtNameToWidget(menuBar, "fileMenuButton.fileMenu.getinfo")) == NULL) {
X    fprintf(stderr, "Directorymanager: Can't find getinfo menu widget\n");
X    exit(2);
X  }
X  if ((trashmenu   = 
X       XtNameToWidget(menuBar, "fileMenuButton.fileMenu.trash")) == NULL) {
X    fprintf(stderr, "Directorymanager: Can't find trash menu widget\n");
X    exit(2);
X  }
X  if ((copymenu    = 
X       XtNameToWidget(menuBar, "fileMenuButton.fileMenu.copy")) == NULL) {
X    fprintf(stderr, "Directorymanager: Can't find copy menu widget\n");
X    exit(2);
X  }
X  if ((movemenu    = 
X       XtNameToWidget(menuBar, "fileMenuButton.fileMenu.move")) == NULL) {
X    fprintf(stderr, "Directorymanager: Can't find move menu widget\n");
X    exit(2);
X  }
X  if ((mapmenu     = 
X       XtNameToWidget(menuBar, "optionMenuButton.optionMenu.map")) == NULL) {
X    fprintf(stderr, "Directorymanager: Can't find map menu widget\n");
X    exit(2);
X  }
X  (void) directoryManagerNewDirectory(cwd);
X  buttonSensitive = True;
X  changestate(False); 	   /* Insure that menus are insensitive */
X}
X
Xpublic void selection_made(Widget w, caddr_t client_data, caddr_t call_data)
X{
X  /* Someone has either selected or deselected an item.
X   * If there's nothing selected then buttons are changed to 
X   * not sensitive.
X   */
X
X  extern Boolean buttonSensitive;
X  extern Widget trashButton, copyButton, moveButton;
X  Arg arglist[1];
X  Cardinal i;
X
X
X  if (XedwListSelection(w) != buttonSensitive)
X    if (buttonSensitive == False) {
X      changestate(True);
X    } else {
X      changestate(False);
X    }
X}
X
Xprivate void DoubleClick(Widget w, XButtonEvent *event)
X{
X  /* Either Start a program, View a file or change directory.
X   * executable = try to exec it.
X   * directory  = try to enter it.
X   * otherwise offer to view it.
X   */
X  extern void query_dialog(String, Boolean);
X  extern int execute(String, String, String, Boolean);
X
X  extern Boolean buttonSensitive;
X  extern Widget trashButton, moveButton, copyButton;
X
X  struct stat filestatus;
X  String fullname, filename, temp;
X  XedwListReturnStruct *highlighted;
X  Arg arglist[1];
X  Cardinal i;
X
X  selection_made(w, (caddr_t)0, (caddr_t)0);
X  highlighted = XedwListShowCurrent(w);
X
X  if (highlighted->xedwList_index != XDTM_LIST_NONE) {
X    filename = getfilename(highlighted->string);
X    fullname=(String) XtMalloc((strlen(filename)+strlen(cwd)+1) * sizeof(char));
X    strcpy(fullname, cwd);
X    if (strcmp(cwd, "/") != 0)
X      strcat(fullname, "/");
X    strcat(fullname, filename);
X    if (stat(fullname, &filestatus) == -1) {
X      fprintf(stderr,"xdtm: ARRRGGHHH stat error\n");
X    } else {
X      if ((filestatus.st_mode & S_IFMT) == S_IFDIR) {
X	if (strcmp(filename, "..") == 0) {
X	  strcpy(fullname, cwd);
X	  if ((temp = (char*) strrchr(fullname, '/')) == NULL) 
X	    fprintf(stderr, "xdtm: impossible error\n");
X	  if (temp == fullname)
X	    *(temp+1) = '\0';
X	  else
X	    *temp = '\0';
X	}  
X	if (strcmp(filename, ".") == 0) {
X	  XtFree(fullname);
X	  fullname=XtNewString(cwd);
X	}
X	if (directoryManagerNewDirectory(fullname) == True) {
X	  XtFree(cwd);
X	  cwd=fullname;
X	  changestate(False);
X	} else XBell(XtDisplay(w), 100);
X      } else {
X	/* Not a directory, is it executable */
X	if ((filestatus.st_mode & S_IXUSR) != 0 ||
X	    (filestatus.st_mode & S_IXGRP) != 0 ||
X	    (filestatus.st_mode & S_IXOTH) != 0) {
X	  extern void setCursor(Cursor);
X	  extern Cursor busy;
X
X	  setCursor(busy);
X	  execute(fullname, filename, filename, False);
X	  setCursor(NULL);
X	} else
X	  if ((filestatus.st_mode & S_IFMT) == S_IFREG) {
X	    /* Display dialog box to ask whether to display file */
X	    query_dialog(fullname, True);
X	  } else XBell(XtDisplay(w), 100);
X	XtFree(fullname);
X      }
X    }
X    XtFree(highlighted);
X  }
X}
X
Xprivate void GoUp(Widget w, XButtonEvent *event)
X{
X  Cardinal i;
X  /* Find entry with .. */
X  for (i=0; i < icon_list_size && 
X       (strcmp(getfilename(icon_list[i]->string), "..") != 0); i++); 
X
X  XedwListUnhighlight(w, XedwAll);
X  /* Call XedwListHighlight with item number */
X  XedwListHighlight(w, i);
X
X  /* Call double click */
X
X  DoubleClick(w, (XButtonEvent*) NULL);
X
X}
X
Xprivate void SelectAll(Widget w, XButtonEvent *event)
SHAR_EOF
echo "End of part 1"
echo "File code/dirman.c is continued in part 2"
echo "2" > s2_seq_.tmp
exit 0



More information about the Alt.sources mailing list