1 /*****************************************************************************
2  ** File          : dirman.c                                                **
3  ** Purpose       : Directory Manager                                       **
4  ** Author        : Edward Groenendaal                                      **
5  ** Date          : 18th Feb 1991                                           **
6  ** Documentation : Xdtm Design Folder                                      **
7  ** Changes       : 28-11-91, Edward Groenendaal                            **
8  **                 Merged Jon's code into V1.8 to make V2.0                **
9  **                 18-04-92, Edward Groenendaal                            **
10  **                 Added #if NeedFunctionPrototypes stuff                  **
11  **                 June 16, 1992, Ramon Santiago                           **
12  **                 Changed all XtCreate calls to XtVaCreate calls.         **
13  **                 Changed all caddr_t to XtPointer.                       **
14  **                 June 20, 1992, Ramon Santiago                           **
15  **                 removed some lint                                       **
16  *****************************************************************************/
17 
18 /* Include the application header file */
19 #include "xdtm.h"
20 #include "menus.h"
21 #include "parse.h"
22 
23 /* Include the local header files */
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <dirent.h>
28 #include <sys/stat.h>
29 #include <sys/param.h>
30 #include <limits.h>
31 #include <X11/Xaw/AsciiText.h>
32 
33 #include "Xedw/XedwList.h"
34 #include "Xedw/XedwForm.h"
35 
36 #define LISTSIZE    128		/* The initial size of the icon_list   */
37 #define LISTINCR    64		/* The steps by which it will increase */
38 
39 #ifdef TRUE_SYSV
40 #ifndef MAXPATHLEN
41 #define MAXPATHLEN 512  /* jcc */
42 #endif
43 #endif
44 
45 /* external and forward functions definitions */
46 #if NeedFunctionPrototypes
47   public void changestate(Boolean);
48   private void DoubleClick(Widget, XButtonEvent*);
49   extern void doubleclick_dialog(String, String);
50   extern void ExecuteIconProgram(Widget, AppProgram *, XtPointer);
51   public String getfilename(String);
52   extern Boolean getIconType(String, String, XdtmList*);
53   private void GoUp(Widget, XButtonEvent*);
54   private int iconcmp(const void *, const void *);
55   extern void PopMenu(Widget, XButtonEvent*);
56   private void Refresh(Widget, XButtonEvent*);
57   private void SelectAll(Widget, XButtonEvent*);
58   public void selection_made(Widget, XtPointer, XtPointer);
59   extern void setCursor(Cursor);
60   extern void setscroll(Widget, float);
61 #else
62   public void changestate();
63   private void DoubleClick();
64   extern void doubleclick_dialog();
65   extern void ExecuteIconProgram();
66   public String getfilename();
67   extern Boolean getIconType();
68   private void GoUp();
69   private int iconcmp();
70   extern void PopMenu();
71   private void Refresh();
72   private void SelectAll();
73   public void selection_made();
74   extern void setCursor();
75   extern void setscroll();
76 #endif
77 
78 public Widget   directoryManager;
79 public String   cwd;	                   /* current working directory */
80 public Cardinal icon_list_size = 0;
81 public Cardinal icon_list_max_size = LISTSIZE;
82 public XdtmList **icon_list;		   /* List with icons and/or filenames */
83 public String   pwd_env_var;
84 
85 /* local copies of the menu panes which are to be made insensitive when
86  * no there is no current selection.
87  */
88 private Widget duplicatemenu, infomenu, trashmenu,
89                copymenu, movemenu, mapmenu;
90 
91 
92 /*****************************************************************************
93  *                       createDirectoryManagerWidgets                       *
94  *****************************************************************************/
createDirectoryManagerWidgets(view)95 public void createDirectoryManagerWidgets(view)
96 Widget view;
97 {
98   /* Create the directory manager widget
99    *
100    * - Takes the directoryManager's parent widget
101    */
102 
103   extern Icon_mode current_mode;
104   XtTranslations dirManTranslations;
105 
106   /* New actions for directoryManager */
107 
108   static XtActionsRec actions[] = {
109     {"DoubleClick", (XtActionProc)DoubleClick},
110     {"GoUp",        (XtActionProc)GoUp},
111     {"SelectAll",   (XtActionProc)SelectAll},
112     {"Refresh",     (XtActionProc)Refresh},
113     {"PopMenu",     (XtActionProc)PopMenu},
114     {NULL, (XtActionProc)NULL}
115   };
116 
117   /* New translations for directoryManager */
118   static char defaultTranslations[] =
119              "<Btn1Up>(2):     DoubleClick()\n\
120               <Key>u:          GoUp()\n\
121               <Key>a:          SelectAll()\n\
122 	      Ctrl<Key>L:      Refresh()\n\
123               <Btn3Down>:      Set() PopMenu()\n\
124               <Btn2Down>:      Set()";
125   /* on peut peut-etre ajouter Info avec Btn2Up ? */
126 
127   /* Set the initial mode depending on the value set in the application
128    * defaults. (current_mode.mode set previously to this value when
129    * creating widgets.
130    */
131 
132   directoryManager =
133     XtVaCreateManagedWidget(
134         "directoryManager",
135 	xedwListWidgetClass,
136 	view,
137 	    XtNshowIcons,      (current_mode.mode == Icons) ? True : False,
138 	    XtNrowSpacing,     (current_mode.mode != Icons) ? 5 : 2,
139 	    XtNforceColumns,   (current_mode.mode == Long) ? True : False,
140 	    XtNdefaultColumns, (current_mode.mode == Long) ? 1 : 2,
141 	    XtNfont,           app_data.dm_font,
142 	    XtNmSelections,    True,
143 	    NULL ) ;
144 
145   /* Add callbacks and translations */
146   XtAddCallback(directoryManager, XtNcallback,
147 		(XtCallbackProc)selection_made, (XtPointer)0);
148   XtAppAddActions(XtWidgetToApplicationContext(view),
149 		  actions, XtNumber(actions));
150   dirManTranslations = XtParseTranslationTable(defaultTranslations);
151   XtAugmentTranslations(directoryManager, dirManTranslations);
152 }
153 
154 
155 /*****************************************************************************
156  *                          splitPath                                        *
157  *****************************************************************************/
158 #if NeedFunctionPrototypes
splitPath(String fullname,String * basename,String * path)159 public void splitPath(String fullname, String *basename, String *path)
160 #else
161 public void splitPath(fullname, basename, path)
162      String fullname;
163      String *basename;
164      String *path;
165 #endif
166 {
167   /* split a fullname description into basename and path.
168    */
169 
170     int n, len = strlen(fullname);
171 
172     n = len - 1;
173     while ((n >= 0)  && (fullname[n] != '/')) n--;
174 
175     if (n < 0) /* no slash, it's a basename */
176     {
177 	*basename = XtNewString(fullname);
178 	*path = XtNewString("");
179 	return;
180     }
181     else /* fullname[n] is the last '/' in fullname */
182     {
183 	*path = (String)XtMalloc((n + 1) * sizeof(char));
184 	strncpy(*path, fullname, n);
185 	(*path)[n] = 0;
186 	*basename = XtNewString(&fullname[n + 1]);
187 	return;
188     }
189 }
190 
191 
192 /*****************************************************************************
193  *                     directoryManagerNewDirectory                          *
194  *****************************************************************************/
directoryManagerNewDirectory(newpath)195 public Boolean directoryManagerNewDirectory(newpath)
196 String newpath;
197 {
198   /* Change the contents of the directoryManager to that of the directory
199    * contained in the string newpath.
200    */
201 
202   extern Cursor    busy;
203   extern Widget    dirSelector;
204   extern Widget    directoryManagerView;
205 
206   XdtmList         temp;
207   DIR             *dirp;
208   struct dirent   *dp;
209   Cardinal         i = 0 ;
210   Boolean          result = False; /* Whether the change of directories succeeded */
211 
212   /* create a new one */
213   if ((dirp = opendir(newpath)) != NULL && chdir(newpath) == 0) {
214 
215     /* set cursor to busy */
216     setCursor(busy);
217 
218     /* Emacs likes the env var PWD to find out the current directory */
219     sprintf(pwd_env_var, "PWD=%s", newpath);
220 
221     if (putenv(pwd_env_var) != 0) {
222       fprintf(stderr, "xdtm: Can't allocate space for environment\n");
223       exit(2);
224     }
225 
226 
227     /* In the process of all this we lose our highlighted items, so
228      * let's dim the menu items to reflect this. */
229     changestate(False);
230 
231     /* Trash old list */
232     for(i=0; i < icon_list_size; i++) {
233       XtFree((char *)icon_list[i]->string);
234       XtFree((char *)icon_list[i]);
235     }
236 
237     /* Get icon type for each file */
238     i = 0;
239     while ((dp = readdir(dirp)) != NULL) {
240 
241       String basename = NULL, path = NULL;
242 
243       if (i == icon_list_max_size) {
244 	icon_list_max_size += LISTINCR;
245 	icon_list = (XdtmList**) XtRealloc((char *)icon_list,
246 					   sizeof(XdtmList*) *
247 					   icon_list_max_size);
248       }
249 
250       if (((strcmp(dp->d_name, ".") == 0) &&
251 	   (app_data.usedotspec == False)) ||
252 	  ((strcmp(dp->d_name, "..") == 0) &&
253 	   (app_data.usedotdotspec == False))) {
254 
255 	splitPath(newpath, &basename, &path);
256 	if (strcmp(dp->d_name, "..") == 0) {
257 	  String tmppath = path;
258 
259 	  XtFree(basename);
260 	  splitPath(tmppath, &basename, &path);
261 	  XtFree(tmppath);
262         }
263       } else {
264 	  basename = XtNewString(dp->d_name);
265 	  path = XtNewString(newpath);
266       }
267 
268       if (getIconType(basename, path, &temp)) {
269 	icon_list[i] = XtNew(XdtmList);
270 
271 	if (strcmp(dp->d_name, basename) != 0) {
272 	  /* This is either . or .. without their spec
273 	     replace basename by dp->d_name in temp.string */
274 	  int l, lbase = strlen(basename), ltemp = strlen(temp.string);
275 	  String ptr;
276 
277 	  /* in any case (icons, short or long listing) basename is
278 	     always last in string, point at it */
279           ptr = temp.string + (ltemp - lbase);
280 
281 	  /* copy dp->d_name at ptr */
282 	  strcpy(ptr, dp->d_name);
283 
284 	  /* adjust string length */
285 	  if ((l = strlen(dp->d_name) - lbase) != 0)
286 	    temp.string = XtRealloc(temp.string, ltemp + l + 1);
287         }
288 
289 	icon_list[i]->string    = temp.string;
290 	icon_list[i]->isdir     = temp.isdir;
291 	icon_list[i]->icon      = temp.icon;
292 	icon_list[i]->mask      = temp.mask;
293 	icon_list[i]->user_data = temp.user_data;
294 	i++;
295       }
296 
297       XtFree(basename);
298       XtFree(path);
299 
300     }
301     icon_list[i] = NULL;	/* NULL terminated */
302     icon_list_size = i;
303 
304     /* Sort the list */
305     qsort((char*)icon_list, icon_list_size, sizeof(icon_list[0]), iconcmp);
306 
307     /* Change the contents of the directory Manager */
308     XedwListChange(directoryManager, (XedwList**) icon_list, icon_list_size,
309 		   0, True);
310 
311     if (app_data.scrollonexit == True)
312       /* Set the scrollbar of the viewport to the top */
313       setscroll(directoryManagerView, 0.0);
314 
315     closedir(dirp);
316     result = True;
317 
318     /* Change entry in the directory selector */
319 
320     XtVaSetValues(
321         dirSelector,
322 	XtNstring, newpath,
323 	NULL ) ;
324 
325     /* reset cursor */
326     setCursor((Cursor)NULL);
327   } else
328     alert_dialog("Error: invalid directory!", newpath, NULL);
329 
330   return(result);
331 }
332 
333 /*****************************************************************************
334  *                                iconcmp                                    *
335  *****************************************************************************/
336 #if NeedFunctionPrototypes
iconcmp(const void * p1,const void * p2)337 private int iconcmp(const void *p1, const void *p2)
338 #else
339 private int iconcmp(p1, p2)
340 void *p1;
341 void *p2;
342 #endif
343 {
344   XdtmList **ip1 = (XdtmList **)p1;
345   XdtmList **ip2 = (XdtmList **)p2;
346 
347   /* compare the strings of 2 XdtmList's
348    * If isdir=True then put in front, otherwise put in order
349    */
350     if (app_data.dirfirst == True)
351     {
352 	if ((*ip1)->isdir == True) {
353 	    if ((*ip2)->isdir == True) {
354 		return (strcmp(getfilename((*ip1)->string),
355 			       getfilename((*ip2)->string)));
356 	    } else {
357 		/* The second element is NOT a directory */
358 		return(-1);
359 	    }
360 	} else {
361 	    /* First element is a file */
362 	    if ((*ip2)->isdir == True) {
363 		/* Second element is a directory */
364 		return(1);
365 	    } else {
366 		/* Both elements are files */
367 		return (strcmp(getfilename((*ip1)->string),
368 			       getfilename((*ip2)->string)));
369 	    }
370 	}
371     } else return (strcmp(getfilename((*ip1)->string),
372 			  getfilename((*ip2)->string)));
373 }
374 
375 /*****************************************************************************
376  *                              initDirectoryManager                         *
377  *****************************************************************************/
initDirectoryManager()378 public void initDirectoryManager()
379 {
380   /* Get the menubar pane widgets, create the initial icon_list, find
381    * out what the current directory is.
382    */
383 
384   extern Boolean buttonSensitive;
385   extern Widget  menuBar;
386   char           tmpcwd[MAXPATHLEN];
387 
388   /* Initialise the icon list */
389   icon_list = (XdtmList**) XtMalloc(sizeof(XdtmList*) * LISTSIZE);
390 
391   /* Set the starting directory */
392 #ifdef USE_CWD
393   if (getcwd(tmpcwd, MAXPATHLEN) != NULL)
394 #else
395   if ((char *)getwd(tmpcwd) != (char *)NULL)
396 #endif
397     cwd = XtNewString(tmpcwd);
398   else
399     if ((cwd = (char*) getenv("HOME")) == NULL)
400       cwd = XtNewString("/");
401     else
402       cwd = XtNewString(cwd);
403 
404   /* Get the PWD entry from the environment */
405 
406   pwd_env_var = XtMalloc(sizeof(char)*255);
407 
408   sprintf(pwd_env_var, "PWD=%s", cwd);
409 
410   if (putenv(pwd_env_var) != 0) {
411     fprintf(stderr, "xdtm: Can't allocate space for environment\n");
412     exit(2);
413   }
414 
415   /* Get the id's of the menu widgets which are to be toggled with the
416    * buttons. Note: This relies on the menus being created first, which
417    * they are.
418    */
419   if ((duplicatemenu =
420        XtNameToWidget(menuBar, "fileMenuButton.fileMenu.duplicate")) == NULL) {
421     fprintf(stderr, "Directorymanager: Can't find duplicate menu widget\n");
422     exit(2);
423   }
424   if ((infomenu =
425        XtNameToWidget(menuBar, "fileMenuButton.fileMenu.info")) == NULL) {
426     fprintf(stderr, "Directorymanager: Can't find info menu widget\n");
427     exit(2);
428   }
429   if ((trashmenu   =
430        XtNameToWidget(menuBar, "fileMenuButton.fileMenu.trash")) == NULL) {
431     fprintf(stderr, "Directorymanager: Can't find trash menu widget\n");
432     exit(2);
433   }
434   if ((copymenu    =
435        XtNameToWidget(menuBar, "fileMenuButton.fileMenu.copy")) == NULL) {
436     fprintf(stderr, "Directorymanager: Can't find copy menu widget\n");
437     exit(2);
438   }
439   if ((movemenu    =
440        XtNameToWidget(menuBar, "fileMenuButton.fileMenu.move")) == NULL) {
441     fprintf(stderr, "Directorymanager: Can't find move menu widget\n");
442     exit(2);
443   }
444   if ((mapmenu     =
445        XtNameToWidget(menuBar,
446 		      "selectionMenuButton.selectionMenu.map")) == NULL) {
447     fprintf(stderr, "Directorymanager: Can't find map menu widget\n");
448     exit(2);
449   }
450 
451   /* Add a passive grab to be able to popup spring loaded menu correctly */
452   XGrabButton(XtDisplay(directoryManager), AnyButton, AnyModifier,
453 	      XtWindow(directoryManager), TRUE,
454 	      ButtonPressMask|ButtonReleaseMask,
455 	      GrabModeAsync, GrabModeAsync, None, None );
456 
457   (void) directoryManagerNewDirectory(cwd);
458   buttonSensitive = True;
459   changestate(False); 	   /* Insure that menus are insensitive */
460 }
461 
462 /*****************************************************************************
463  *                              selection_made                               *
464  *****************************************************************************/
465 /*ARGSUSED*/
selection_made(w,client_data,call_data)466 public void selection_made(w, client_data, call_data)
467 Widget w ;
468 XtPointer client_data ;
469 XtPointer call_data ;
470 {
471   /* Someone has either selected or deselected an item.
472    * If there's nothing selected then buttons are changed to
473    * not sensitive.
474    */
475 
476   extern Boolean buttonSensitive;
477 
478   if (XedwListSelection(w) != buttonSensitive)
479     if (buttonSensitive == False) {
480       changestate(True);
481     } else {
482       changestate(False);
483     }
484 }
485 
486 /*****************************************************************************
487  *                              DoubleClick                                  *
488  *****************************************************************************/
489 /*ARGSUSED*/
DoubleClick(w,event)490 private void DoubleClick(w, event)
491 Widget w;
492 XButtonEvent *event;
493 {
494   /* If the file is a directory, then change to that directory -
495    * if the file has an opt associated with it then run that program
496    * else show the file info.
497    */
498 
499   extern Icon_mode current_mode;
500 
501   struct stat           filestatus;
502   String                fullname, filename, temp;
503   XedwListReturnStruct *highlighted;
504   Cardinal              index;
505   AppProgram           *opt_pgm;
506 
507   selection_made(w, (XtPointer)0, (XtPointer)0);
508   highlighted = XedwListShowCurrent(w);
509 
510   if (highlighted->xedwList_index != XDTM_LIST_NONE) {
511     index = highlighted->xedwList_index;
512     if ((current_mode.mode == Short) /* No userdefinable ops in Short mode */
513 	|| (icon_list[index] == NULL) || (icon_list[index]->user_data == NULL))
514       opt_pgm = NULL;
515     else
516       opt_pgm = ((iconOps *)(icon_list[index]->user_data))->cmd;
517     filename = getfilename(highlighted->string);
518     fullname =  (String) XtMalloc((strlen(filename)+strlen(cwd)+2) *
519 				  sizeof(char));
520     strcpy(fullname, cwd);
521     if (strcmp(cwd, "/") != 0)
522       strcat(fullname, "/");
523     strcat(fullname, filename);
524 
525     /* Use normal stat.. follows symbolic links.. can use on SYSV */
526     if (stat(fullname, &filestatus) == -1) {
527       alert_dialog("Sorry, that file does", "not really exist!!", "Cancel");
528     } else {
529       if ((filestatus.st_mode & S_IFMT) == S_IFDIR) {
530 
531 	/* The file is a directory */
532 
533 	if (strcmp(filename, "..") == 0) {
534 	  /* Go up one level */
535 	  strcpy(fullname, cwd);
536 	  if ((temp = (char*) strrchr(fullname, '/')) == NULL)
537 	    fprintf(stderr, "xdtm: impossible error (dirman.c)\n");
538 	  if (temp == fullname)
539 	    *(temp+1) = '\0';
540 	  else
541 	    *temp = '\0';
542 	}
543 	if (strcmp(filename, ".") == 0) {
544 	  /* Refresh directory contents */
545 	  XtFree((char *)fullname);
546 	  fullname=XtNewString(cwd);
547 	}
548 	if (directoryManagerNewDirectory(fullname) == True) {
549 	  /* Normal directory - change to it */
550 	  XtFree((char *)cwd);
551 	  cwd=fullname;
552 	  changestate(False);
553 	}
554       } else {
555 	if (opt_pgm) {
556 	  /* There's a program associated with this type of file */
557 	  ExecuteIconProgram(NULL, opt_pgm, NULL);
558 	} else
559 	  if ((filestatus.st_mode & S_IFMT) == S_IFREG) {
560 	    /* Display dialog box to ask whether to display file */
561 	    doubleclick_dialog(filename, cwd);
562 	  } else alert_dialog("Cannot double click",
563 			      "on such file!", NULL);
564 	XtFree((char *)fullname);
565       }
566     }
567   }
568   XedwListFreeCurrent(highlighted);
569 }
570 
571 /*****************************************************************************
572  *                                     GoUp                                  *
573  *****************************************************************************/
574 /*ARGSUSED*/
GoUp(w,event)575 private void GoUp(w, event)
576 Widget w;
577 XButtonEvent *event;
578 {
579   /* Change to the directory immediately above the current one,
580    * does this by highlighting the .. directory, then calling
581    * DoubleClick to change to the highlighted directory.
582    * I used this longwinded approach because it showed on screen
583    * what was actually happening.
584    */
585 
586   register int i = 0 ;
587 
588   /* Find entry with .. */
589 
590   for (; i < icon_list_size &&
591        (strcmp(getfilename(icon_list[i]->string), "..") != 0); i++);
592 
593   XedwListUnhighlight(w, XedwAll);
594   XedwListHighlight(w, i);  /* Call XedwListHighlight with item number */
595   DoubleClick(w, (XButtonEvent*) NULL);  /* Call double click */
596 }
597 
598 /*****************************************************************************
599  *                                 SelectAll                                 *
600  *****************************************************************************/
601 /*ARGSUSED*/
SelectAll(w,event)602 private void SelectAll(w, event)
603 Widget w;
604 XButtonEvent *event;
605 {
606   /* Select All the files in the current directory except for . and .. */
607 
608   extern Mode    mode;
609   extern Cursor  busy;
610 
611   register int i;
612 
613   /* Don't do it if in copy or move mode */
614   if (mode == NormalMode) {
615     setCursor(busy);
616     XedwListHighlight(w, XedwAll);
617 
618     /* unhighlight . and .. */
619     for (i=0; i < icon_list_size &&
620 	 (strcmp(getfilename(icon_list[i]->string), ".") != 0); i++);
621     if (i < icon_list_size) XedwListUnhighlight(w, i);
622     for (i= (i < icon_list_size ? i : 0); i < icon_list_size &&
623 	 (strcmp(getfilename(icon_list[i]->string), "..") != 0); i++);
624     if (i < icon_list_size) XedwListUnhighlight(w, i);
625     setCursor((Cursor)NULL);
626   } else alert_dialog("Cannot select all", "while trying to Copy/Move", NULL);
627 
628 
629   /* do buttons */
630   if (icon_list_size > 2) {
631     changestate(True);
632   }
633 }
634 
635 /*****************************************************************************
636  *                                Refresh                                    *
637  *****************************************************************************/
638 /*ARGSUSED*/
Refresh(w,event)639 private void Refresh(w, event)
640 Widget w;
641 XButtonEvent *event;
642 {
643   /* Refresh the current directory contents to the actual contents. */
644 
645   directoryManagerNewDirectory(cwd);
646 }
647 
648 /*****************************************************************************
649  *                               changestate                                 *
650  *****************************************************************************/
651 #if NeedFunctionPrototypes
changestate(Boolean new_state)652 public void changestate(Boolean new_state)
653 #else
654 public void changestate(new_state)
655 Boolean new_state;
656 #endif
657 {
658   /* Toggle the sensitivity of all the widgets which may not be used
659    * when no files are highlighted.
660    *
661    * - Takes the new state for widgets.
662    */
663 
664   extern Boolean buttonSensitive;
665   extern Widget  trashButton, copyButton, moveButton;
666   extern Mode    mode;
667 
668   if (buttonSensitive == True) {
669     if (mode == MoveMode) {
670       /* Turn off Trash and Copy */
671       XtSetSensitive(copyButton,    False);
672       XtSetSensitive(trashButton,   False);
673       XtSetSensitive(copymenu,      False);
674       XtSetSensitive(trashmenu,     False);
675       XtSetSensitive(mapmenu,       False);
676       XtSetSensitive(duplicatemenu, False);
677       XtSetSensitive(infomenu,      False);
678       buttonSensitive = False;
679     } else if (mode == CopyMode) {
680       /* Turn off Trash and Move */
681       XtSetSensitive(moveButton,    False);
682       XtSetSensitive(trashButton,   False);
683       XtSetSensitive(movemenu,      False);
684       XtSetSensitive(trashmenu,     False);
685       XtSetSensitive(mapmenu,       False);
686       XtSetSensitive(duplicatemenu, False);
687       XtSetSensitive(infomenu,      False);
688       buttonSensitive = False;
689     } else if (new_state == False) {
690       /* Turn off All */
691       XtSetSensitive(moveButton,    False);
692       XtSetSensitive(copyButton,    False);
693       XtSetSensitive(trashButton,   False);
694       XtSetSensitive(copymenu,      False);
695       XtSetSensitive(movemenu,      False);
696       XtSetSensitive(trashmenu,     False);
697       XtSetSensitive(mapmenu,       False);
698       XtSetSensitive(duplicatemenu, False);
699       XtSetSensitive(infomenu,      False);
700       buttonSensitive = False;
701     }
702   } else {
703     /* buttonSensitive == False */
704 
705     /* If in MoveMode or CopyMode, then everything is set anyway */
706     if (mode == NormalMode && new_state == True) {
707       /* Set all to True */
708       XtSetSensitive(trashButton,   True);
709       XtSetSensitive(moveButton,    True);
710       XtSetSensitive(copyButton,    True);
711       XtSetSensitive(trashmenu,     True);
712       XtSetSensitive(movemenu,      True);
713       XtSetSensitive(copymenu,      True);
714       XtSetSensitive(duplicatemenu, True);
715       XtSetSensitive(mapmenu,       True);
716       XtSetSensitive(infomenu,      True);
717       buttonSensitive = True;
718     }
719   }
720 }
721 
722 /*****************************************************************************
723  *                              getfilename                                  *
724  *****************************************************************************/
getfilename(s)725 public String getfilename(s)
726 String s;
727 {
728   /* If in Long Listing mode this function returns the filename part
729    * of the string used in the directory list. If not in Long Listing
730    * then return the string unmolested.
731    * NOTE that the string returned when in Long Listing mode should not be
732    * freed as it was never allocated.
733    * NOTE also that doing string = getfilename(string) should avoided.
734    */
735   extern Icon_mode current_mode;
736 
737   if (current_mode.mode == Long && (strlen(s) > current_mode.length))
738     return (s+current_mode.length);
739   else
740     return (s);
741 }
742