Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtfile / FileMgr.c
1 /* $TOG: FileMgr.c /main/19 1998/01/27 12:19:54 mgreess $ */
2 /************************************<+>*************************************
3  ****************************************************************************
4  *
5  *   FILE:           FileMgr.c
6  *
7  *   COMPONENT_NAME: Desktop File Manager (dtfile)
8  *
9  *   Description:    Source file for the File Manager dialog.
10  *
11  *   FUNCTIONS: BranchListToString
12  *              CheckMoveType
13  *              Close
14  *              CountDirectories
15  *              Create
16  *              CreateFmPopup
17  *              Destroy
18  *              DirTreeExpand
19  *              DoTheMove
20  *              DropOnFileWindow
21  *              DropOnGadget
22  *              DropOnObject
23  *              DropOnPrimaryHotspot
24  *              FMInput
25  *              ActivateClist
26  *              FileMgrBuildDirectories
27  *              FileMgrPropagateSettings
28  *              FileMgrRedisplayFiles
29  *              FileMgrReread
30  *              FreeDirectoryData
31  *              FreeDirectorySet
32  *              FreePositionInfo
33  *              FreeValues
34  *              GetDefaultValues
35  *              GetFileData
36  *              GetPixmapData
37  *              GetResourceValues
38  *              GetSessionDir
39  *              GetTopInfo
40  *              InheritPositionInfo
41  *              IsShown
42  *              LoadPositionInfo
43  *              MakeDirectorySets
44  *              MoveCancelCB
45  *              MoveOkCB
46  *              MsgTimerEvent
47  *              NewDirectorySet
48  *              PositionFlagSet
49  *              PositioningEnabledInView
50  *              ProcessDropOnFileWindow
51  *              ProcessDropOnObject
52  *              QueryBranchList
53  *              ReadTreeDirectory
54  *              SavePositionInfo
55  *              SelectVisible
56  *              SelectionListToString
57  *              SetDisplayedRecur
58  *              SetFocus
59  *              SetIconAttributes
60  *              SetPWD
61  *              SetSpecialMsg
62  *              SetValues
63  *              ShowChangeDirField
64  *              ShowNewDirectory
65  *              StringToBranchList
66  *              StringToSelectionList
67  *              SystemClose
68  *              UpdateBranchList
69  *              UpdateBranchState
70  *              UpdateHeaders
71  *              UpdateStatusLine
72  *              WriteResourceValues
73  *
74  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
75  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
76  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
77  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
78  *
79  ****************************************************************************
80  ************************************<+>*************************************/
81
82 #include <stdio.h>
83 #include <sys/types.h>
84 #include <pwd.h>
85 #include <string.h>
86 #include <sys/stat.h>
87
88 #include <Xm/XmP.h>
89 #include <Xm/CascadeB.h>
90 #include <Xm/DrawingA.h>
91 #include <Xm/DrawingAP.h>
92 #include <Xm/DrawnB.h>
93 #include <Xm/Frame.h>
94 #include <Xm/Form.h>
95 #include <Xm/LabelG.h>
96 #include <Xm/MainW.h>
97 #include <Xm/PushBG.h>
98 #include <Xm/RowColumn.h>
99 #include <Xm/ScrolledW.h>
100 #include <Xm/SeparatoG.h>
101 #include <Xm/Text.h>
102 #include <Xm/TextF.h>
103 #include <Xm/ToggleBG.h>
104 #include <Xm/VendorSEP.h>
105 #include <Dt/Icon.h>
106 #include <Dt/IconP.h>
107 #include <Dt/IconFile.h>
108
109 #include <X11/ShellP.h>
110 #include <X11/Shell.h>
111 #include <X11/Xatom.h>
112 #include <X11/keysymdef.h>
113
114 #include <Xm/Protocols.h>
115
116 #include <Dt/Action.h>
117 #include <Dt/DtP.h>                     /* required for DtDirPaths type */
118 #include <Dt/Connect.h>                 /* required for DtMakeConnect... */
119 #include <Dt/FileM.h>
120 #include <Dt/HourGlass.h>
121 #include <Dt/DtNlUtils.h>
122 #include <Dt/Dts.h>
123
124 #include <Xm/DragIcon.h>
125 #include <Xm/DragC.h>
126 #include <Dt/Dnd.h>
127
128 #include <Tt/tttk.h>
129
130 #include "Encaps.h"
131 #include "SharedProcs.h"
132 #include "Help.h"
133 #include "FileMgr.h"
134 #include "Desktop.h"
135 #include "Main.h"
136 #include "Common.h"
137 #include "Filter.h"
138 #include "Find.h"
139 #include "ChangeDir.h"
140 #include "ModAttr.h"
141 #include "Prefs.h"
142 #include "SharedMsgs.h"
143 #include "IconicPath.h"
144
145
146 /*  Dialog classes installed by Main.c  */
147
148 extern int file_mgr_dialog;
149 extern int change_dir_dialog;
150 extern int preferences_dialog;
151 extern int filter_dialog;
152 extern int find_dialog;
153 extern int mod_attr_dialog;
154
155 extern int ReadInFiletypes(
156                     FilterData *filter_data) ;
157
158 /* global varibles used within this function when we have to
159  * put up a _DtMessage dialog
160  */
161 static int          global_file_count;
162 static char         **global_file_set;
163 static char         **global_host_set;
164 static FileMgrData  *fm;
165 static int          view_type;
166 static FileViewData *fv;
167 static DesktopRec   *dtWindow;
168 static unsigned int mod;
169 static DirectorySet *dd;
170 static Pixmap       change_view_pixmap = XmUNSPECIFIED_PIXMAP;
171
172 /* Global variables used in Command.c, FileMgr.c and FileOp.c */
173 int     G_dropx, G_dropy;
174
175 /********    Static Function Declarations    ********/
176
177 static XmFontListEntry FontListDefaultEntry(
178                         XmFontList font_list) ;
179 static void Create(
180                         Display *display,
181                         Widget parent,
182                         Widget *return_widget,
183                         XtPointer *dialog) ;
184 static XtPointer GetDefaultValues( void ) ;
185 static XtPointer GetResourceValues(
186                         XrmDatabase data_base,
187                         char **name_list) ;
188 static void SetValues(
189                         FileMgrRec *file_mgr_rec,
190                         FileMgrData *file_mgr_data) ;
191 static void WriteResourceValues(
192                         DialogData *values,
193                         int fd,
194                         char **name_list) ;
195 static void FreeValues(
196                         FileMgrData *file_mgr_data) ;
197 static void Destroy(
198                         XtPointer recordPtr) ;
199 static void GetSessionDir(
200                         FileMgrData *file_mgr_data) ;
201 static void BranchListToString(
202                         int fd,
203                         char ***value,
204                         char *out_buf) ;
205 static void SelectionListToString(
206                         int fd,
207                         FileViewData ***value,
208                         char *out_buf) ;
209 static Boolean StringToBranchList(
210                         Display *display,
211                         XrmValue *args,
212                         Cardinal num_args,
213                         XrmValue *from_val,
214                         XrmValue *to_val,
215                         XtPointer *converter_data );
216 static void StringToSelectionList(
217                         XrmValue *args,
218                         Cardinal num_args,
219                         XrmValue *from_val,
220                         XrmValue *to_val) ;
221 static void GetFileData(
222                         FileMgrData *file_mgr_data,
223                         Boolean valid,
224                         char ** branch_list) ;
225 static FileViewData * GetTopInfo(
226                         FileMgrData *file_mgr_data,
227                         char *host_name,
228                         char *directory_name,
229                         char **branch_list) ;
230 static void CountDirectories(
231                         FileViewData *ip,
232                         int *np) ;
233 static DirectorySet * NewDirectorySet(
234                         char *name,
235                         FileViewData *ip,
236                         FileMgrData *file_mgr_data) ;
237 static void MakeDirectorySets(
238                         FileMgrData *file_mgr_data,
239                         FileViewData *ip,
240                         DirectorySet **directory_set,
241                         int *index) ;
242 static void ReadTreeDirectory(
243                         Widget w,
244                         char *host_name,
245                         char *directory_name,
246                         FileMgrData *file_mgr_data,
247                         char **branch_list,
248                         DirectorySet ***directory_set,
249                         int *directory_count) ;
250 static Bool IsShown(    FileMgrData *fmd,
251                         FileViewData *ip);
252 static void SetDisplayedRecur(
253                         FileMgrData *fmd,
254                         FileViewData *dp,
255                         int level) ;
256 static void SelectVisible (
257                         FileMgrData *file_mgr_data) ;
258 static void FreeDirectorySet(
259                         DirectorySet ** directory_set,
260                         int directory_count) ;
261 static void FreeDirectoryData(
262                         FileMgrData *file_mgr_data) ;
263 static void SystemClose(
264                         Widget w,
265                         XtPointer data) ;
266 static void SetIconAttributes(
267                         FileMgrRec *file_mgr_rec,
268                         FileMgrData *file_mgr_data,
269                         char *directory_name) ;
270 static void SetFocus (
271                         FileMgrRec  * file_mgr_rec,
272                         FileMgrData * file_mgr_data) ;
273 static void MoveOkCB(
274                         Widget w,
275                         XtPointer client_data,
276                         XtPointer call_data ) ;
277 static void MoveCancelCB(
278                         Widget w,
279                         XtPointer client_data,
280                         XtPointer call_data ) ;
281 static void CreateFmPopup (
282                         Widget w );
283 static void DoTheMove(
284                         int type);
285 static void FMInput(
286                         Widget wid,
287                         XEvent *event,
288                         String *params,
289                         Cardinal *num_params );
290 static void ActivateClist(
291                         Widget wid,
292                         XEvent *event,
293                         String *params,
294                         Cardinal *num_params );
295
296 /********    End Static Function Declarations    ********/
297
298
299 #define TREE_DASH_WIDTH 1
300
301 /*  Resource read and write function  */
302
303 static char * FILEMGR = "FileMgr";
304
305
306 /* Action for osfMenu */
307 static XtActionsRec FMAction[] =
308 { { "FMInput", FMInput},
309   { "ActivateClist", ActivateClist}
310 };
311
312
313 /*  The resources set for the FileMgr dialog  */
314
315 static DialogResource resources[] =
316 {
317    { "show_type", SHOW_TYPE, sizeof(unsigned char),
318       XtOffset(FileMgrDataPtr, show_type),
319       (XtPointer) SINGLE_DIRECTORY, ShowTypeToString },
320
321    { "tree_files", TREE_FILES, sizeof(unsigned char),
322       XtOffset(FileMgrDataPtr, tree_files),
323       (XtPointer) TREE_FILES_NEVER, TreeFilesToString },
324
325    { "view_single", VIEW, sizeof(unsigned char),
326       XtOffset(FileMgrDataPtr, view_single),
327       (XtPointer) BY_NAME_AND_ICON, ViewToString },
328
329    { "view_tree", VIEW, sizeof(unsigned char),
330       XtOffset(FileMgrDataPtr, view_tree),
331       (XtPointer) BY_NAME_AND_SMALL_ICON, ViewToString },
332
333    { "order", ORDER, sizeof(unsigned char),
334       XtOffset(FileMgrDataPtr, order),
335       (XtPointer) ORDER_BY_ALPHABETICAL, OrderToString },
336
337    { "direction", DIRECTION_RESRC, sizeof(unsigned char),
338       XtOffset(FileMgrDataPtr, direction),
339       (XtPointer) DIRECTION_ASCENDING, DirectionToString },
340
341    { "positionEnabled", RANDOM, sizeof(unsigned char),
342       XtOffset(FileMgrDataPtr, positionEnabled),
343       (XtPointer) RANDOM_OFF, RandomToString },
344
345    { "host", XmRString, sizeof(String),
346       XtOffset(FileMgrDataPtr, host), (XtPointer) NULL, _DtStringToString },
347
348    { "current_directory", XmRString, sizeof(String),
349       XtOffset(FileMgrDataPtr, current_directory),
350       (XtPointer) "~", _DtStringToString },
351
352    { "branch_list", BRANCH_LIST, sizeof(XtPointer),
353       XtOffset(FileMgrDataPtr, branch_list),
354       (XtPointer) NULL, BranchListToString },
355
356    { "restricted_directory", XmRString, sizeof(String),
357       XtOffset(FileMgrDataPtr, restricted_directory),
358       (XtPointer) NULL, _DtStringToString },
359
360    { "title", XmRString, sizeof(String),
361       XtOffset(FileMgrDataPtr, title),
362       (XtPointer) NULL, _DtStringToString },
363
364    { "helpVol", XmRString, sizeof(String),
365       XtOffset(FileMgrDataPtr, helpVol),
366       (XtPointer) NULL, _DtStringToString },
367
368    { "selection_list", SELECTION_LIST, sizeof(XtPointer),
369       XtOffset(FileMgrDataPtr, selection_list),
370       (XtPointer) NULL, SelectionListToString },
371
372    { "show_iconic_path", XmRBoolean, sizeof(Boolean),
373       XtOffset(FileMgrDataPtr, show_iconic_path),
374       (XtPointer) True, _DtBooleanToString },
375
376    { "show_current_directory", XmRBoolean, sizeof(Boolean),
377       XtOffset(FileMgrDataPtr, show_current_dir),
378       (XtPointer) False, _DtBooleanToString },
379
380    { "show_status_line", XmRBoolean, sizeof(Boolean),
381       XtOffset(FileMgrDataPtr, show_status_line),
382       (XtPointer) True, _DtBooleanToString },
383
384    { "fast_cd_enabled", XmRBoolean, sizeof(Boolean),
385       XtOffset(FileMgrDataPtr, fast_cd_enabled),
386       (XtPointer) False, _DtBooleanToString },
387
388    { "toolbox", XmRBoolean, sizeof(Boolean),
389       XtOffset(FileMgrDataPtr, toolbox),
390       (XtPointer) False, _DtBooleanToString },
391
392    { "show_hid_enabled", XmRBoolean, sizeof(Boolean),
393       XtOffset(FileMgrDataPtr, show_hid_enabled),
394       (XtPointer) False, _DtBooleanToString },
395
396    { "secondaryHelpDialogCount", XmRInt, sizeof(int),
397       XtOffset(FileMgrDataPtr, secondaryHelpDialogCount),
398       (XtPointer) 0, _DtIntToString },
399
400    { "attr_dialog_count", XmRInt, sizeof(int),
401       XtOffset(FileMgrDataPtr, attr_dialog_count),
402       (XtPointer) 0, _DtIntToString },
403
404    { "trashcan", XmRBoolean, sizeof(Boolean),
405      XtOffset(FileMgrDataPtr, IsTrashCan),
406      (XtPointer) False, _DtBooleanToString },
407 };
408
409
410 /*
411  *  The Dialog Class structure.
412  */
413
414 static DialogClass fileMgrClassRec =
415 {
416    resources,
417    XtNumber(resources),
418    Create,
419    (DialogInstallChangeProc) NULL,
420    (DialogInstallCloseProc) NULL,
421    Destroy,
422    (DialogGetValuesProc) NULL,
423    GetDefaultValues,
424    GetResourceValues,
425    (DialogSetValuesProc) SetValues,
426    WriteResourceValues,
427    (DialogFreeValuesProc) FreeValues,
428    NULL,
429    (DialogSetFocusProc) SetFocus,
430 };
431
432 DialogClass * fileMgrClass = (DialogClass *) &fileMgrClassRec;
433
434 #ifdef _CHECK_FOR_SPACES
435 char translations_sp_esc[] = "<Key>space:Space()\n\
436                              <Key>osfCancel:EscapeFM()";
437 char translations_space[] = "<Key>space:Space()";
438 #else
439 char translations_sp_esc[] = "Ctrl<Key>space:Space()\n\
440                              <Key>osfCancel:EscapeFM()";
441 char translations_space[] = "Ctrl<Key>space:Space()";
442 #endif
443 char translations_escape[] = "<Key>osfCancel:EscapeFM()";
444
445 #define DOUBLE_CLICK_DRAG
446 #ifndef DOUBLE_CLICK_DRAG
447 char translations_da[] = "\
448 <Key>osfCancel:DrawingAreaInput() ManagerGadgetSelect()\n\
449 <Key>plus:DrawingAreaInput() ManagerGadgetSelect()\n\
450 <Key>minus:DrawingAreaInput() ManagerGadgetSelect()\n\
451 <Btn2Down>:DrawingAreaInput() ManagerGadgetArm()\n\
452 <Btn2Down>,<Btn2Up>:DrawingAreaInput() ManagerGadgetActivate()\n\
453 <Btn2Up>:DrawingAreaInput() ManagerGadgetActivate()\n\
454 <Btn2Down>(2+):DrawingAreaInput() ManagerGadgetMultiArm()\n\
455 <Btn2Up>(2+):DrawingAreaInput() ManagerGadgetMultiActivate()";
456
457 #else
458
459 extern _XmConst char _XmDrawingA_traversalTranslations[];
460
461 char translations_da[] = "\
462 <BtnMotion>:ManagerGadgetButtonMotion()\n\
463 <Btn1Down>:DrawingAreaInput() ManagerGadgetArm()\n\
464 <Btn1Down>,<Btn1Up>:DrawingAreaInput() ManagerGadgetActivate()\n\
465 <Btn1Up>:DrawingAreaInput() ManagerGadgetActivate()\n\
466 <Btn1Down>(2+):DrawingAreaInput() ManagerGadgetMultiArm() \
467                ManagerGadgetMultiActivate()\n\
468 <Btn2Down>:DrawingAreaInput() ManagerGadgetArm()\n\
469 <Btn2Down>,<Btn2Up>:DrawingAreaInput() ManagerGadgetActivate()\n\
470 <Btn2Up>:DrawingAreaInput() ManagerGadgetActivate()\n\
471 <BtnDown>:DrawingAreaInput()\n\
472 <BtnUp>:DrawingAreaInput()\n\
473 :<Key>osfActivate:DrawingAreaInput() ManagerParentActivate()\n\
474 :<Key>osfCancel:DrawingAreaInput() ManagerGadgetSelect()\n\
475 :<Key>osfHelp:DrawingAreaInput() ManagerGadgetHelp()\n\
476 :<Key>osfSelect:DrawingAreaInput() ManagerGadgetSelect()\n\
477 :<Key>osfDelete:DrawingAreaInput() ManagerGadgetSelect()\n\
478 :<Key>osfMenu:FMInput(@)\n\
479 :<Key>osfEndLine:FMInput(@)\n\
480 <Key>osfBeginLine:FMInput(@)\n\
481 :<Key>osfPageDown:FMInput(@)\n\
482 :<Key>osfPageUp:FMInput(@)\n\
483 :<Key>F1:DrawingAreaInput() ManagerGadgetHelp()\n\
484 s c a <Key>c: ActivateClist(@)\n\
485 ~s ~m ~a <Key>Return:DrawingAreaInput() ManagerParentActivate()\n\
486 <Key>Return:DrawingAreaInput() ManagerGadgetSelect()\n\
487 <Key>space:DrawingAreaInput() ManagerGadgetSelect()\n\
488 :<Key>plus:DrawingAreaInput() ManagerGadgetSelect()\n\
489 :<Key>minus:DrawingAreaInput() ManagerGadgetSelect()\n\
490 <KeyDown>:DrawingAreaInput() ManagerGadgetKeyInput()\n\
491 <KeyUp>:DrawingAreaInput()";
492 #endif /* DOUBLE_CLICK_DRAG */
493
494 /************************************************************************
495  *
496  *  FontListDefaultEntry
497  *
498  *      Return the first entry in the font list with the tag
499  *      XmFONTLIST_DEFAULT_TAG.  If there isn't one, just return the
500  *      first entry in the font list.
501  *
502  ************************************************************************/
503
504 static XmFontListEntry
505 FontListDefaultEntry(XmFontList font_list)
506 {
507     XmFontContext context;
508     XmFontListEntry first_entry, entry;
509     char *tag;
510
511     if (!XmFontListInitFontContext(&context, font_list))
512         return NULL;
513
514     entry = first_entry = XmFontListNextEntry(context);
515     while (entry) {
516         tag = XmFontListEntryGetTag(entry);
517         if (!strcmp(XmFONTLIST_DEFAULT_TAG, tag)) {
518             XtFree(tag);
519             break;
520         }
521
522         XtFree(tag);
523         entry = XmFontListNextEntry(context);
524     }
525
526     XmFontListFreeFontContext(context);
527
528     return entry ? entry : first_entry;
529 }
530
531 /************************************************************************
532  *
533  *  Create
534  *
535  ************************************************************************/
536
537 static void
538 Create(
539         Display *display,
540         Widget parent,
541         Widget *return_widget,
542         XtPointer *dialog )
543 {
544    static Boolean first = True;
545    FileMgrRec * file_mgr_rec;
546    Widget shell;
547    Widget main;
548    Widget menu;
549    Widget header_frame;
550    Widget header_separator;
551    Widget iconic_path_da;
552    Widget current_directory_frame;
553    Widget current_directory_drop;
554    Widget current_directory_icon;
555    Widget directory_list_form;
556    Widget work_frame;
557    Widget status_form;
558    Widget status_separator;
559    Widget status_line;
560
561    Pixel background;
562    Pixel foreground;
563    Pixel top_shadow;
564    Pixel bottom_shadow;
565    Pixel select;
566    Colormap colormap;
567
568    XmFontList font_list;
569    XtPointer entry_font;
570    XmFontType type;
571    XFontSetExtents *extents;
572    Atom delete_window;
573    Arg args[32];
574    int n;
575    int font_height;
576    int curdir_height;
577    int temp;
578    int icon_offset, cur_dir_offset;
579    Dimension shadow_thickness;
580    Dimension highlight_thickness;
581    XtTranslations trans_table, trans_table1;
582
583
584    /*  Allocate the change directory dialog instance record.  */
585
586    file_mgr_rec = (FileMgrRec *) XtMalloc (sizeof (FileMgrRec));
587    file_mgr_rec->action_pane_file_type = NULL;
588
589    /* set up translations in main edit widget */
590    trans_table = XtParseTranslationTable(translations_sp_esc);
591    {
592      char * resolvedTranslationString;
593
594      resolvedTranslationString = ResolveTranslationString( translations_da,
595                                                            (char *)file_mgr_rec );
596      trans_table1 = XtParseTranslationTable( resolvedTranslationString );
597      XtFree( resolvedTranslationString );
598      resolvedTranslationString  = NULL;
599    }
600
601    /*  Create the shell and main window used for the view.  */
602
603    XtSetArg (args[0], XmNallowShellResize, True);
604    if(!first && (special_view == True && special_title != NULL && !TrashView))
605    {
606       file_mgr_rec->shell = shell =
607          XtAppCreateShell (special_title, DTFILE_CLASS_NAME,
608                         applicationShellWidgetClass, display, args, 1);
609       XtFree(special_title);
610       special_title = NULL;
611    }
612    else
613       file_mgr_rec->shell = shell =
614          XtAppCreateShell (application_name, DTFILE_CLASS_NAME,
615                         applicationShellWidgetClass, display, args, 1);
616    if(!TrashView)
617       special_view = False;
618
619    n = 0;
620    XtSetArg (args[n], XmNdeleteResponse, XmUNMAP);      n++;
621
622    if (first == False || TrashView)
623    {
624       XtSetArg (args[n], XmNgeometry, NULL);            n++;
625    }
626    else
627       first = False;
628
629    /* Set the useAsyncGeo on the shell */
630    XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
631    XtSetValues (shell, args, n);
632
633    delete_window = XmInternAtom (XtDisplay (shell), "WM_DELETE_WINDOW", False);
634    XmAddWMProtocolCallback (shell, delete_window, (XtCallbackProc)SystemClose,
635                             (XtPointer)file_mgr_rec);
636
637    file_mgr_rec->main = main = XmCreateMainWindow (shell, "main", args, 1);
638    XtManageChild (main);
639    XtAddCallback(main, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
640                  HELP_FILE_MANAGER_VIEW_STR);
641
642
643    /*  Get the select color  */
644
645    XtSetArg (args[0], XmNbackground, &background);
646    XtSetArg (args[1], XmNcolormap,  &colormap);
647    XtGetValues (main, args, 2);
648
649    XmGetColors (XtScreen (main), colormap, background,
650                 &foreground, &top_shadow, &bottom_shadow, &select);
651
652    /*  Create the menu.  */
653
654
655    if(TrashView)
656    {
657       file_mgr_rec->menuStates = NULL;
658       file_mgr_rec->menu = menu = CreateTrashMenu (main, file_mgr_rec);
659    }
660    else
661    {
662       file_mgr_rec->menuStates = (RENAME | MOVE | DUPLICATE | LINK | TRASH |
663                                   MODIFY | CHANGEDIR | PREFERENCES | FILTER |
664                                   FIND | CREATE_DIR | CREATE_FILE | SETTINGS |
665                                   CLEAN_UP | MOVE_UP |
666                                   HOME | CHANGE_DIR | TERMINAL);
667
668       file_mgr_rec->menu = menu = CreateMenu (main, file_mgr_rec);
669    }
670
671    /*  Create the work area frame.  */
672
673    XtSetArg (args[0], XmNshadowThickness, 1);
674    XtSetArg (args[1], XmNshadowType, XmSHADOW_OUT);
675    XtSetArg (args[2], XmNmarginWidth, 5);
676    XtSetArg (args[3], XmNmarginHeight, 5);
677    work_frame = XmCreateFrame (main, "work_frame", args, 4);
678    XtManageChild (work_frame);
679
680
681    /*  Create the current directory frame.  */
682
683    n = 0;
684    XtSetArg (args[n], XmNshadowThickness, 1);                   n++;
685    XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT);             n++;
686    XtSetArg (args[n], XmNmarginWidth, 1);                       n++;
687    XtSetArg (args[n], XmNmarginHeight, 1);                      n++;
688    XtSetArg (args[n], XmNtextTranslations, trans_table);        n++;
689    file_mgr_rec->header_frame = header_frame =
690          XmCreateForm (main, "header_frame", args, n);
691
692    XtAddCallback(header_frame, XmNhelpCallback,
693                     (XtCallbackProc)HelpRequestCB,
694                     HELP_FILE_MANAGER_VIEW_STR);
695
696    /*  Create the current directory line only if not in showFilesystem.  */
697    if (showFilesystem && !TrashView)
698    {
699       /* Create the iconic path */
700       n = 0;
701       XtSetArg (args[n], DtNfileMgrRec, file_mgr_rec);          n++;
702       XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);      n++;
703       XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
704       XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);    n++;
705       file_mgr_rec->iconic_path_da = iconic_path_da =
706          _DtCreateIconicPath(header_frame, "iconic_path", args, n);
707       XtManageChild (iconic_path_da);
708       file_mgr_rec->iconic_path_width = 0;
709
710       /* Create the separator between iconic path and current directory */
711       n = 0;
712       XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);    n++;
713       XtSetArg (args[n], XmNtopWidget, iconic_path_da);         n++;
714       XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
715       XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);    n++;
716       file_mgr_rec->header_separator = header_separator =
717          XmCreateSeparatorGadget(header_frame, "header_separator", args, n);
718       XtManageChild (header_separator);
719
720       /* Create a form for the current directory */
721       n = 0;
722       XtSetArg (args[n], XmNtextTranslations, trans_table);     n++;
723       XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);    n++;
724       XtSetArg (args[n], XmNtopWidget, header_separator);       n++;
725       XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
726       XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);    n++;
727       file_mgr_rec->current_directory_frame = current_directory_frame =
728             XmCreateForm (header_frame, "current_directory_frame", args, n);
729       XtManageChild (file_mgr_rec->current_directory_frame);
730
731       /* Event handler for detecting drag threshold surpassed */
732       XtAddEventHandler(current_directory_frame,
733                         Button1MotionMask|Button2MotionMask,
734                         False, (XtEventHandler)CurrentDirectoryIconMotion,
735                         file_mgr_rec);
736
737       /* Create the change directory drop zone. */
738       if (showDropZone)
739       {
740          if (change_view_pixmap == XmUNSPECIFIED_PIXMAP)
741          {
742             change_view_pixmap =
743               _DtGetPixmap(XtScreen(current_directory_frame),
744                            CHANGE_VIEW_ICON_S, foreground, background);
745          }
746          n = 0;
747          XtSetArg (args[n], XmNstring, NULL);                      n++;
748          XtSetArg (args[n], XmNshadowThickness, 2);                n++;
749          XtSetArg (args[n], XmNfillOnArm, False);                  n++;
750          XtSetArg (args[n], XmNhighlightThickness, 0);             n++;
751          XtSetArg (args[n], XmNpixmap, change_view_pixmap);        n++;
752          XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);      n++;
753          XtSetArg (args[n], XmNtopOffset, 2);                      n++;
754          XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
755          XtSetArg (args[n], XmNleftOffset, 5);                     n++;
756          XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);   n++;
757          XtSetArg (args[n], XmNbottomOffset, 2);                   n++;
758          XtSetArg (args[n], XmNtraversalOn, False);                n++;
759          XtSetArg (args[n], XmNdropSiteOperations,
760                       XmDROP_MOVE | XmDROP_COPY | XmDROP_LINK);    n++;
761          file_mgr_rec->current_directory_drop = current_directory_drop =
762             _DtCreateIcon (current_directory_frame, "drop_cd", args, n);
763
764          XtAddCallback (current_directory_drop, XmNdropCallback,
765                         DropOnChangeView, (XtPointer) file_mgr_rec);
766       }
767       else
768         file_mgr_rec->current_directory_drop = current_directory_drop = NULL;
769
770       /* Create the current directory icon. */
771       n = 0;
772       XtSetArg (args[n], XmNstring, NULL);                      n++;
773       XtSetArg (args[n], XmNimageName, SMALL_DIRECTORY_ICON);   n++;
774       XtSetArg (args[n], XmNshadowThickness, 0);                n++;
775       XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);      n++;
776       if (showDropZone)
777       {
778          XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);    n++;
779          XtSetArg (args[n], XmNleftWidget, current_directory_drop); n++;
780          XtSetArg (args[n], XmNleftOffset, 0);                      n++;
781       }
782       else
783       {
784          XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);      n++;
785          XtSetArg (args[n], XmNleftOffset, 5);                      n++;
786       }
787       XtSetArg (args[n], XmNtraversalOn, False);                    n++;
788       file_mgr_rec->current_directory_icon = current_directory_icon =
789          _DtCreateIcon (current_directory_frame, "current_directory_icon",
790                         args, n);
791
792       /* Create the current directory line */
793       n = 0;
794       XtSetArg (args[n], XmNshadowThickness, 0);             n++;
795       XtSetArg (args[n], XmNmarginWidth, 0);                 n++;
796       XtSetArg (args[n], XmNmarginHeight, 0);                n++;
797       XtSetArg (args[n], XmNpushButtonEnabled, False);       n++;
798       XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);   n++;
799       XtSetArg (args[n], XmNtopOffset, 1);                   n++;
800       XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);  n++;
801       XtSetArg (args[n], XmNleftOffset, 5);                  n++;
802       XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
803       XtSetArg (args[n], XmNrightOffset, 1);                 n++;
804       XtSetArg (args[n], XmNtraversalOn, True);              n++;
805       file_mgr_rec->current_directory =
806         XmCreateDrawnButton(current_directory_frame, "current_directory",
807                                                                       args, n);
808       XtManageChild (file_mgr_rec->current_directory);
809
810
811       /* Create overlay text field, for typing in a new directory */
812       n = 0;
813       XtSetArg (args[n], XmNmarginHeight, 0);                         n++;
814       XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);            n++;
815       XtSetArg (args[n], XmNtopOffset, 1);                            n++;
816       XtSetArg (args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET);n++;
817       XtSetArg (args[n], XmNleftWidget,
818                          file_mgr_rec->current_directory);            n++;
819       XtSetArg (args[n], XmNleftOffset, 0);                           n++;
820       XtSetArg (args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET);n++;
821       XtSetArg (args[n], XmNbottomWidget,
822                          file_mgr_rec->current_directory);            n++;
823       XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);          n++;
824       XtSetArg (args[n], XmNrightOffset, 1);                          n++;
825       XtSetArg (args[n], XmNtraversalOn, True);                       n++;
826       file_mgr_rec->current_directory_text = XmCreateTextField(
827                      current_directory_frame, FAST_RENAME, args, n);
828
829       /*
830        * Make sure the font & highlight thickness of the text field is the
831        * same as the corresponding values for the current directory line.
832        */
833       XtSetArg (args[0], XmNhighlightThickness, &highlight_thickness);
834       XtSetArg (args[1], XmNfontList, &font_list);
835       XtGetValues (file_mgr_rec->current_directory, args, 2);
836
837       XtSetArg (args[0], XmNhighlightThickness, highlight_thickness);
838       XtSetArg (args[1], XmNfontList, font_list);
839       XtSetValues (file_mgr_rec->current_directory_text, args, 2);
840
841       /*
842        * Calculate how high to make the current directory line by adding
843        * up the font height and the highlight and shadow thickness
844        */
845       XtSetArg (args[0], XmNshadowThickness, &shadow_thickness);
846       XtGetValues (file_mgr_rec->current_directory_text, args, 1);
847
848       entry_font = XmFontListEntryGetFont(FontListDefaultEntry(font_list), &type);
849       if(type == XmFONT_IS_FONTSET) {
850           extents = XExtentsOfFontSet((XFontSet)entry_font);
851           font_height = extents->max_logical_extent.height;
852       }
853       else {
854           font_height = ((XFontStruct *)entry_font)->ascent +
855                  ((XFontStruct *)entry_font)->descent;
856       }
857       curdir_height = font_height + 2*(highlight_thickness + shadow_thickness);
858
859       XtSetArg (args[0], XmNtopOffset, &cur_dir_offset);
860       XtGetValues (file_mgr_rec->current_directory, args, 1);
861
862       XtSetArg (args[0], XmNheight, curdir_height);
863       XtSetValues (file_mgr_rec->current_directory, args, 1);
864
865       XtSetArg (args[0], XmNheight, curdir_height + 2*cur_dir_offset);
866       XtSetValues (file_mgr_rec->current_directory_frame, args, 1);
867
868       XtAddCallback(file_mgr_rec->current_directory_text, XmNactivateCallback,
869                                  (XtCallbackProc)ChangeToNewDir, file_mgr_rec);
870       XtAddCallback(file_mgr_rec->current_directory_text, XmNhelpCallback,
871                     (XtCallbackProc)HelpRequestCB,
872                     HELP_FILE_MANAGER_VIEW_STR);
873 #ifdef FOO
874       /* This code is here so the Text Path (used to be Fast Change Dir
875          text) will be checked if user is ever try to type on the portion
876          before his restricted path.
877          It's no longer needed because, there won't be anything since
878          I'm tryting to treat restrictMode the same way I treat restricted
879          directory (i.e. dtfile -restricted).
880          Why I want to treat them the same way? Because they are the
881          same sort of things and it, also, solves the iconic path problem.
882          Note that user can double click on one of the icon and to a directory
883          above the restricted directory.
884       */
885       if(restrictMode)
886       {
887          /* add the callbacks to make sure the user isn't able to
888             go anywhere above their restricted directory */
889          XtAddCallback (file_mgr_rec->current_directory_text,
890                         XmNmodifyVerifyCallback, (XtCallbackProc)TextChange,
891                         (XtPointer)NULL );
892          XtAddCallback (file_mgr_rec->current_directory_text,
893                         XmNmotionVerifyCallback, (XtCallbackProc)TextChange,
894                         (XtPointer)NULL );
895       }
896 #endif
897    }
898
899    /* create the status line */
900    n = 0;
901    XtSetArg (args[n], XmNshadowThickness, 1);           n++;
902    XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT);             n++;
903    XtSetArg (args[n], XmNmarginWidth, 5);                       n++;
904    XtSetArg (args[n], XmNmarginHeight, 1);                      n++;
905    status_form = XmCreateForm (main, "status_form", args, n);
906    XtManageChild (status_form);
907
908    n = 0;
909    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING);     n++;
910    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);         n++;
911    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);        n++;
912    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);       n++;
913    file_mgr_rec->status_line =
914          XmCreateLabelGadget (status_form, "status_line", args, n);
915    XtManageChild (file_mgr_rec->status_line);
916
917    /*  Associate the menu and frames with the appropriate  */
918    /*  areas of the main windows.                          */
919
920    XmMainWindowSetAreas (main, menu, file_mgr_rec->header_frame,
921                             NULL, NULL, work_frame);
922    XtSetArg (args[0], XmNmessageWindow, status_form);
923    XtSetValues(main, args, 1);
924
925    /*  Create the Scrolled Window for the file display area and  */
926    /*  set the scrollbars colors correctly.                      */
927
928    n = 0;
929    XtSetArg (args[n], XmNspacing, 2);                           n++;
930    XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC);         n++;
931    XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmAS_NEEDED);  n++;
932    file_mgr_rec->scroll_window =
933       XmCreateScrolledWindow (work_frame, "scroll_window", args, n);
934    XtManageChild (file_mgr_rec->scroll_window);
935    if(TrashView)
936       XtAddCallback(file_mgr_rec->scroll_window, XmNhelpCallback,
937                     (XtCallbackProc)HelpRequestCB,
938                      HELP_TRASH_OVERVIEW_TOPIC_STR);
939    else
940       XtAddCallback(file_mgr_rec->scroll_window, XmNhelpCallback,
941                     (XtCallbackProc)HelpRequestCB,
942                     HELP_FILE_MANAGER_VIEW_STR);
943
944    /*  Get the 2 scrollbars and reset their foreground to the proper color  */
945    /*  Also turn their traversal off and set the highlight thickness to 0.  */
946
947    XtSetArg (args[0], XmNhorizontalScrollBar, &(file_mgr_rec->horizontal_scroll_bar));
948    XtSetArg (args[1], XmNverticalScrollBar, &(file_mgr_rec->vertical_scroll_bar));
949    XtGetValues (file_mgr_rec->scroll_window, args, 2);
950
951    XtSetArg (args[0], XmNforeground, background);
952    XtSetArg (args[1], XmNtraversalOn, True);
953    XtSetValues (file_mgr_rec->horizontal_scroll_bar, args, 2);
954    XtSetValues (file_mgr_rec->vertical_scroll_bar, args, 2);
955
956
957    /*  Add an event handler to catch resizes occuring on the scrolled  */
958    /*  window, in order to force a relayout of the icons.              */
959
960    XtAddEventHandler (file_mgr_rec->scroll_window, StructureNotifyMask,
961                       False, (XtEventHandler)FileWindowResizeCallback,
962                       file_mgr_rec);
963    XtAddEventHandler (shell, StructureNotifyMask,
964                       False, (XtEventHandler)FileWindowMapCallback,
965                       file_mgr_rec);
966
967
968    /*  Create a drawing area as a child of the scrolled window  */
969
970    n = 0;
971    XtSetArg (args[n], XmNmarginWidth, 0);               n++;
972    XtSetArg (args[n], XmNmarginHeight, 0);              n++;
973    XtSetArg (args[n], XmNresizePolicy, XmRESIZE_GROW);  n++;
974    file_mgr_rec->file_window =
975       XmCreateDrawingArea (file_mgr_rec->scroll_window, "file_window", args, n);
976    XtAppAddActions( XtWidgetToApplicationContext(file_mgr_rec->file_window),
977                     FMAction,
978                     XtNumber(FMAction));
979    XtManageChild (file_mgr_rec->file_window);
980
981    XtManageChild (file_mgr_rec->header_frame);
982
983    XtSetArg (args[0], XmNbackground, select);
984    XtSetValues (file_mgr_rec->file_window, args, 1);
985
986    XtSetArg (args[0], XmNbackground, select);
987    XtSetValues (XtParent (file_mgr_rec->file_window), args, 1);
988
989    if(fileMgrPopup.menu == NULL)
990       CreateFmPopup(file_mgr_rec->file_window);
991    else
992       XmAddToPostFromList(fileMgrPopup.menu, file_mgr_rec->file_window);
993
994    /* set up translations in main edit widget */
995 #ifdef DOUBLE_CLICK_DRAG
996    XtUninstallTranslations(file_mgr_rec->file_window);
997    XtOverrideTranslations(file_mgr_rec->file_window,
998      (XtTranslations)
999        ((XmManagerClassRec *)XtClass(file_mgr_rec->file_window))
1000                                       ->manager_class.translations);
1001    XtOverrideTranslations(file_mgr_rec->file_window, trans_table1);
1002    XtOverrideTranslations(file_mgr_rec->file_window,
1003         XtParseTranslationTable(_XmDrawingA_traversalTranslations));
1004 #else
1005    XtOverrideTranslations(file_mgr_rec->file_window, trans_table1);
1006 #endif
1007
1008    /*  Add the callbacks for processing selections, exposures,  */
1009    /*  and geometry changes of the drawing area.                */
1010
1011    XtAddCallback (file_mgr_rec->file_window, XmNexposeCallback,
1012                   FileWindowExposeCallback, file_mgr_rec);
1013
1014    XtAddCallback (file_mgr_rec->file_window, XmNinputCallback,
1015                      FileWindowInputCallback, file_mgr_rec);
1016
1017    /* Event handler for detecting drag threshold surpassed */
1018    XtAddEventHandler(file_mgr_rec->file_window,
1019                      Button1MotionMask|Button2MotionMask,
1020                      False, (XtEventHandler)FileIconMotion,
1021                      file_mgr_rec);
1022
1023    /* Arrange for initial focus to be inside the file window */
1024    file_mgr_rec->focus_widget = file_mgr_rec->file_window;
1025
1026    /*  Set the return values for the dialog widget and dialog instance.  */
1027
1028    *return_widget = (Widget) main;
1029    *dialog = (XtPointer) file_mgr_rec;
1030 }
1031
1032
1033 /************************************************************************
1034  *
1035  *  GetDefaultValues
1036  *
1037  ************************************************************************/
1038
1039 static XtPointer
1040 GetDefaultValues( void )
1041 {
1042    FileMgrData * file_mgr_data;
1043    PreferencesData *preferences_data;
1044    unsigned char *viewP;
1045
1046
1047    /*  Allocate and initialize the default change dir dialog data.  */
1048
1049    file_mgr_data = (FileMgrData *) XtMalloc (sizeof (FileMgrData));
1050
1051    file_mgr_data->displayed = False;
1052    file_mgr_data->mapped = False;
1053    file_mgr_data->x = 0;
1054    file_mgr_data->y = 0;
1055
1056    file_mgr_data->busy_status = not_busy;
1057    file_mgr_data->busy_detail = 0;
1058
1059    file_mgr_data->num_objects = 0;
1060    file_mgr_data->object_positions = NULL;
1061    file_mgr_data->grid_height = 0;
1062    file_mgr_data->grid_width = 0;
1063    file_mgr_data->layout_data = NULL;
1064
1065    file_mgr_data->special_msg = NULL;
1066    file_mgr_data->msg_timer_id = 0;
1067
1068    file_mgr_data->show_type = SINGLE_DIRECTORY;
1069    file_mgr_data->tree_files = TREE_FILES_NEVER;
1070    file_mgr_data->view_single = BY_NAME_AND_ICON;
1071    file_mgr_data->view_tree = BY_NAME_AND_SMALL_ICON;
1072    file_mgr_data->tree_preread_level = 1;
1073    file_mgr_data->tree_show_level = 1;
1074    file_mgr_data->show_iconic_path = True;
1075    file_mgr_data->show_current_dir = True;
1076    file_mgr_data->show_status_line = True;
1077
1078    file_mgr_data->scrollToThisFile = NULL;
1079    file_mgr_data->scrollToThisDirectory = NULL;
1080
1081    file_mgr_data->renaming = NULL;
1082
1083    if(special_view && !TrashView)
1084    {
1085       if(special_title != NULL)
1086       {
1087          file_mgr_data->title = XtNewString(special_title);
1088       }
1089       else
1090          file_mgr_data->title = NULL;
1091
1092       if(special_helpVol != NULL)
1093       {
1094          file_mgr_data->helpVol = XtNewString(special_helpVol);
1095          XtFree(special_helpVol);
1096          special_helpVol = NULL;
1097       }
1098       else
1099          file_mgr_data->helpVol = XtNewString(fileMgrHelpVol);
1100
1101       if(special_restricted != NULL)
1102         file_mgr_data->restricted_directory = special_restricted;
1103       else
1104         file_mgr_data->restricted_directory = NULL;
1105
1106       if(special_treeType == UNSET_VALUE)
1107          file_mgr_data->show_type = SINGLE_DIRECTORY;
1108       else
1109          file_mgr_data->show_type = special_treeType;
1110
1111       if(special_treeFiles == UNSET_VALUE)
1112          file_mgr_data->tree_files = TREE_FILES_NEVER;
1113       else
1114          file_mgr_data->tree_files = special_treeFiles;
1115
1116       if(file_mgr_data->show_type == MULTIPLE_DIRECTORY)
1117         viewP = &file_mgr_data->view_tree;
1118       else
1119         viewP = &file_mgr_data->view_single;
1120       if(special_viewType == UNSET_VALUE)
1121          file_mgr_data->view = *viewP;
1122       else
1123          file_mgr_data->view = *viewP = special_viewType;
1124
1125       if(special_orderType == UNSET_VALUE)
1126          file_mgr_data->order = ORDER_BY_ALPHABETICAL;
1127       else
1128          file_mgr_data->order = special_orderType;
1129
1130       if(special_directionType == UNSET_VALUE)
1131          file_mgr_data->direction = DIRECTION_ASCENDING;
1132       else
1133          file_mgr_data->direction = special_directionType;
1134
1135       if(special_randomType == UNSET_VALUE)
1136          file_mgr_data->positionEnabled = RANDOM_OFF;
1137       else
1138          file_mgr_data->positionEnabled = special_randomType;
1139
1140    }
1141    else
1142    {
1143       if(fileMgrTitle == NULL)
1144          file_mgr_data->title = NULL;
1145       else
1146          file_mgr_data->title = XtNewString(fileMgrTitle);
1147
1148       file_mgr_data->helpVol = XtNewString(fileMgrHelpVol);
1149
1150       if(treeType == UNSET_VALUE || TrashView)
1151          file_mgr_data->show_type = SINGLE_DIRECTORY;
1152       else
1153          file_mgr_data->show_type = treeType;
1154
1155       if(treeFiles == UNSET_VALUE)
1156          file_mgr_data->tree_files = TREE_FILES_NEVER;
1157       else
1158          file_mgr_data->tree_files = treeFiles;
1159
1160       if(file_mgr_data->show_type == MULTIPLE_DIRECTORY)
1161         viewP = &file_mgr_data->view_tree;
1162       else
1163         viewP = &file_mgr_data->view_single;
1164       if(viewType == UNSET_VALUE)
1165          file_mgr_data->view = *viewP;
1166       else
1167          file_mgr_data->view = *viewP = viewType;
1168
1169       if(orderType == UNSET_VALUE)
1170          file_mgr_data->order = ORDER_BY_ALPHABETICAL;
1171       else
1172          file_mgr_data->order = orderType;
1173
1174       if(directionType == UNSET_VALUE)
1175          file_mgr_data->direction = DIRECTION_ASCENDING;
1176       else
1177          file_mgr_data->direction = directionType;
1178
1179       if(randomType == UNSET_VALUE)
1180          file_mgr_data->positionEnabled = RANDOM_OFF;
1181       else
1182          file_mgr_data->positionEnabled = randomType;
1183
1184       file_mgr_data->restricted_directory = NULL;
1185    }
1186
1187    file_mgr_data->restoreKind = NORMAL_RESTORE;
1188
1189    file_mgr_data->host = NULL;
1190    file_mgr_data->current_directory = NULL;
1191    file_mgr_data->branch_list = NULL;
1192
1193    file_mgr_data->toolbox = False;
1194    file_mgr_data->dropSite = False;
1195
1196    file_mgr_data->newSize = True;
1197
1198    file_mgr_data->directory_count = 0;
1199    file_mgr_data->directory_set = NULL;
1200    file_mgr_data->tree_root = NULL;
1201
1202    file_mgr_data->selection_list =
1203       (FileViewData **) XtMalloc (sizeof (FileViewData *));
1204    file_mgr_data->selection_list[0] = NULL;
1205
1206    file_mgr_data->selection_table = NULL;
1207    file_mgr_data->selected_file_count = 0;
1208
1209    file_mgr_data->fast_cd_enabled = False;
1210    file_mgr_data->show_hid_enabled = False;
1211
1212    file_mgr_data->cd_inited = False;
1213    file_mgr_data->cd_font = NULL;
1214    file_mgr_data->cd_fontset = NULL;
1215    file_mgr_data->cd_normal_gc = 0;
1216    file_mgr_data->cd_select_gc = 0;
1217    file_mgr_data->cd_select = NULL;
1218
1219    file_mgr_data->tree_solid_thin_gc = 0;
1220    file_mgr_data->tree_solid_thick_gc = 0;
1221    file_mgr_data->tree_dash_thin_gc = 0;
1222    file_mgr_data->tree_dash_thick_gc = 0;
1223
1224    file_mgr_data->file_mgr_rec = NULL;
1225    file_mgr_data->popup_menu_icon = NULL;
1226    file_mgr_data->drag_file_view_data = NULL;
1227
1228    file_mgr_data->change_dir = _DtGetDefaultDialogData (change_dir_dialog);
1229    file_mgr_data->preferences = _DtGetDefaultDialogData (preferences_dialog);
1230
1231    /* now set up the preferences the way they really are */
1232    preferences_data = (PreferencesData *)file_mgr_data->preferences->data;
1233    preferences_data->show_type = file_mgr_data->show_type;
1234    preferences_data->tree_files = file_mgr_data->tree_files;
1235    preferences_data->view_single = file_mgr_data->view_single;
1236    preferences_data->view_tree = file_mgr_data->view_tree;
1237    preferences_data->order = file_mgr_data->order;
1238    preferences_data->direction = file_mgr_data->direction;
1239    preferences_data->positionEnabled = file_mgr_data->positionEnabled;
1240    preferences_data->show_iconic_path = file_mgr_data->show_iconic_path;
1241    preferences_data->show_current_dir = file_mgr_data->show_current_dir;
1242    preferences_data->show_status_line = file_mgr_data->show_status_line;
1243
1244    file_mgr_data->filter_edit = _DtGetDefaultDialogData (filter_dialog);
1245    file_mgr_data->filter_active = _DtGetDefaultDialogData (filter_dialog);
1246    file_mgr_data->find = _DtGetDefaultDialogData (find_dialog);
1247    file_mgr_data->attr_dialog_list = NULL;
1248    file_mgr_data->attr_dialog_count = 0;
1249    file_mgr_data->secondaryHelpDialogList = NULL;
1250    file_mgr_data->secondaryHelpDialogCount = 0;
1251    file_mgr_data->primaryHelpDialog = NULL;
1252
1253    return ((XtPointer) file_mgr_data);
1254 }
1255
1256
1257 /************************************************************************
1258  *
1259  *  GetResourceValues
1260  *
1261  ************************************************************************/
1262
1263 static XtPointer
1264 GetResourceValues(
1265         XrmDatabase data_base,
1266         char **name_list )
1267 {
1268    static Boolean first = True;
1269    FileMgrData * file_mgr_data;
1270    PreferencesData *preferences_data;
1271    char * host_name;
1272    char * directory_name;
1273    char * new_name_list[20];
1274    int name_list_count;
1275    struct passwd * pwInfo;
1276    char * homeDir;
1277    char number[10];
1278    int i, j, count;
1279    char * tmpStr;
1280
1281    if (first)
1282    {
1283       first = False;
1284
1285       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1286                          SHOW_TYPE, StringToShowType, NULL, 0);
1287       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1288                          TREE_FILES, StringToTreeFiles, NULL, 0);
1289       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1290                          VIEW, StringToView, NULL, 0);
1291       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1292                          ORDER, StringToOrder, NULL, 0);
1293       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1294                          DIRECTION_RESRC, StringToDirection, NULL, 0);
1295       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1296                          RANDOM, StringToRandom, NULL, 0);
1297       XtAppSetTypeConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1298                              BRANCH_LIST, (XtTypeConverter)StringToBranchList,
1299                              NULL, 0, XtCacheNone, NULL);
1300       XtAppAddConverter (XtWidgetToApplicationContext (toplevel), XmRString,
1301                          SELECTION_LIST, (XtConverter)StringToSelectionList,
1302                          NULL, 0);
1303    }
1304
1305
1306    /*  Allocate and get the resources for change dir dialog data.  */
1307
1308    file_mgr_data = (FileMgrData *) XtMalloc (sizeof (FileMgrData));
1309
1310    file_mgr_data->busy_status = not_busy;
1311    file_mgr_data->busy_detail = 0;
1312    file_mgr_data->num_objects = 0;
1313    file_mgr_data->object_positions = NULL;
1314    file_mgr_data->grid_height = 0;
1315    file_mgr_data->grid_width = 0;
1316    file_mgr_data->layout_data = NULL;
1317    file_mgr_data->secondaryHelpDialogList = NULL;
1318    file_mgr_data->secondaryHelpDialogCount = 0;
1319    file_mgr_data->attr_dialog_count = 0;
1320    file_mgr_data->attr_dialog_list = NULL;
1321    file_mgr_data->primaryHelpDialog = NULL;
1322    file_mgr_data->popup_menu_icon = NULL;
1323    file_mgr_data->title = NULL;
1324    file_mgr_data->helpVol = NULL;
1325    file_mgr_data->restricted_directory = NULL;
1326    file_mgr_data->toolbox = False;
1327    file_mgr_data->dropSite = False;
1328    file_mgr_data->tree_preread_level = 1;  /* @@@ make these resources? */
1329    file_mgr_data->tree_show_level = 1;
1330    file_mgr_data->tree_files = TREE_FILES_NEVER;
1331    file_mgr_data->special_msg = NULL;
1332    file_mgr_data->msg_timer_id = 0;
1333    file_mgr_data->show_iconic_path = True;
1334    file_mgr_data->show_current_dir = True;
1335    file_mgr_data->show_status_line = True;
1336    file_mgr_data->scrollToThisFile = NULL;
1337    file_mgr_data->scrollToThisDirectory = NULL;
1338    file_mgr_data->renaming = NULL;
1339
1340    _DtDialogGetResources (data_base, name_list, FILEMGR, (char *)file_mgr_data,
1341                        resources, fileMgrClass->resource_count);
1342    if (file_mgr_data->show_type == MULTIPLE_DIRECTORY)
1343      file_mgr_data->view = file_mgr_data->view_tree;
1344    else
1345      file_mgr_data->view = file_mgr_data->view_single;
1346
1347    /* Bases on the type of restore session we are doing we must
1348     * adjust the host, current_directory, and selections to the
1349     * proper values (e.g. restore session or restore settings)
1350     */
1351     if (restoreType != NORMAL_RESTORE)
1352     {
1353       GetSessionDir(file_mgr_data);
1354
1355       /* Adjust the selected files to null */
1356       file_mgr_data->selection_list = NULL;
1357
1358       /* Set the Displayed to false so we do not use the x and y
1359          values when we place the window in showDialog
1360        */
1361       file_mgr_data->displayed = False;
1362
1363       if(special_view && !TrashView)
1364       {
1365          if(special_title != NULL)
1366             file_mgr_data->title = XtNewString(special_title);
1367          else
1368             file_mgr_data->title = XtNewString(file_mgr_data->title);
1369
1370          if(special_helpVol != NULL)
1371             file_mgr_data->helpVol = XtNewString(special_helpVol);
1372          else
1373             file_mgr_data->helpVol = XtNewString(file_mgr_data->helpVol);
1374
1375          if(special_treeType != UNSET_VALUE)
1376             file_mgr_data->show_type = special_treeType;
1377
1378          if(special_treeFiles != UNSET_VALUE)
1379             file_mgr_data->tree_files = special_treeFiles;
1380
1381          if(special_viewType != UNSET_VALUE)
1382          {
1383            file_mgr_data->view = special_viewType;
1384            if(file_mgr_data->show_type == MULTIPLE_DIRECTORY)
1385               file_mgr_data->view_tree = special_viewType;
1386            else
1387               file_mgr_data->view_single = special_viewType;
1388          }
1389
1390          if(special_orderType != UNSET_VALUE)
1391             file_mgr_data->order = special_orderType;
1392
1393          if(special_directionType != UNSET_VALUE)
1394             file_mgr_data->direction = special_directionType;
1395
1396          if(special_randomType != UNSET_VALUE)
1397             file_mgr_data->positionEnabled = special_randomType;
1398       }
1399       else
1400       {
1401          file_mgr_data->title = XtNewString(file_mgr_data->title);
1402          file_mgr_data->helpVol = XtNewString(file_mgr_data->helpVol);
1403       }
1404     }
1405     else
1406     {
1407       GetSessionDir(file_mgr_data);
1408
1409       file_mgr_data->title = XtNewString(file_mgr_data->title);
1410       file_mgr_data->helpVol = XtNewString(file_mgr_data->helpVol);
1411     }
1412
1413    /* The GetSessionDir() function depends on the hostname being set. */
1414    /* So, we'll do it earlier */
1415    if(file_mgr_data->host != NULL)
1416       file_mgr_data->host = XtNewString(file_mgr_data->host);
1417    else
1418       file_mgr_data->host = XtNewString(home_host_name);
1419
1420    file_mgr_data->restoreKind = NORMAL_RESTORE;
1421
1422    file_mgr_data->directory_count = 0;
1423    file_mgr_data->directory_set = NULL;
1424    file_mgr_data->tree_root = NULL;
1425
1426    file_mgr_data->selected_file_count = 0;
1427    file_mgr_data->selection_table = (char **) file_mgr_data->selection_list;
1428    file_mgr_data->selection_list =
1429       (FileViewData **) XtMalloc (sizeof (FileViewData *));
1430    file_mgr_data->selection_list[0] = NULL;
1431
1432    file_mgr_data->cd_inited = False;
1433    file_mgr_data->cd_font = NULL;
1434    file_mgr_data->cd_fontset = NULL;
1435    file_mgr_data->cd_normal_gc = 0;
1436    file_mgr_data->cd_select_gc = 0;
1437    file_mgr_data->cd_select = NULL;
1438
1439    file_mgr_data->popup_menu_icon = NULL;
1440    file_mgr_data->drag_file_view_data = NULL;
1441
1442    file_mgr_data->tree_solid_thin_gc = 0;
1443    file_mgr_data->tree_solid_thick_gc = 0;
1444    file_mgr_data->tree_dash_thin_gc = 0;
1445    file_mgr_data->tree_dash_thick_gc = 0;
1446
1447    host_name = XtNewString (file_mgr_data->host);
1448    directory_name = XtNewString (file_mgr_data->current_directory);
1449
1450    FileMgrBuildDirectories (file_mgr_data, host_name, directory_name);
1451
1452    XtFree ((char *) host_name);
1453    host_name = NULL;
1454    XtFree ((char *) directory_name);
1455
1456    if (restoreType == NORMAL_RESTORE &&
1457                        file_mgr_data->positionEnabled == RANDOM_ON)
1458    {
1459       /* Restore the optional positional data */
1460       RestorePositionalData(data_base, name_list, file_mgr_data, FILEMGR);
1461    }
1462
1463
1464    /*  Get a copy of the name list to be used to build new name lists.  */
1465
1466    _DtDuplicateDialogNameList(name_list, new_name_list, 20, &name_list_count);
1467
1468    /* Load sub-dialogs */
1469
1470    /* Get secondary help dialogs */
1471    if(restoreType == NORMAL_RESTORE &&
1472                      file_mgr_data->secondaryHelpDialogCount > 0)
1473    {
1474       _DtLoadSubdialogArray(new_name_list, name_list_count,
1475                          &(file_mgr_data->secondaryHelpDialogList),
1476                          file_mgr_data->secondaryHelpDialogCount,
1477                          help_dialog, data_base, 1);
1478    }
1479    else
1480    {
1481       file_mgr_data->secondaryHelpDialogList = NULL;
1482       file_mgr_data->secondaryHelpDialogCount = 0;
1483    }
1484
1485    /* Get primary help dialog */
1486    new_name_list[name_list_count] = number;
1487    new_name_list[name_list_count + 1] = NULL;
1488    sprintf(number, "%d", 0);
1489    if (restoreType == NORMAL_RESTORE)
1490    {
1491       file_mgr_data->primaryHelpDialog =
1492                 _DtGetResourceDialogData(help_dialog, data_base, new_name_list);
1493       if(((DialogInstanceData *)
1494                  (file_mgr_data->primaryHelpDialog->data))->displayed == False)
1495       {
1496          _DtFreeDialogData( file_mgr_data->primaryHelpDialog );
1497          file_mgr_data->primaryHelpDialog = NULL;
1498       }
1499    }
1500    else
1501       file_mgr_data->primaryHelpDialog = NULL;
1502
1503    if (restoreType == NORMAL_RESTORE &&
1504                      file_mgr_data->attr_dialog_count > 0)
1505    {
1506       /* Get properties dialogs */
1507       _DtLoadSubdialogArray(new_name_list, name_list_count,
1508                          &(file_mgr_data->attr_dialog_list),
1509                          file_mgr_data->attr_dialog_count,
1510                          mod_attr_dialog, data_base, 1);
1511    }
1512    else
1513    {
1514       file_mgr_data->attr_dialog_list = NULL;
1515       file_mgr_data->attr_dialog_count = 0;
1516    }
1517    new_name_list[name_list_count] = NULL;
1518
1519    file_mgr_data->change_dir =
1520       _DtGetResourceDialogData (change_dir_dialog, data_base, name_list);
1521
1522    file_mgr_data->preferences =
1523       _DtGetResourceDialogData (preferences_dialog, data_base, name_list);
1524
1525    /* Set all dialogs displayed flag for change_dir, and preferences
1526     * to false if not NORMAL_RESTORE
1527     */
1528    if (restoreType != NORMAL_RESTORE)
1529    {
1530       ((DialogInstanceData *)
1531               (file_mgr_data->change_dir->data))->displayed = False;
1532
1533       ((DialogInstanceData *)
1534               (file_mgr_data->preferences->data))->displayed = False;
1535    }
1536
1537    /* now set up the preferences the way they really are */
1538    preferences_data = (PreferencesData *)file_mgr_data->preferences->data;
1539    preferences_data->show_type = file_mgr_data->show_type;
1540    preferences_data->tree_files = file_mgr_data->tree_files;
1541    preferences_data->view_single = file_mgr_data->view_single;
1542    preferences_data->view_tree = file_mgr_data->view_tree;
1543    preferences_data->order = file_mgr_data->order;
1544    preferences_data->direction = file_mgr_data->direction;
1545    preferences_data->positionEnabled = file_mgr_data->positionEnabled;
1546    preferences_data->show_iconic_path = file_mgr_data->show_iconic_path;
1547    preferences_data->show_current_dir = file_mgr_data->show_current_dir;
1548    preferences_data->show_status_line = file_mgr_data->show_status_line;
1549
1550    /*  Build the name list for the file dialog that is displayed,  */
1551    /*  get resource data and perform and other initialization.     */
1552
1553    tmpStr = GetSharedMessage(FILTER_EDIT_ID_STRING);
1554    new_name_list[name_list_count] = XtNewString (tmpStr);
1555    new_name_list[name_list_count + 1] = NULL;
1556
1557    file_mgr_data->filter_edit =
1558       _DtGetResourceDialogData (filter_dialog, data_base, new_name_list);
1559
1560    XtFree ((char *) new_name_list[name_list_count]);
1561    new_name_list[name_list_count] = NULL;
1562
1563
1564    /*  Build the name list for the filter dialog that is used for the  */
1565    /*  current processing values.  Get the resource data and perform   */
1566    /*  and other initialization.                                       */
1567
1568    tmpStr = GetSharedMessage(FILTER_ACTIVE_ID_STRING);
1569    new_name_list[name_list_count] = XtNewString (tmpStr);
1570    new_name_list[name_list_count + 1] = NULL;
1571
1572    file_mgr_data->filter_active =
1573       _DtGetResourceDialogData (filter_dialog, data_base, new_name_list);
1574
1575    XtFree ((char *) new_name_list[name_list_count]);
1576    new_name_list[name_list_count] = NULL;
1577
1578    /*  Get the resource data for the find dialog and perform  */
1579    /*  additional initialization.                             */
1580
1581    file_mgr_data->find =
1582       _DtGetResourceDialogData (find_dialog, data_base, name_list);
1583
1584
1585    /* Set the FilterDialog and Find dialog displayed flag to false if
1586     * not NORMAL_RESTORE
1587     */
1588
1589    if (restoreType != NORMAL_RESTORE)
1590    {
1591       ((DialogInstanceData *)
1592               (file_mgr_data->filter_edit->data))->displayed = False;
1593
1594       ((DialogInstanceData *)
1595               (file_mgr_data->find->data))->displayed = False;
1596
1597    }
1598
1599    return ((XtPointer) file_mgr_data);
1600 }
1601
1602 /************************************************************************
1603  *
1604  *  SetValues
1605  *
1606  ************************************************************************/
1607
1608 static void
1609 SetValues(
1610         FileMgrRec *file_mgr_rec,
1611         FileMgrData *file_mgr_data )
1612 {
1613    Widget cd = file_mgr_rec->current_directory;
1614    Widget cdi = file_mgr_rec->current_directory_icon;
1615    Widget cdd = file_mgr_rec->current_directory_drop;
1616    Widget widg;
1617    XmFontList font_list;
1618    XtPointer entry_font;
1619    XmFontType type;
1620    Pixel foreground;
1621    Pixel background;
1622    XGCValues gc_values;
1623    int gc_mask;
1624    ChangeDirData * change_dir_data;
1625    ModAttrRec *modAttr_rec;
1626    DialogData *attr_dialog;
1627    ModAttrData *attr_data;
1628    Boolean loadOk;
1629
1630    register int i;
1631    register int j;
1632    register int k;
1633    DirectorySet ** directory_set;
1634    FileViewData ** order_list;
1635    int directory_count;
1636    char * file_name;
1637    char * realPath;
1638    char * textString;
1639    char *tmpStr, *tempStr;
1640    Arg args[8];
1641    PixmapData *pixmapData;
1642
1643    file_mgr_data->file_mgr_rec = (XtPointer) file_mgr_rec;
1644
1645    /* this is what we did for the ultrix port to get the name of the
1646       Application dir right, BUT it has some bugs */
1647    if(file_mgr_data->title != NULL)
1648    {
1649       XtSetArg (args[0], XmNtitle, file_mgr_data->title);
1650       XtSetValues(file_mgr_rec->shell, args, 1);
1651    }
1652
1653    /*  Set up the callbacks for the current directory line only if
1654        not in showFilesystem.  */
1655
1656    if(showFilesystem && !TrashView)
1657    {
1658       XtRemoveAllCallbacks (cd, XmNarmCallback);
1659       XtAddCallback (cd, XmNarmCallback, CurrentDirSelected, file_mgr_rec);
1660
1661       XtRemoveAllCallbacks (cd, XmNexposeCallback);
1662       XtAddCallback (cd, XmNexposeCallback, CurrentDirExposed, file_mgr_rec);
1663
1664       XtRemoveAllCallbacks (cdi, XmNcallback);
1665       XtAddCallback (cdi, XmNcallback, CurrentDirIconCallback, file_mgr_rec);
1666
1667       if (cdd)
1668       {
1669          XtRemoveAllCallbacks (cdd, XmNcallback);
1670          XtAddCallback (cdd, XmNcallback, CurrentDirDropCallback, file_mgr_rec);
1671       }
1672
1673       DtUpdateIconicPath(file_mgr_rec, file_mgr_data, False);
1674    }
1675
1676    /*
1677     * To help our menu callbacks get the file_mgr_rec when they are
1678     * activated, we will register the file_mgr_rec pointer as the
1679     * user_data for the menubar.  That way, since the callbacks can
1680     * find out which menubar they were invoked from, they can easily
1681     * map this into the file_mgr_rec.
1682     */
1683    XtSetArg(args[0], XmNuserData, file_mgr_rec);
1684    XtSetValues(file_mgr_rec->menu, args, 1);
1685    if(fileMgrPopup.menu != NULL)
1686       XtSetValues(fileMgrPopup.menu, args, 1);
1687
1688
1689    /*
1690     * Adjust some widgets, in case this is a recycled dialog, which
1691     * previously had been used as a desktop view, or vice-versa.
1692     */
1693
1694    XtManageChild(file_mgr_rec->header_frame);
1695    XtManageChild(file_mgr_rec->directoryBarBtn);
1696
1697
1698    if(showFilesystem && !TrashView)
1699    {
1700       widg = cd;
1701       XtSetArg (args[0], XmNallowShellResize, False);
1702       XtSetValues(file_mgr_rec->shell, args, 1);
1703    }
1704    else
1705       widg = file_mgr_rec->directoryBarBtn;
1706
1707
1708    XtSetArg (args[0], XmNforeground, &foreground);
1709    XtSetArg (args[1], XmNbackground, &background);
1710    XtSetArg (args[2], XmNfontList, &font_list);
1711    XtGetValues (widg, args, 3);
1712
1713    /*  If the current_directory data has not been initialized  */
1714    /*  for this data record, do it now.                        */
1715
1716    if (file_mgr_data->cd_inited == False)
1717    {
1718       file_mgr_data->cd_inited = True;
1719
1720       entry_font = XmFontListEntryGetFont(FontListDefaultEntry(font_list), &type);
1721       if(type == XmFONT_IS_FONTSET) {
1722           file_mgr_data->cd_fontset = (XFontSet)entry_font;
1723           file_mgr_data->cd_fonttype = XmFONT_IS_FONTSET;
1724           gc_mask = GCForeground | GCBackground;
1725       }
1726       else {
1727           file_mgr_data->cd_font = (XFontStruct *)entry_font;
1728           file_mgr_data->cd_fonttype = XmFONT_IS_FONT;
1729           gc_values.font = ((XFontStruct *)entry_font)->fid;
1730           gc_mask = GCForeground | GCBackground | GCFont;
1731       }
1732
1733       gc_values.foreground = foreground;
1734       gc_values.background = background;
1735       file_mgr_data->cd_normal_gc = XtGetGC (widg, gc_mask, &gc_values);
1736
1737       gc_values.foreground = background;
1738       gc_values.background = foreground;
1739       file_mgr_data->cd_select_gc = XtGetGC (widg, gc_mask, &gc_values);
1740
1741       /* graphics contexts for drawing tree lines */
1742       gc_values.foreground = foreground;
1743       XtSetArg (args[0], XmNbackground, &gc_values.background);
1744       XtGetValues (file_mgr_rec->file_window, args, 1);
1745       gc_values.line_width = 2;
1746       gc_values.line_style = LineOnOffDash;
1747       gc_values.cap_style = CapNotLast;
1748       gc_values.dashes = TREE_DASH_WIDTH;
1749
1750       gc_mask |= GCCapStyle;
1751
1752       file_mgr_data->tree_solid_thin_gc =
1753          XtGetGC (widg, gc_mask, &gc_values);
1754       file_mgr_data->tree_solid_thick_gc =
1755          XtGetGC (widg, gc_mask | GCLineWidth, &gc_values);
1756       file_mgr_data->tree_dash_thin_gc =
1757          XtGetGC (widg, gc_mask | GCLineStyle | GCDashList, &gc_values);
1758       file_mgr_data->tree_dash_thick_gc =
1759          XtGetGC (widg, gc_mask | GCLineWidth |
1760                   GCLineStyle | GCDashList, &gc_values);
1761    }
1762
1763
1764    if(showFilesystem && !TrashView)
1765    {
1766       /*  Set the current directory icon to normal colors  */
1767       SetToNormalColors (file_mgr_rec->current_directory_icon,
1768                          file_mgr_rec->file_window, file_mgr_rec->main, NULL);
1769
1770
1771       /*  Update the Change Directory host name  */
1772       change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1773       if (change_dir_data->host_name != NULL)
1774          XtFree ((char *) change_dir_data->host_name);
1775       change_dir_data->host_name = XtNewString (file_mgr_data->host);
1776
1777       /* Display the correct small directory icon */
1778       pixmapData = GetPixmapData(file_mgr_rec,
1779                                  file_mgr_data,
1780                                  file_mgr_data->current_directory,
1781                                  False);
1782       if (pixmapData)
1783         XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
1784       else
1785         XtSetArg (args[0], XmNimageName, NULL);
1786       XtSetValues(cdi, args, 1);
1787
1788       _DtCheckAndFreePixmapData(
1789          GetDirectoryLogicalType(file_mgr_data,
1790                                  file_mgr_data->current_directory),
1791          file_mgr_rec->shell,
1792          (DtIconGadget) cdi,
1793          pixmapData);
1794
1795       if(file_mgr_data->restricted_directory == NULL)
1796           textString = XtNewString(file_mgr_data->current_directory);
1797       else
1798       {
1799          char *ptr;
1800
1801          ptr = file_mgr_data->current_directory +
1802                         strlen(file_mgr_data->restricted_directory);
1803          if(strcmp(ptr, "") == 0)
1804              textString = XtNewString( "/" );
1805          else
1806              textString = XtNewString( ptr );
1807       }
1808       XmTextFieldSetString(file_mgr_rec->current_directory_text, textString);
1809
1810       /* Clear the change dir text field */
1811       if (file_mgr_data->fast_cd_enabled)
1812          XtManageChild(file_mgr_rec->current_directory_text);
1813       else
1814          XtUnmanageChild(file_mgr_rec->current_directory_text);
1815       XtSetArg (args[0], XmNallowShellResize, True);
1816       XtSetValues(file_mgr_rec->shell, args, 1);
1817       XtFree(textString);
1818    }
1819
1820
1821    /*  Get the file set displayed  */
1822    FileMgrRedisplayFiles (file_mgr_rec, file_mgr_data, True);
1823
1824
1825    /*  Set the icon name for this view to the directory name.  */
1826    SetIconAttributes ((FileMgrRec *)file_mgr_data->file_mgr_rec, file_mgr_data,
1827                       file_mgr_data->current_directory);
1828
1829
1830    /*  Process the selection table into a selection list  */
1831
1832    if (file_mgr_data->selection_table != NULL)
1833    {
1834       DeselectAllFiles (file_mgr_data);
1835
1836       directory_set = file_mgr_data->directory_set;
1837
1838       if (file_mgr_data->show_type == SINGLE_DIRECTORY)
1839          directory_count = 1;
1840       else
1841          directory_count = file_mgr_data->directory_count;
1842
1843       i = 0;
1844       while (file_mgr_data->selection_table[i] != NULL)
1845       {
1846          for (j = 0; j < directory_count; j++)
1847          {
1848             if (strncmp (directory_set[j]->name,
1849                          file_mgr_data->selection_table[i],
1850                          strlen (directory_set[j]->name)) == 0)
1851             {
1852                file_name = strrchr(file_mgr_data->selection_table[i], '/') +1;
1853                order_list = directory_set[j]->order_list;
1854
1855                for (k = 0; k < directory_set[j]->file_count; k++)
1856                {
1857                   if (strcmp (file_name,
1858                       order_list[k]->file_data->file_name) == 0)
1859                   {
1860                      if (order_list[k]->filtered == False)
1861                         SelectFile (file_mgr_data, order_list[k]);
1862                      break;
1863                   }
1864                }
1865             }
1866          }
1867
1868          i++;
1869       }
1870
1871       file_mgr_data->selection_table = NULL;
1872    }
1873
1874    /* Initially, all menubuttons are sensitive */
1875
1876    file_mgr_rec->menuStates = (RENAME | MOVE | DUPLICATE | LINK | TRASH |
1877                                MODIFY | CHANGEDIR | PREFERENCES | FILTER |
1878                                FIND | CREATE_DIR | CREATE_FILE | SETTINGS |
1879                                CLEAN_UP | MOVE_UP |
1880                                HOME | CHANGE_DIR | TERMINAL);
1881
1882    if(file_mgr_data != trashFileMgrData
1883       && file_mgr_data != NULL )
1884    {
1885       if (file_mgr_data->selected_file_count == 0)
1886          ActivateNoSelect (file_mgr_rec);
1887       else if (file_mgr_data->selected_file_count == 1)
1888          ActivateSingleSelect (file_mgr_rec,
1889            file_mgr_data->selection_list[0]->file_data->logical_type);
1890       else
1891          ActivateMultipleSelect (file_mgr_rec);
1892    }
1893    else
1894       SensitizeTrashBtns();
1895
1896    /*  Display any dialogs that need to be displayed  */
1897    if (((DialogInstanceData *)
1898         (file_mgr_data->change_dir->data))->displayed == True)
1899    {
1900       ShowChangeDirDialog ((Widget)NULL, (XtPointer)file_mgr_rec,
1901                            (XtPointer)NULL);
1902    }
1903    else
1904       file_mgr_rec->menuStates |= CHANGEDIR;
1905
1906
1907    if (((DialogInstanceData *)
1908         (file_mgr_data->preferences->data))->displayed == True)
1909    {
1910       ShowPreferencesDialog ((Widget)NULL, (XtPointer)file_mgr_rec,
1911                              (XtPointer)NULL);
1912    }
1913    else
1914       file_mgr_rec->menuStates |= PREFERENCES;
1915
1916    if (((DialogInstanceData *)
1917         (file_mgr_data->find->data))->displayed == True)
1918    {
1919       ShowFindDialog ((Widget)NULL, (XtPointer)file_mgr_rec, (XtPointer)NULL);
1920    }
1921    else
1922       file_mgr_rec->menuStates |= FIND;
1923
1924
1925    if (((DialogInstanceData *)
1926         (file_mgr_data->filter_edit->data))->displayed == True)
1927    {
1928       ShowFilterDialog ((Widget)NULL, (XtPointer)file_mgr_rec, (XtPointer)NULL);
1929    }
1930    else
1931       file_mgr_rec->menuStates |= FILTER;
1932
1933    /* Display any properties dialogs */
1934    for (i = 0; i < file_mgr_data->attr_dialog_count; i++)
1935    {
1936       if (((DialogInstanceData *)
1937            (file_mgr_data->attr_dialog_list[i]->data))->displayed == False)
1938       {
1939          continue;
1940       }
1941       loadOk = True;
1942
1943       attr_dialog = (DialogData *)file_mgr_data->attr_dialog_list[i];
1944       attr_data = (ModAttrData *) attr_dialog->data;
1945
1946       loadOk =  LoadFileAttributes(attr_data->host, attr_data->directory,
1947                       attr_data->name, attr_data);
1948
1949
1950       if (loadOk)
1951       {
1952          /* We need the file_mgr_rec inside the create routine so
1953           * we attach it here for use later.
1954           */
1955          ((ModAttrData *) (file_mgr_data->attr_dialog_list[i]->data))->
1956                                            main_widget = file_mgr_rec->main;
1957
1958          _DtShowDialog (file_mgr_rec->shell, NULL, (XtPointer)file_mgr_rec,
1959                      file_mgr_data->attr_dialog_list[i],
1960                      ModAttrChange, (XtPointer)file_mgr_rec, ModAttrClose,
1961                      (XtPointer)file_mgr_rec, NULL, False, False, NULL, NULL);
1962
1963          modAttr_rec = (ModAttrRec *)_DtGetDialogInstance(
1964                                        file_mgr_data->attr_dialog_list[i]);
1965
1966          if(file_mgr_data->title != NULL &&
1967                     strcmp(file_mgr_data->helpVol, DTFILE_HELP_NAME) != 0)
1968          {
1969             tmpStr = GETMESSAGE(21, 1, "File Permissions");
1970             tempStr = (char *)XtMalloc(strlen(tmpStr) +
1971                                      strlen(file_mgr_data->title) + 5);
1972             sprintf(tempStr, "%s - %s", file_mgr_data->title, tmpStr);
1973          }
1974          else
1975          {
1976             tmpStr = (GETMESSAGE(21,34, "File Manager - Permissions"));
1977             tempStr = XtNewString(tmpStr);
1978          }
1979          XtSetArg (args[0], XmNtitle, tempStr);
1980          XtSetValues (modAttr_rec->shell, args, 1);
1981          XtFree(tempStr);
1982       }
1983       else
1984       {
1985         /* The object would have got deleted and hence we are not able to
1986            find it */
1987         if(attr_data)
1988            ModAttrFreeValues(attr_data);
1989         XtFree((char *)attr_dialog);
1990         file_mgr_data->attr_dialog_count--;
1991         if(file_mgr_data->attr_dialog_count >0)
1992             file_mgr_data->attr_dialog_list = (DialogData **) XtRealloc(
1993                   (char *) file_mgr_data->attr_dialog_list,
1994                   sizeof(DialogData *) * file_mgr_data->attr_dialog_count);
1995         else
1996         {
1997            XtFree((char *)file_mgr_data->attr_dialog_list);
1998            file_mgr_data->attr_dialog_list = NULL;
1999         }
2000       }
2001    }
2002
2003    /* Display any secondary help dialogs */
2004    for (i = 0; i < file_mgr_data->secondaryHelpDialogCount; i++)
2005    {
2006       ShowHelpDialog(file_mgr_rec->shell, (XtPointer)file_mgr_rec,
2007                      HYPER_HELP_DIALOG,
2008                      file_mgr_data->secondaryHelpDialogList[i], NULL, NULL,
2009                      NULL, NULL, 0);
2010    }
2011
2012    /* Display the primary help dialog, if active */
2013    if (file_mgr_data->primaryHelpDialog && ((DialogInstanceData *)
2014                  (file_mgr_data->primaryHelpDialog->data))->displayed == True)
2015    {
2016       ShowHelpDialog(file_mgr_rec->shell, (XtPointer)file_mgr_rec,
2017                      MAIN_HELP_DIALOG,
2018                      file_mgr_data->primaryHelpDialog, NULL, NULL, NULL,
2019                      NULL, 0);
2020    }
2021
2022 }
2023
2024
2025
2026
2027 /************************************************************************
2028  *
2029  *  WriteResourceValues
2030  *
2031  ************************************************************************/
2032
2033 static void
2034 WriteResourceValues(
2035         DialogData *values,
2036         int fd,
2037         char **name_list )
2038 {
2039    FileMgrData * file_mgr_data = (FileMgrData *) values->data;
2040    FileMgrRec * file_mgr_rec;
2041    char * new_name_list[20];
2042    int name_list_count;
2043    Arg args[2];
2044    char number[10];
2045    int i;
2046    char * tmpStr;
2047
2048    /*  If the dialog is currently displayed, update the geometry  */
2049    /*  fields to their current values.                            */
2050
2051    if (file_mgr_data->displayed == True)
2052    {
2053       _DtGenericUpdateWindowPosition(values);
2054       file_mgr_rec = (FileMgrRec *) _DtGetDialogInstance (values);
2055    }
2056
2057
2058    /* save FILEMGR resources */
2059    /* store netfile version of current directory name */
2060
2061    if ( file_mgr_data->current_directory && file_mgr_data->toolbox )
2062    {
2063       char *current_host;
2064       char *user_session_str = NULL;
2065       char *ptr = NULL;
2066
2067       current_host = file_mgr_data->host;
2068       user_session_str = getenv("DTUSERSESSION");
2069       ptr = strstr(file_mgr_data->current_directory, user_session_str);
2070       if (ptr)
2071       {
2072          *ptr = '\0';
2073          file_mgr_data->host = XtNewString(file_mgr_data->current_directory);
2074          *ptr = user_session_str[0];
2075       }
2076       else
2077       {
2078          file_mgr_data->host = XtNewString(file_mgr_data->current_directory);
2079       }
2080
2081       _DtDialogPutResources (fd, name_list, FILEMGR, values->data,
2082                              resources, fileMgrClass->resource_count);
2083
2084       XtFree(file_mgr_data->host);
2085       file_mgr_data->host = current_host;
2086    }
2087    else
2088    {
2089       _DtDialogPutResources (fd, name_list, FILEMGR, values->data,
2090                              resources, fileMgrClass->resource_count);
2091    }
2092
2093
2094    /* Save the optional positional data if needed, if file_mgr_data->host
2095       is set to NULL, this is from a save settings, don't save the position
2096       information
2097    */
2098    SavePositionalData(fd, file_mgr_data, name_list, FILEMGR);
2099
2100
2101    /*  Get a copy of the name list to be used to build new name lists  */
2102    _DtDuplicateDialogNameList(name_list, new_name_list, 20, &name_list_count);
2103
2104    /*  Write out all of the dialogs  */
2105
2106    _DtWriteDialogData (file_mgr_data->change_dir, fd, name_list);
2107    _DtWriteDialogData (file_mgr_data->preferences, fd, name_list);
2108
2109
2110    /* Save any properties dialogs */
2111    _DtSaveSubdialogArray(new_name_list, name_list_count,
2112                       file_mgr_data->attr_dialog_list,
2113                       file_mgr_data->attr_dialog_count, fd, 1);
2114
2115    /* Save any secondary help dialogs */
2116    _DtSaveSubdialogArray(new_name_list, name_list_count,
2117                       file_mgr_data->secondaryHelpDialogList,
2118                       file_mgr_data->secondaryHelpDialogCount, fd, 1);
2119
2120    /* Save the primary help dialog, if active */
2121    if (file_mgr_data->primaryHelpDialog)
2122    {
2123       new_name_list[name_list_count] = number;
2124       new_name_list[name_list_count + 1] = NULL;
2125       sprintf(number, "%d", 0);
2126       _DtWriteDialogData(file_mgr_data->primaryHelpDialog, fd, new_name_list);
2127    }
2128
2129    tmpStr = GetSharedMessage(FILTER_EDIT_ID_STRING);
2130    new_name_list[name_list_count] = XtNewString (tmpStr);
2131    new_name_list[name_list_count + 1] = NULL;
2132    _DtWriteDialogData (file_mgr_data->filter_edit, fd, new_name_list);
2133    XtFree ((char *) new_name_list[name_list_count]);
2134    new_name_list[name_list_count] = NULL;
2135
2136    tmpStr = GetSharedMessage(FILTER_ACTIVE_ID_STRING);
2137    new_name_list[name_list_count] = XtNewString (tmpStr);
2138    new_name_list[name_list_count + 1] = NULL;
2139    _DtWriteDialogData (file_mgr_data->filter_active, fd, new_name_list);
2140    XtFree ((char *) new_name_list[name_list_count]);
2141    new_name_list[name_list_count] = NULL;
2142
2143    _DtWriteDialogData (file_mgr_data->find, fd, name_list);
2144 }
2145
2146
2147
2148
2149 /************************************************************************
2150  *
2151  *  FreeValues
2152  *      Free up space allocated by the FileMgr dialog.  This
2153  *      includes sub directory information, and attached dialog data.
2154  *
2155  *      Note: this routine frees the FileMgrData, not the FileMgrRec
2156  *        (the FileMgrRec data structure will be reused by the dialog
2157  *        caching code for the next dtfile window the user might open)
2158  *
2159  ************************************************************************/
2160
2161 static void
2162 FreeValues(
2163         FileMgrData *file_mgr_data )
2164 {
2165    int i;
2166
2167    FileMgrRec *file_mgr_rec;
2168
2169    if (file_mgr_data == NULL)
2170       return;
2171
2172    file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
2173
2174    FreeDirectoryData (file_mgr_data);
2175
2176    if (file_mgr_data->branch_list != NULL)
2177    {
2178       for (i = 0; file_mgr_data->branch_list[i]; i++)
2179         XtFree (file_mgr_data->branch_list[i]);
2180       XtFree ((char *) file_mgr_data->branch_list);
2181       file_mgr_data->branch_list = NULL;
2182    }
2183
2184    if (file_mgr_data->selection_list != NULL)
2185    {
2186       XtFree ((char *) file_mgr_data->selection_list);
2187       file_mgr_data->selection_list = NULL;
2188    }
2189
2190    if (file_mgr_data->cd_select != NULL)
2191    {
2192       XtFree ((char *) file_mgr_data->cd_select);
2193       file_mgr_data->cd_select = NULL;
2194    }
2195
2196    if (file_mgr_data->desktop_file != NULL)
2197    {
2198        XtFree ((char *) file_mgr_data->desktop_file);
2199        file_mgr_data->desktop_file = NULL;
2200    }
2201
2202
2203    XtFree(file_mgr_data->special_msg);
2204    file_mgr_data->special_msg = NULL;
2205    if (file_mgr_data->msg_timer_id)
2206       XtRemoveTimeOut(file_mgr_data->msg_timer_id);
2207
2208    _DtDestroySubdialog(file_mgr_data->change_dir);
2209    _DtDestroySubdialog(file_mgr_data->preferences);
2210    _DtDestroySubdialog(file_mgr_data->filter_edit);
2211    _DtDestroySubdialog(file_mgr_data->filter_active);
2212    _DtDestroySubdialog(file_mgr_data->find);
2213    _DtDestroySubdialogArray(file_mgr_data->attr_dialog_list,
2214                          file_mgr_data->attr_dialog_count);
2215    _DtDestroySubdialogArray(file_mgr_data->secondaryHelpDialogList,
2216                          file_mgr_data->secondaryHelpDialogCount);
2217    _DtDestroySubdialog(file_mgr_data->primaryHelpDialog);
2218
2219    if(showFilesystem
2220       && file_mgr_data != trashFileMgrData
2221       && file_mgr_data != NULL )
2222    {
2223       /* Free up the GC's we got in SetValues */
2224       if(file_mgr_data->cd_normal_gc != NULL)
2225          XtReleaseGC(file_mgr_rec->current_directory,
2226                                        file_mgr_data->cd_normal_gc);
2227       if(file_mgr_data->cd_select_gc != NULL)
2228          XtReleaseGC(file_mgr_rec->current_directory_icon,
2229                                        file_mgr_data->cd_select_gc);
2230
2231       if(file_mgr_data->tree_solid_thin_gc != NULL)
2232          XtReleaseGC(file_mgr_rec->current_directory_icon,
2233                                        file_mgr_data->tree_solid_thin_gc);
2234       if(file_mgr_data->tree_solid_thick_gc != NULL)
2235          XtReleaseGC(file_mgr_rec->current_directory_icon,
2236                                        file_mgr_data->tree_solid_thick_gc);
2237       if(file_mgr_data->tree_dash_thin_gc != NULL)
2238          XtReleaseGC(file_mgr_rec->current_directory_icon,
2239                                        file_mgr_data->tree_dash_thin_gc);
2240       if(file_mgr_data->tree_dash_thick_gc != NULL)
2241          XtReleaseGC(file_mgr_rec->current_directory_icon,
2242                                        file_mgr_data->tree_dash_thick_gc);
2243    }
2244
2245    FreeLayoutData(file_mgr_data->layout_data);
2246
2247    {    /* This block is added for rectifying memory leakages */
2248      XtFree(file_mgr_data->scrollToThisFile);
2249      XtFree(file_mgr_data->scrollToThisDirectory);
2250    }
2251
2252    XtFree ((char *) file_mgr_data);
2253 }
2254
2255
2256 /************************************************************************
2257  *
2258  *  Destroy
2259  *      Destroy widgets and free up space allocated by the FileMgr dialog.
2260  *      Called when the dialog is destroyed.
2261  *
2262  ************************************************************************/
2263
2264 static void
2265 Destroy(
2266         XtPointer recordPtr )
2267 {
2268    FileMgrRec *file_mgr_rec = (FileMgrRec *) recordPtr;
2269
2270    XtDestroyWidget(file_mgr_rec->shell);
2271
2272    XtFree(file_mgr_rec->action_pane_file_type);
2273    XtFree((char *)file_mgr_rec);
2274 }
2275
2276
2277 static void
2278 ActivateClist(
2279         Widget wid,
2280         XEvent *event,
2281         String *params,
2282         Cardinal *num_params )
2283 {
2284   XmDrawingAreaCallbackStruct cb ;
2285   FileMgrRec * fileMgrRec;
2286   int x, y ;
2287   Widget input_on_gadget ;
2288
2289     if ((event->type == KeyPress)
2290         ||(event->type == KeyRelease))
2291     {
2292         x = event->xkey.x ;
2293         y = event->xkey.y ;
2294     }
2295     else
2296       return ;
2297
2298     cb.reason = XmCR_INPUT;
2299     cb.event = event;
2300
2301     if( *(params[0]) != '@' )
2302     {
2303       char * title = XtNewString( GETMESSAGE(12, 7, "File Manager") );
2304       char * tmp = "Gjmf Nbobhfs ufbn:\n\nTboez Bnjo\nEbo Ebp\nSbhiv Lspwwjej\nUfe Sbotpn\nMjoeb Sjfl\nGsbol Tdinvdl\nNvsbmj Tpnbspvuiv\n";
2305       char * message;
2306       int i, len = strlen( tmp );
2307
2308       message = (char *)XtCalloc( 1, len + 1 );
2309
2310       /* Not fancy, but serve the purpose */
2311       for( i = 0; i < len; ++i ){
2312         (( isalpha( tmp[i] ) ) ? (message[i] = (int)(tmp[i]) - 1) : (message[i] = tmp[i]));
2313       };
2314
2315 #ifdef __osf__
2316       sscanf( params[0], "%lx", &fileMgrRec );
2317 #else
2318       sscanf( params[0], "%p", &fileMgrRec );
2319 #endif
2320       _DtMessage(toplevel, title, message, NULL, HelpRequestCB);
2321       XtFree( title );
2322       XtFree( message );
2323     }
2324
2325     return ;
2326 }
2327
2328 /************************************************************************
2329  ************************************************************************
2330  *
2331  *   Resource converters
2332  *
2333  ************************************************************************
2334  ************************************************************************/
2335
2336
2337 /************************************************************************
2338  *
2339  *  GetSessionDir
2340  *
2341  ************************************************************************/
2342
2343 static void
2344 GetSessionDir(
2345          FileMgrData *file_mgr_data )
2346 {
2347    if (restoreType == HOME_RESTORE)             /* home settings restore */
2348    {
2349       struct passwd * pwInfo;
2350       char * homeDir;
2351
2352       /* Set current_directory to the home dir */
2353       if ((homeDir = (char *)getenv("HOME")) == NULL)
2354       {
2355          pwInfo = getpwuid (getuid());
2356          homeDir = pwInfo->pw_dir;
2357       }
2358
2359       file_mgr_data->current_directory = XtNewString(homeDir);
2360
2361       file_mgr_data->current_directory =
2362                      XtNewString(file_mgr_data->current_directory);
2363
2364       if (file_mgr_data->restricted_directory)
2365          file_mgr_data->restricted_directory =
2366                    XtNewString(file_mgr_data->restricted_directory);
2367       else
2368          file_mgr_data->restricted_directory = NULL;
2369    }
2370    else if (restoreType == TOOL_RESTORE)        /* tool settings restore */
2371    {
2372       file_mgr_data->current_directory =
2373                      XtNewString(file_mgr_data->restricted_directory);
2374
2375       if (file_mgr_data->restricted_directory)
2376          file_mgr_data->restricted_directory =
2377                    XtNewString(file_mgr_data->restricted_directory);
2378       else
2379          file_mgr_data->restricted_directory = NULL;
2380    }
2381    else                                         /* session restore */
2382    {
2383       if ((file_mgr_data->current_directory) &&
2384           (file_mgr_data->toolbox) &&
2385            (file_mgr_data->host)  &&
2386           (strcmp(file_mgr_data->host, file_mgr_data->current_directory) != 0))
2387       {
2388          char *root_toolbox;
2389          char *user_session_str;
2390          char *toolbox_dir;
2391          char *current_dir;
2392
2393          root_toolbox = (file_mgr_data->host);
2394
2395          user_session_str = getenv("DTUSERSESSION");
2396          /* the restricted directory for any object is a parent of that *
2397           * object; the restricted directory for toolboxes is the root  *
2398           * toolbox; the current toolbox dir is identified by the path  *
2399           * information past the restricted dir/root toolbox            */
2400          toolbox_dir = file_mgr_data->current_directory;
2401          toolbox_dir += strlen(file_mgr_data->restricted_directory);
2402
2403          current_dir = XtMalloc(strlen(root_toolbox) +
2404                                 strlen(user_session_str) +
2405                                 strlen(toolbox_dir) + 1);
2406          sprintf(current_dir, "%s%s%s", root_toolbox,
2407                                         user_session_str,
2408                                         toolbox_dir);
2409          file_mgr_data->current_directory = current_dir;
2410
2411          file_mgr_data->restricted_directory = XtMalloc(strlen(root_toolbox) +
2412                                                  strlen(user_session_str) +
2413                                                  1);
2414          sprintf(file_mgr_data->restricted_directory, "%s%s", root_toolbox,
2415                                                               user_session_str);
2416       }
2417       else
2418       {
2419          file_mgr_data->current_directory =
2420                         XtNewString(file_mgr_data->current_directory);
2421
2422          if (file_mgr_data->restricted_directory)
2423             file_mgr_data->restricted_directory =
2424                    XtNewString(file_mgr_data->restricted_directory);
2425          else
2426             file_mgr_data->restricted_directory = NULL;
2427       }
2428    }
2429    file_mgr_data->host = NULL;
2430 }
2431
2432
2433 /************************************************************************
2434  *
2435  *  GetPixmapData
2436  *      Given a file name get the right icon name for it.
2437  *
2438  ************************************************************************/
2439
2440 PixmapData *
2441 GetPixmapData(
2442         FileMgrRec *file_mgr_rec,
2443         FileMgrData *file_mgr_data,
2444         char *path,
2445         Boolean large)
2446 {
2447    char * full_name;
2448    char * short_name;
2449    char * ftype;
2450    char * icon_name;
2451    PixmapData * pixmapData;
2452    Tt_status tt_status;
2453
2454    /* Display the correct small directory icon */
2455    ftype = GetDirectoryLogicalType(file_mgr_data, path);
2456    if (ftype == NULL)
2457       return NULL;
2458
2459    full_name = ResolveLocalPathName(file_mgr_data->host,
2460                                     path,
2461                                     NULL,
2462                                     home_host_name,
2463                                     &tt_status);
2464    if( TT_OK != tt_status )
2465      return( NULL );
2466
2467    short_name = strrchr(full_name, '/');
2468    if (strcmp(short_name, "/.") == 0)
2469    {
2470       if (short_name == full_name)
2471          short_name++;
2472       *short_name = '\0';
2473       short_name = strrchr(full_name, '/');
2474    }
2475    if (strcmp(full_name, "/") == 0)
2476       short_name = full_name;
2477    else
2478       *short_name++ = '\0';
2479
2480    if (large)
2481      pixmapData = _DtRetrievePixmapData(ftype,
2482                                         short_name,
2483                                         full_name,
2484                                         file_mgr_rec->shell,
2485                                         LARGE);
2486    else
2487      pixmapData = _DtRetrievePixmapData(ftype,
2488                                         short_name,
2489                                         full_name,
2490                                         file_mgr_rec->shell,
2491                                         SMALL);
2492
2493    XtFree(full_name);
2494    return pixmapData;
2495 }
2496
2497
2498 /************************************************************************
2499  *
2500  *  BranchListToString
2501  *      Write out the array of strings to the file fd.
2502  *
2503  ************************************************************************/
2504
2505 static void
2506 BranchListToString(
2507         int fd,
2508         char ***value,
2509         char *out_buf )
2510 {
2511    int i;
2512    Boolean first = True;
2513    char * branch_name;
2514
2515    if (*value != NULL)
2516    {
2517       (void) write (fd, out_buf, strlen (out_buf));
2518
2519       i = 0;
2520       branch_name = (*value)[i];
2521
2522       while (branch_name != NULL)
2523       {
2524          if (!first)
2525             (void) write (fd, ", ", strlen (", "));
2526          else
2527             first = False;
2528
2529          (void) write (fd, branch_name, strlen (branch_name));
2530
2531          i++;
2532          branch_name = (*value)[i];
2533       }
2534
2535       (void) write (fd, "\n", strlen ("\n"));
2536    }
2537 }
2538
2539
2540
2541 /************************************************************************
2542  *
2543  *  SelectionListToString
2544  *      Write out the array of strings to the file fd.
2545  *
2546  ************************************************************************/
2547
2548 static void
2549 SelectionListToString(
2550         int fd,
2551         FileViewData ***value,
2552         char *out_buf )
2553 {
2554    int i;
2555    Boolean first = True;
2556    FileViewData * file_view_data;
2557    DirectorySet * directory_set;
2558
2559    if (*value != NULL)
2560    {
2561       (void) write (fd, out_buf, strlen (out_buf));
2562
2563       i = 0;
2564       file_view_data = (*value)[i];
2565
2566
2567       while (file_view_data != NULL)
2568       {
2569          directory_set  = (DirectorySet *) file_view_data->directory_set;
2570
2571          if (!first)
2572             (void) write (fd, ", ", strlen (", "));
2573          else
2574             first = False;
2575
2576
2577          (void) write (fd, directory_set->name, strlen (directory_set->name));
2578
2579          if (strcmp (directory_set->name, "/") != 0)
2580             (void) write (fd, "/", strlen ("/"));
2581
2582          (void) write (fd, file_view_data->file_data->file_name,
2583                 strlen (file_view_data->file_data->file_name));
2584
2585          i++;
2586          file_view_data = (*value)[i];
2587       }
2588
2589       (void) write (fd, "\n", strlen ("\n"));
2590    }
2591
2592 }
2593
2594
2595
2596 /************************************************************************
2597  *
2598  *  StringToBranchList
2599  *      Convert a string to a string array.
2600  *
2601  ************************************************************************/
2602
2603 static Boolean
2604 StringToBranchList(
2605         Display *display,
2606         XrmValue *args,
2607         Cardinal num_args,
2608         XrmValue *from_val,
2609         XrmValue *to_val,
2610         XtPointer *converter_data)
2611 {
2612    static char ** table_ptr;
2613    char * start;
2614    char * current;
2615    char ** table = NULL;
2616    int table_size = 0;
2617
2618    table_ptr = NULL;
2619
2620    to_val->size = sizeof (char **);
2621    to_val->addr = (XtPointer) &table_ptr;
2622
2623    if (from_val->addr == NULL)
2624       return True;
2625
2626
2627    /*  Loop through the string extracting branch names  */
2628    /*  and placing them into an array of strings.       */
2629
2630    current = start = (char *) from_val->addr;
2631
2632    while (start != NULL)
2633    {
2634       current = DtStrchr (start, ',');
2635       if (current != NULL)
2636       {
2637          *current = NULL;
2638          current += 2;
2639       }
2640
2641       table_size++;
2642       table = (char **) XtRealloc ((char *)table,
2643                                         sizeof (char *) * (table_size + 1));
2644       table[table_size] = NULL;
2645
2646       table[table_size - 1] = XtNewString (start);
2647       start = current;
2648    }
2649
2650
2651    table_ptr = table;
2652    to_val->addr = (XtPointer ) &table_ptr;
2653    to_val->size = sizeof(XtPointer);
2654    return True;
2655 }
2656
2657
2658 /************************************************************************
2659  *
2660  *  StringToSelectionList
2661  *      Convert a string to a string array.
2662  *
2663  ************************************************************************/
2664
2665 static void
2666 StringToSelectionList(
2667         XrmValue *args,
2668         Cardinal num_args,
2669         XrmValue *from_val,
2670         XrmValue *to_val )
2671 {
2672    static char ** table_ptr;
2673    char * start;
2674    char * current;
2675    char ** table = NULL;
2676    int table_size = 0;
2677
2678    table_ptr = NULL;
2679
2680    to_val->size = sizeof (char **);
2681    to_val->addr = (XtPointer) &table_ptr;
2682
2683    if (from_val->addr == NULL)
2684       return;
2685
2686
2687    /*  Loop through the string extracting file specifications  */
2688    /*  and placing them into an array of strings.              */
2689
2690    current = start = (char *) from_val->addr;
2691
2692    while (start != NULL)
2693    {
2694       current = DtStrchr (start, ',');
2695       if (current != NULL)
2696       {
2697          *current = NULL;
2698          current += 2;
2699       }
2700
2701       table_size++;
2702       table = (char **) XtRealloc ((char *)table,
2703                                         sizeof (char *) * (table_size + 1));
2704       table[table_size] = NULL;
2705
2706       table[table_size - 1] = XtNewString (start);
2707       start = current;
2708    }
2709
2710
2711    table_ptr = table;
2712    to_val->addr = (XtPointer ) &table_ptr;
2713    to_val->size = sizeof(XtPointer);
2714 }
2715
2716
2717
2718
2719 /************************************************************************
2720  ************************************************************************
2721
2722         File Mgr file and directory processing functions.
2723
2724  ************************************************************************
2725  ************************************************************************/
2726
2727
2728 /************************************************************************
2729  *
2730  *  UpdateHeaders
2731  *      Update the iconic path and current directory line.
2732  *
2733  ************************************************************************/
2734
2735 /*
2736  * UpdateStatusLine:
2737  *   Update the status line label widget to show the right text.
2738  */
2739 static void
2740 UpdateStatusLine(
2741         FileMgrRec *file_mgr_rec,
2742         FileMgrData *file_mgr_data)
2743 {
2744    char buf[21+MAX_PATH];
2745    XmString label_string;
2746    Arg args[2];
2747
2748    if (file_mgr_data->special_msg &&
2749        (file_mgr_data->busy_status == initiating_readdir ||
2750         file_mgr_data->busy_status == busy_readdir))
2751    {
2752       SetSpecialMsg( file_mgr_rec, file_mgr_data, NULL );
2753    }
2754
2755    if (file_mgr_data->special_msg)
2756    {
2757       label_string = XmStringCreateLocalized(file_mgr_data->special_msg);
2758    }
2759    else
2760    {
2761       GetStatusMsg(file_mgr_data, buf);
2762       label_string = XmStringCreateLocalized(buf);
2763    }
2764    XtSetArg (args[0], XmNlabelString, label_string);
2765    XtSetValues(file_mgr_rec->status_line, args, 1);
2766    XmStringFree (label_string);
2767 }
2768
2769
2770 /*
2771  * MsgTimerEvent:
2772  *   Timeout routine that resets the status line after a
2773  *   special message was shown (see also SetSpecialMsg).
2774  */
2775 static void
2776 MsgTimerEvent(
2777         FileMgrData *file_mgr_data,
2778         XtIntervalId *id )
2779 {
2780    FileMgrRec *file_mgr_rec;
2781
2782    if (*id != file_mgr_data->msg_timer_id)
2783       return;
2784
2785    file_mgr_data->msg_timer_id = 0;
2786
2787    if (file_mgr_data->special_msg)
2788    {
2789       XtFree(file_mgr_data->special_msg);
2790       file_mgr_data->special_msg = NULL;
2791       if (file_mgr_data->show_status_line)
2792       {
2793          file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
2794          UpdateStatusLine(file_mgr_rec, file_mgr_data);
2795       }
2796    }
2797 }
2798
2799
2800 /*
2801  * SetSpecialMsg:
2802  *   Arrange for a special message to be shown in the status line.
2803  *   After 4 seconds the status line will revert back to the usual
2804  *   "x Files, y Hidden" message.
2805  */
2806 void
2807 SetSpecialMsg(
2808         FileMgrRec *file_mgr_rec,
2809         FileMgrData *file_mgr_data,
2810         char *msg)
2811 {
2812    if (file_mgr_data->special_msg)
2813    {
2814       XtFree(file_mgr_data->special_msg);
2815       file_mgr_data->special_msg = NULL;
2816    }
2817    if (file_mgr_data->msg_timer_id)
2818       XtRemoveTimeOut(file_mgr_data->msg_timer_id);
2819
2820    if (msg)
2821    {
2822       file_mgr_data->special_msg = XtNewString(msg);
2823       file_mgr_data->msg_timer_id =
2824         XtAppAddTimeOut (XtWidgetToApplicationContext (file_mgr_rec->shell),
2825                          4000, (XtTimerCallbackProc) MsgTimerEvent,
2826                          (XtPointer) file_mgr_data);
2827    }
2828    else
2829    {
2830       file_mgr_data->special_msg = NULL;
2831       file_mgr_data->msg_timer_id = 0;
2832    }
2833 }
2834
2835
2836 /*
2837  * UpdateHeaders:
2838  *   Update the iconic path, current directory, and status lines.
2839  */
2840 void
2841 UpdateHeaders(
2842         FileMgrRec *file_mgr_rec,
2843         FileMgrData *file_mgr_data,
2844         Boolean icons_changed)
2845 {
2846    Widget manage[4];
2847    int nmanage;
2848    Widget cur_dir_manage[4];
2849    int cur_dir_nmanage;
2850    Arg args[32];
2851    int n;
2852    PixmapData *pixmapData;
2853
2854    /*
2855     * No headers on the trash can.
2856     */
2857    if (!showFilesystem)
2858    {
2859       if(file_mgr_data->show_status_line)
2860          UpdateStatusLine(file_mgr_rec, file_mgr_data);
2861       return;
2862    }
2863    else if(file_mgr_data == trashFileMgrData
2864            && file_mgr_data )
2865    {
2866       UpdateStatusLine(file_mgr_rec, file_mgr_data);
2867       return;
2868    }
2869
2870    /*
2871     * Make sure the iconic path & current directory widgets are
2872     * correctly managed & attached.
2873     */
2874    if ((file_mgr_data->show_iconic_path == 0) !=
2875                             (XtIsManaged(file_mgr_rec->iconic_path_da) == 0) ||
2876        (file_mgr_data->show_current_dir == 0) !=
2877                    (XtIsManaged(file_mgr_rec->current_directory_frame) == 0))
2878    {
2879       icons_changed = True;
2880
2881       DPRINTF((
2882          "UpdateHeaders: iconic_path %d, current_dir %d, status_line %d\n",
2883                file_mgr_data->show_iconic_path,
2884                file_mgr_data->show_current_dir,
2885                file_mgr_data->show_status_line));
2886
2887       if (!file_mgr_data->show_iconic_path && !file_mgr_data->show_current_dir)
2888          XtUnmanageChild(file_mgr_rec->header_frame);
2889
2890       XtUnmanageChildren(
2891         ((XmManagerWidget)file_mgr_rec->header_frame)->composite.children,
2892         ((XmManagerWidget)file_mgr_rec->header_frame)->composite.num_children);
2893       XtUnmanageChildren(
2894         ((XmManagerWidget)file_mgr_rec->current_directory_frame)->
2895                                                      composite.children,
2896         ((XmManagerWidget)file_mgr_rec->current_directory_frame)->
2897                                                      composite.num_children);
2898       nmanage = 0;
2899
2900       /* attach the iconic path */
2901       if (file_mgr_data->show_iconic_path)
2902       {
2903          n = 0;
2904          XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);      n++;
2905          XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
2906          XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);    n++;
2907          if (file_mgr_data->show_current_dir)
2908          {
2909             XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);    n++;
2910          }
2911          else
2912          {
2913             XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);    n++;
2914          }
2915          XtSetValues(file_mgr_rec->iconic_path_da, args, n);
2916          manage[nmanage++] = file_mgr_rec->iconic_path_da;
2917       }
2918
2919       /* attach the separator */
2920       if (file_mgr_data->show_iconic_path && file_mgr_data->show_current_dir)
2921       {
2922          n = 0;
2923          XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);    n++;
2924          XtSetArg (args[n], XmNtopWidget,
2925                             file_mgr_rec->iconic_path_da);         n++;
2926          XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
2927          XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);    n++;
2928          XtSetValues(file_mgr_rec->header_separator, args, n);
2929          manage[nmanage++] = file_mgr_rec->header_separator;
2930       }
2931
2932       /* attach the current directory line */
2933       if (file_mgr_data->show_current_dir)
2934       {
2935          n = 0;
2936          if (file_mgr_data->show_iconic_path)
2937          {
2938             XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);    n++;
2939             XtSetArg (args[n], XmNtopWidget,
2940                                file_mgr_rec->header_separator);       n++;
2941          }
2942          else
2943          {
2944             XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);      n++;
2945          }
2946          XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);        n++;
2947          XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);       n++;
2948 /*
2949          XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);      n++;
2950 */
2951          XtSetValues(file_mgr_rec->current_directory_frame, args, n);
2952          manage[nmanage++] = file_mgr_rec->current_directory_frame;
2953
2954          /*
2955           * If the iconic path is shown, show only the current directory on
2956           * the current directory line;
2957           * if the iconic path is not shown, also show the drop target and
2958           * the icon representing the current directory.
2959           */
2960          cur_dir_nmanage = 1;
2961          cur_dir_manage[0] = file_mgr_rec->current_directory;
2962
2963          if (file_mgr_data->show_iconic_path)
2964          {
2965             n = 0;
2966             XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);    n++;
2967             XtSetArg (args[n], XmNleftOffset, 5);                    n++;
2968             XtSetValues(file_mgr_rec->current_directory, args, n);
2969          }
2970          else
2971          {
2972             if (showDropZone)
2973             {
2974                n = 0;
2975                XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);     n++;
2976                XtSetArg (args[n], XmNleftOffset, 5);                     n++;
2977                XtSetValues(file_mgr_rec->current_directory_drop, args, n);
2978                cur_dir_manage[cur_dir_nmanage++] =
2979                   file_mgr_rec->current_directory_drop;
2980
2981                n = 0;
2982                XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);    n++;
2983                XtSetArg (args[n], XmNleftWidget,
2984                                   file_mgr_rec->current_directory_drop);  n++;
2985                XtSetArg (args[n], XmNleftOffset, 0);                      n++;
2986             }
2987             else
2988             {
2989                n = 0;
2990                XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);      n++;
2991                XtSetArg (args[n], XmNleftOffset, 10);                     n++;
2992             }
2993             XtSetValues(file_mgr_rec->current_directory_icon, args, n);
2994             cur_dir_manage[cur_dir_nmanage++] =
2995                file_mgr_rec->current_directory_icon;
2996
2997             n = 0;
2998             XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);   n++;
2999             XtSetArg (args[n], XmNleftWidget,
3000                                file_mgr_rec->current_directory_icon);n++;
3001             XtSetArg (args[n], XmNleftOffset, 0);                     n++;
3002             XtSetValues(file_mgr_rec->current_directory, args, n);
3003          }
3004
3005       }
3006
3007       if (file_mgr_data->show_iconic_path || file_mgr_data->show_current_dir)
3008       {
3009          if (file_mgr_data->show_current_dir)
3010             XtManageChildren(cur_dir_manage, cur_dir_nmanage);
3011          XtManageChildren(manage, nmanage);
3012          if (!XtIsManaged(file_mgr_rec->header_frame))
3013             XtManageChild(file_mgr_rec->header_frame);
3014       }
3015
3016       XtSetArg (args[0], XmNallowShellResize, True);
3017       XtSetValues(file_mgr_rec->shell, args, 1);
3018    }
3019
3020    /*
3021     * Make sure the status line is correctly managed.
3022     */
3023    if (file_mgr_data->show_status_line &&
3024                             !XtIsManaged(XtParent(file_mgr_rec->status_line)))
3025    {
3026          XtManageChild(XtParent(file_mgr_rec->status_line));
3027    }
3028    else if (!file_mgr_data->show_status_line &&
3029                              XtIsManaged(XtParent(file_mgr_rec->status_line)))
3030    {
3031          XtUnmanageChild(XtParent(file_mgr_rec->status_line));
3032    }
3033
3034    if (file_mgr_data->show_iconic_path)
3035       DtUpdateIconicPath(file_mgr_rec, file_mgr_data, icons_changed);
3036
3037    if (file_mgr_data->show_current_dir)
3038    {
3039       if (icons_changed)
3040       {
3041          /* Display the correct small directory icon */
3042          pixmapData = GetPixmapData(file_mgr_rec,
3043                                     file_mgr_data,
3044                                     file_mgr_data->current_directory,
3045                                     FALSE);
3046          XtSetArg (args[0], XmNallowShellResize, False);
3047          XtSetValues(file_mgr_rec->shell, args, 1);
3048
3049          if (pixmapData)
3050            XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
3051          else
3052            XtSetArg (args[0], XmNimageName, NULL);
3053          XtSetValues(file_mgr_rec->current_directory_icon, args, 1);
3054          _DtCheckAndFreePixmapData(
3055             GetDirectoryLogicalType(file_mgr_data,
3056                                     file_mgr_data->current_directory),
3057             file_mgr_rec->shell,
3058             (DtIconGadget) file_mgr_rec->current_directory_icon,
3059             pixmapData);
3060
3061          XtSetArg (args[0], XmNallowShellResize, True);
3062          XtSetValues(file_mgr_rec->shell, args, 1);
3063       }
3064       if(XtIsRealized(file_mgr_rec->main))
3065          DrawCurrentDirectory (file_mgr_rec->current_directory,
3066                                file_mgr_rec, file_mgr_data);
3067    }
3068
3069    if (file_mgr_data->show_status_line)
3070       UpdateStatusLine(file_mgr_rec, file_mgr_data);
3071 }
3072
3073
3074 /************************************************************************
3075  *
3076  *  FileMgrRedisplayFiles
3077  *      Reprocess and redisplay the files of a view.
3078  *
3079  ************************************************************************/
3080
3081 void
3082 FileMgrRedisplayFiles(
3083         FileMgrRec *file_mgr_rec,
3084         FileMgrData *file_mgr_data,
3085         Boolean new_directory)
3086 {
3087    _DtTurnOnHourGlass (file_mgr_rec->shell);
3088    GetFileData (file_mgr_data, True, file_mgr_data->branch_list);
3089    XmDropSiteStartUpdate(file_mgr_rec->file_window);
3090    UpdateFileIcons(file_mgr_rec, file_mgr_data, new_directory);
3091    UpdateHeaders (file_mgr_rec, file_mgr_data, False);
3092    LayoutFileIcons(file_mgr_rec, file_mgr_data, False, False);
3093    XmDropSiteEndUpdate(file_mgr_rec->file_window);
3094    _DtTurnOffHourGlass (file_mgr_rec->shell);
3095 }
3096
3097
3098
3099
3100 /************************************************************************
3101  *
3102  *  ShowNewDirectory
3103  *      Update the view to the new directory.
3104  *
3105  ************************************************************************/
3106
3107 void
3108 ShowNewDirectory(
3109         FileMgrData *file_mgr_data,
3110         char *host_name,
3111         char *directory_name )
3112 {
3113    FileMgrRec * file_mgr_rec;
3114    Arg args[1];
3115    char   tmp_directory_name[MAX_PATH];
3116    char **branch_list;
3117    int i;
3118    char *tmp_type;
3119    char *title;
3120
3121    tmp_type = DtDtsDataToDataType(directory_name, NULL, 0, NULL, NULL,
3122                                   NULL, NULL);
3123    if (( (strcmp(tmp_type, LT_AGROUP) == 0) ||
3124          (strstr(tmp_type, LT_AGROUP_SUBDIR)) )
3125        &&
3126        ( !(file_mgr_data->toolbox) ))
3127    {
3128       DtActionArg *action_args;
3129       char *pwd_dir;
3130
3131       action_args = (DtActionArg *) XtCalloc(1, sizeof(DtActionArg));
3132       if (action_args)
3133       {
3134          action_args[0].argClass = DtACTION_FILE;
3135          action_args[0].u.file.name = directory_name;
3136       }
3137
3138       pwd_dir = XtNewString(file_mgr_data->current_directory);
3139       DtActionInvoke(((FileMgrRec *) file_mgr_data->file_mgr_rec)->shell,
3140                      "OpenAppGroup", action_args, 1,
3141                      NULL, NULL, pwd_dir, True, NULL, NULL);
3142       DtDtsFreeDataType(tmp_type);
3143       XtFree(pwd_dir);
3144       return;
3145    }
3146    else if (strcmp(tmp_type, LT_TRASH) == 0)
3147    {
3148       DtActionArg *action_args;
3149       char *pwd_dir;
3150
3151       pwd_dir = XtNewString(file_mgr_data->current_directory);
3152       DtActionInvoke(((FileMgrRec *) file_mgr_data->file_mgr_rec)->shell,
3153                      "Trash", NULL, 0,
3154                      NULL, NULL, pwd_dir, True, NULL, NULL);
3155       DtDtsFreeDataType(tmp_type);
3156       XtFree(pwd_dir);
3157       return;
3158    }
3159    DtDtsFreeDataType(tmp_type);
3160
3161    if (openDirType == NEW)
3162    {
3163       DialogData *dialog_data;
3164       FileMgrData *fileMgrData;
3165
3166       fileMgrData = CheckOpenDir(directory_name, host_name);
3167       if(fileMgrData != NULL)
3168       {
3169          dialog_data = _DtGetInstanceData(fileMgrData->file_mgr_rec);
3170          CloseView(dialog_data);
3171       }
3172       ForceMyIconClosed(file_mgr_data->host, file_mgr_data->current_directory);
3173    }
3174
3175    file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
3176
3177    /*  Set the icon name for this view to the directory name.  */
3178
3179    SetIconAttributes ((FileMgrRec *)file_mgr_data->file_mgr_rec, file_mgr_data,
3180                       directory_name);
3181
3182    _DtTurnOnHourGlass (file_mgr_rec->shell);
3183
3184    DeselectAllFiles (file_mgr_data);
3185    ActivateNoSelect (file_mgr_rec);
3186
3187    /* When leaving a directory, save any positional information */
3188    if(file_mgr_data->object_positions)
3189    {
3190       SavePositionInfo(file_mgr_data);
3191       FreePositionInfo(file_mgr_data);
3192    }
3193
3194    /* save the current branch list */
3195    branch_list = file_mgr_data->branch_list;
3196    file_mgr_data->branch_list = NULL;
3197
3198    FileMgrBuildDirectories (file_mgr_data, host_name, directory_name);
3199
3200    GetFileData (file_mgr_data, True, branch_list);
3201
3202    if (branch_list != NULL)
3203    {
3204       for (i = 0; branch_list[i]; i++)
3205         XtFree (branch_list[i]);
3206       XtFree ((char *) branch_list);
3207    }
3208
3209    UpdateCachedDirectories (view_set, view_count);
3210
3211    /* Inherit, or load positional data for this directory */
3212    XmDropSiteStartUpdate(file_mgr_rec->file_window);
3213    LoadPositionInfo(file_mgr_data);
3214    UpdateFileIcons(file_mgr_rec, file_mgr_data, True);
3215
3216    if (showFilesystem && file_mgr_data != trashFileMgrData)
3217       UpdateHeaders (file_mgr_rec, file_mgr_data, True);
3218    else if(file_mgr_data == trashFileMgrData
3219            && file_mgr_data != NULL )
3220       UpdateStatusLine(file_mgr_rec, file_mgr_data);
3221
3222    /* change the title */
3223    title = _DtBuildFMTitle(file_mgr_data);
3224    XtSetArg (args[0], XmNtitle, title);
3225    XtSetValues (file_mgr_rec->shell, args, 1);
3226    XtFree(title);
3227
3228    if (file_mgr_data->show_type == SINGLE_DIRECTORY)
3229       LayoutFileIcons(file_mgr_rec, file_mgr_data, True, True);
3230    else
3231       LayoutFileIcons(file_mgr_rec, file_mgr_data, False, True);
3232
3233    if (openDirType == NEW)
3234       ForceMyIconOpen (file_mgr_data->host, NULL);
3235    XmDropSiteEndUpdate(file_mgr_rec->file_window);
3236 }
3237
3238
3239
3240
3241 /************************************************************************
3242  *
3243  *  FileMgrReread
3244  *      This function causes a rescan of the directory for the view
3245  *      and a full redisplay of the file icons.
3246  *
3247  ************************************************************************/
3248
3249 void
3250 FileMgrReread(
3251         FileMgrRec *file_mgr_rec )
3252 {
3253    DialogData * dialog_data;
3254    FileMgrData * file_mgr_data;
3255    DirectorySet ** directory_set;
3256    int i;
3257
3258
3259    dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
3260    file_mgr_data = (FileMgrData *) dialog_data->data;
3261
3262    _DtTurnOnHourGlass (file_mgr_rec->shell);
3263
3264    directory_set = file_mgr_data->directory_set;
3265
3266    for (i = 0; i < file_mgr_data->directory_count; i++)
3267       RereadDirectory (file_mgr_rec->shell, file_mgr_data->host,
3268                        directory_set[i]->name);
3269
3270    GetFileData (file_mgr_data, False, file_mgr_data->branch_list);
3271    XmDropSiteStartUpdate(file_mgr_rec->file_window);
3272    UpdateFileIcons(file_mgr_rec, file_mgr_data, False);
3273    UpdateHeaders (file_mgr_rec, file_mgr_data, False);
3274    LayoutFileIcons(file_mgr_rec, file_mgr_data, False, True);
3275    XmDropSiteEndUpdate(file_mgr_rec->file_window);
3276    /* _DtTurnOffHourGlass (file_mgr_rec->shell); */
3277 }
3278
3279
3280
3281 /************************************************************************
3282  *
3283  *  FileMgrBuildDirectories
3284  *      Given a directory name, setup the directory set structure
3285  *      contained in the file mgr data stucture.
3286  *
3287  ************************************************************************/
3288
3289 void
3290 FileMgrBuildDirectories(
3291         FileMgrData *file_mgr_data,
3292         char *host_name,
3293         char *directory_name )
3294 {
3295    char current_directory[MAX_PATH];
3296    DirectorySet ** directory_set;
3297
3298    /*  Inform Main that the directory is being changed and       */
3299    /*  free up the data contained in the current directory set.  */
3300
3301    if (file_mgr_data->current_directory != NULL)
3302    {
3303       DirectoryChanged ((XtPointer)file_mgr_data, file_mgr_data->host, host_name,
3304                         file_mgr_data->current_directory, directory_name);
3305       FreeDirectoryData (file_mgr_data);
3306    }
3307
3308    file_mgr_data->current_directory = (char *) XtNewString(directory_name);
3309    (void) strcpy (current_directory, file_mgr_data->current_directory);
3310
3311    /* This code will solve the path problem if user has
3312       Dtfile*restrictMode resource set to True and
3313       also invoke dtfile with -restricted option
3314    */
3315    if( restrictMode
3316        && file_mgr_data->toolbox == False
3317        && file_mgr_data->restricted_directory
3318        && strncmp( file_mgr_data->restricted_directory, directory_name,
3319                    strlen( file_mgr_data->restricted_directory ) ) != 0
3320      )
3321    {
3322       XtFree( file_mgr_data->restricted_directory );
3323       file_mgr_data->restricted_directory = XtNewString( directory_name );
3324    }
3325
3326    if (file_mgr_data->host != NULL)
3327       XtFree ((char *) file_mgr_data->host);
3328
3329    file_mgr_data->host = (char *) XtNewString (host_name);
3330
3331
3332    /*  Allocate the data for one initial directory set  */
3333
3334    file_mgr_data->directory_set = directory_set =
3335       ((DirectorySet **) XtMalloc (2 * sizeof(DirectorySet *))) + 1;
3336    file_mgr_data->directory_count = 1;
3337
3338    directory_set[-1] = NULL;
3339
3340    directory_set[0] = (DirectorySet *) XtMalloc (sizeof (DirectorySet));
3341    directory_set[0]->name = (char *) XtNewString (current_directory);
3342    directory_set[0]->sub_root = NULL;
3343    directory_set[0]->file_count = 0;
3344    directory_set[0]->file_view_data = NULL;
3345    directory_set[0]->order_list = NULL;
3346    directory_set[0]->filtered_file_count = 0;
3347    directory_set[0]->invisible_file_count = 0;
3348    directory_set[0]->file_mgr_data = (XtPointer) file_mgr_data;
3349 }
3350
3351
3352 Boolean
3353 DropOnGadget (
3354    FileMgrData * file_mgr_data,
3355    Widget w,
3356    Position x,
3357    Position y)
3358 {
3359    static Region r = NULL;
3360    unsigned char flags;
3361    XRectangle pRect, lRect;
3362
3363    if ((file_mgr_data->show_type != SINGLE_DIRECTORY) ||
3364        (file_mgr_data->view == BY_ATTRIBUTES))
3365    {
3366       if (   x >= w->core.x
3367           && y >= w->core.y
3368           && x <  (Position)(w->core.x + w->core.width)
3369           && y <  (Position)(w->core.y + w->core.height)
3370          )
3371       {
3372          return(True);
3373       }
3374    }
3375    else
3376    {
3377       if (r == NULL)
3378          r = XCreateRegion();
3379       else
3380          XSubtractRegion(r, r, r);
3381
3382       _DtIconGetIconRects((DtIconGadget)w, &flags, &pRect, &lRect);
3383
3384       if (flags & XmPIXMAP_RECT)
3385          XUnionRectWithRegion(&pRect, r, r);
3386
3387       if (flags & XmLABEL_RECT)
3388          XUnionRectWithRegion(&lRect, r, r);
3389
3390       if (XPointInRegion(r, x, y))
3391          return (True);
3392    }
3393
3394    return(False);
3395 }
3396
3397
3398 /*
3399  * Check to see if the drop occurred within one of the primary hotspots.
3400  * If this is the desktop, then we need to check the hotspots according
3401  * to their stacking order; all other views have their hotspots checked
3402  * according to the order the files were loaded, since overlapping hotspots
3403  * cannot occur.
3404  */
3405
3406 FileViewData *
3407 DropOnPrimaryHotspot (
3408    FileMgrData * file_mgr_data,
3409    Position drop_x,
3410    Position drop_y,
3411    DirectorySet ** directory_data)
3412 {
3413    int directory_count;
3414    register int i, j;
3415    FileViewData * file_view_data;
3416    DirectorySet * dir_data;
3417    ObjectPtr top;
3418
3419    if (PositioningEnabledInView(file_mgr_data))
3420    {
3421       top = GetTopOfStack(file_mgr_data);
3422
3423       while (top)
3424       {
3425          file_view_data = top->file_view_data;
3426
3427          if(file_view_data == NULL)
3428          {
3429             top = top->next;
3430             continue;
3431          }
3432
3433          if (file_view_data->displayed &&
3434             DropOnGadget(file_mgr_data, file_view_data->widget, drop_x, drop_y))
3435          {
3436             *directory_data = file_mgr_data->directory_set[0];
3437             return(file_view_data);
3438          }
3439
3440          top = top->next;
3441       }
3442    }
3443    else
3444    {
3445       if (file_mgr_data->show_type == MULTIPLE_DIRECTORY) {
3446          i = -1;
3447          directory_count = file_mgr_data->directory_count;
3448
3449       } else {
3450          i = 0;
3451          directory_count = 1;
3452       }
3453
3454       for (; i < directory_count; i++)
3455       {
3456          dir_data = file_mgr_data->directory_set[i];
3457
3458          for (j = 0; j < dir_data->file_count; j++)
3459          {
3460             file_view_data = dir_data->file_view_data[j];
3461
3462             if (!file_view_data->displayed)
3463                continue;
3464
3465             if (DropOnGadget(file_mgr_data, file_view_data->widget, drop_x,
3466                              drop_y))
3467             {
3468                *directory_data = dir_data;
3469                return(file_view_data);
3470             }
3471          }
3472       }
3473    }
3474
3475    *directory_data = NULL;
3476    return(False);
3477 }
3478
3479
3480
3481 /************************************************************************
3482  *
3483  *  ProcessDropOnFileWindow
3484  *
3485  ************************************************************************/
3486 static void
3487 ProcessDropOnFileWindow (
3488      Widget w,
3489      DtDndDropCallbackStruct *dropInfo,
3490      FileMgrData *file_mgr_data)
3491 {
3492    char *command = NULL;
3493    char *fileType;
3494
3495   /******************/
3496   /* transfer phase */
3497   /******************/
3498   if(dropInfo->reason != DtCR_DND_DROP_ANIMATE)
3499   {
3500
3501     Arg args[1];
3502     XmDragContext drag_context;
3503
3504    /* Initiating view not valid when another client initiates drag */
3505    if (!dragActive)
3506       initiating_view = NULL;
3507
3508     /* reject the drop if the Protocol is buffer and it was
3509        dropped on the Trash Can
3510     */
3511     if (dropInfo->dropData->protocol == DtDND_BUFFER_TRANSFER)
3512     {
3513       if (file_mgr_data == trashFileMgrData
3514           && file_mgr_data != NULL )
3515       {
3516         dropInfo->status = DtDND_FAILURE;
3517         DPRINTF (("ProcessDropOnFileWindow: Rejecting buffer drop on Trash Can\n"));
3518         return;
3519       }
3520     }
3521
3522
3523     /* if placement is 'As Placed', set blend model to BLEND_NONE */
3524     /* @@@...Need to check if this will work correctly for BUFFERS */
3525     if (PositioningEnabledInView(file_mgr_data))
3526     {
3527       drag_context = (XmDragContext)dropInfo->dragContext;
3528
3529       if (drag_context)
3530       {
3531         XtSetArg(args[0], XmNblendModel, XmBLEND_NONE);
3532         XtSetValues((Widget)drag_context, args, 1);
3533       }
3534     }
3535     /* if placement is 'Grid' */
3536     else
3537     {
3538       /* if initiating view is current view, set status
3539          flag to failure
3540       */
3541       if (initiating_view)
3542       {
3543         if ((((FileMgrData *)initiating_view)->current_directory ==
3544              file_mgr_data->current_directory) &&
3545             (dropInfo->dropData->protocol == DtDND_FILENAME_TRANSFER))
3546          {
3547             /* we actually want to allow a copy or a link to the same directory
3548              * but not a move.  If it's a copy or link, we want the initiating
3549              * view to be NULL so that later we don't error out when it checks
3550              * to see if they are from the same view.  We will fail out if the
3551              * operation is a MOVE (causing the zoom back).
3552              */
3553             fileType = GetDirectoryLogicalType(file_mgr_data,
3554                                         file_mgr_data->current_directory);
3555
3556             command = TypeToAction(dropInfo->operation, fileType);
3557             if( command )
3558             {
3559                if (strcmp(command, "FILESYSTEM_MOVE") == 0)
3560                  dropInfo->status = DtDND_FAILURE;
3561                else
3562                  initiating_view = NULL;
3563             }
3564          }
3565       }
3566     }
3567
3568     /* set the complete move flag to False since the animate
3569        callback handles the deletion of the original file on the move
3570     */
3571
3572     DPRINTF(("DropOnFileWindow: Transfer Callback - Setting Complete move flag to False\n"));
3573
3574     if(dropInfo->dropData->protocol == DtDND_BUFFER_TRANSFER)
3575         dropInfo->completeMove = True;
3576     else
3577         /* set the complete move flag to False since we will be handling */
3578         /* the deletion of the original file                             */
3579
3580         dropInfo->completeMove = False;
3581   }
3582
3583   /*****************************/
3584   /* animate phase, run action */
3585   /*****************************/
3586   else
3587   {
3588     char *command = NULL;
3589     char *fileType;
3590
3591     DPRINTF(("DropOnFileWindow - Animate Callback."));
3592
3593     fileType = GetDirectoryLogicalType(file_mgr_data,
3594                                        file_mgr_data->current_directory);
3595
3596     command = TypeToAction(dropInfo->operation, fileType);
3597
3598     if( command )
3599     {
3600       DirectorySet *directory_set;
3601       int i;
3602
3603       /* retrieve the fileViewData for the current directory */
3604       directory_set = file_mgr_data->directory_set[0];
3605       for( i = 0; i < directory_set->file_count; ++i )
3606       {
3607         if( strcmp(directory_set->order_list[i]->file_data->file_name, "." )
3608             == 0 )
3609         {
3610           RunCommand( command,
3611                       file_mgr_data,
3612                       directory_set->order_list[i],
3613                       NULL,
3614                       dropInfo,
3615                       w );
3616           break;
3617         }
3618       }
3619       DtDtsFreeAttributeValue( command );
3620     }
3621   }
3622 }
3623
3624
3625 /************************************************************************
3626  *
3627  *  DropOnFileWindow
3628  *
3629  ************************************************************************/
3630
3631 void
3632 DropOnFileWindow (
3633      Widget w,
3634      XtPointer client_data,
3635      XtPointer call_data)
3636 {
3637    FileMgrData * file_mgr_data       = (FileMgrData *)client_data;
3638    DtDndDropCallbackStruct *dropInfo = (DtDndDropCallbackStruct *)call_data;
3639
3640    switch (dropInfo->dropData->protocol)
3641      {
3642        case DtDND_FILENAME_TRANSFER:
3643
3644             DPRINTF(("DropOnFileWindow: Number of Files dropped are %d\n",
3645                       dropInfo->dropData->numItems));
3646            ProcessDropOnFileWindow (w, dropInfo, file_mgr_data);
3647            break;
3648        case DtDND_BUFFER_TRANSFER:
3649             DPRINTF (("DropOnFileWindow: Number of Buffers dropped are %d\n",
3650                       dropInfo->dropData->numItems));
3651             ProcessDropOnFileWindow (w, dropInfo, file_mgr_data);
3652            break;
3653        default :
3654            dropInfo->status = DtDND_FAILURE;
3655      } /* endswitch */
3656 }
3657
3658
3659 /************************************************************************
3660  *
3661  *  ProcessDropOnObject
3662  *
3663  ************************************************************************/
3664 static void
3665 ProcessDropOnObject(
3666      Widget w,
3667      DtDndDropCallbackStruct *dropInfo,
3668      FileViewData *file_view_data)
3669 {
3670    char *fileType;
3671
3672    DirectorySet *directory_data =
3673                 (DirectorySet *) file_view_data->directory_set;
3674    FileMgrData *file_mgr_data = (FileMgrData *) directory_data->file_mgr_data;
3675    char *command = NULL;
3676
3677    /******************/
3678    /* transfer phase */
3679    /******************/
3680    if (dropInfo->reason != DtCR_DND_DROP_ANIMATE)
3681    {
3682       DPRINTF(("DropOnObject: Transfer Callback\n"));
3683
3684       /* Initiating view not valid when another client initiates drag */
3685       if (!dragActive)
3686          initiating_view = NULL;
3687
3688       /* check for invalid trash drop */
3689       if (FileFromTrash(dropInfo->dropData->data.files[0]))
3690       {
3691          if (InvalidTrashDragDrop(dropInfo->operation,
3692                FROM_TRASH,
3693                ((FileMgrRec *)file_mgr_data->file_mgr_rec)->file_window))
3694          {
3695             dropInfo->status = DtDND_FAILURE;
3696             return;
3697          }
3698       }
3699       command = TypeToAction(dropInfo->operation,
3700                              file_view_data->file_data->logical_type);
3701       if(command &&
3702          (strncmp("FILESYSTEM_", command, strlen("FILESYSTEM_")) != 0) &&
3703          dropInfo->dropData->protocol == DtDND_BUFFER_TRANSFER)
3704           dropInfo->completeMove = True;
3705       else
3706           /* set the complete move flag to False since we will be handling */
3707           /* the deletion of the original file                             */
3708           dropInfo->completeMove = False;
3709    }
3710
3711    /******************************************/
3712    /* animate phase, retrieve action and run */
3713    /******************************************/
3714    else
3715    {
3716       command = TypeToAction(dropInfo->operation,
3717                              file_view_data->file_data->logical_type);
3718       if (command)
3719       {
3720          RunCommand (command,
3721                      file_mgr_data,
3722                      file_view_data,
3723                      NULL,
3724                      dropInfo,
3725                      NULL);
3726
3727          DtDtsFreeAttributeValue(command);
3728       }
3729    }
3730 }
3731
3732
3733 /************************************************************************
3734  *
3735  *  DropOnObject
3736  *
3737  ************************************************************************/
3738
3739 void
3740 DropOnObject (
3741      Widget w,
3742      XtPointer client_data,
3743      XtPointer call_data)
3744 {
3745    DtDndDropCallbackStruct *dropInfo = (DtDndDropCallbackStruct *)call_data;
3746
3747    switch (dropInfo->dropData->protocol)
3748       {
3749         case DtDND_FILENAME_TRANSFER:
3750         case DtDND_BUFFER_TRANSFER:
3751              ProcessDropOnObject(w, dropInfo, (FileViewData *) client_data);
3752              break;
3753         default:
3754              dropInfo->status = DtDND_FAILURE;
3755       } /* endswitch */
3756 }
3757
3758
3759 /************************************************************************
3760  *
3761  *  FileMgrPropagateSettings
3762  *      Set a new (dst_data) file manager view settings to an
3763  *      old (src_data) settings.
3764  *
3765  ************************************************************************/
3766
3767 void
3768 FileMgrPropagateSettings(
3769         FileMgrData *src_data,
3770         FileMgrData *dst_data )
3771 {
3772
3773    PreferencesData * src_preferences_data;
3774    PreferencesData * dst_preferences_data;
3775
3776    FilterData * src_filter_active_data;
3777    FilterData * dst_filter_active_data;
3778    FilterData * src_filter_edit_data;
3779    FilterData * dst_filter_edit_data;
3780
3781    Arg args[2];
3782    Dimension src_width;
3783    Dimension src_height;
3784
3785    /* Copy the preferences data from src to dst data */
3786
3787    src_preferences_data = (PreferencesData *) src_data->preferences->data;
3788    dst_preferences_data = (PreferencesData *) dst_data->preferences->data;
3789
3790    dst_data->show_type = dst_preferences_data->show_type = src_data->show_type;
3791    dst_data->tree_files = dst_preferences_data->tree_files =
3792                                                           src_data->tree_files;
3793    dst_data->view = src_data->view;
3794    dst_data->view_single = dst_preferences_data->view_single =
3795                                                         src_data->view_single;
3796    dst_data->view_tree = dst_preferences_data->view_tree =
3797                                                         src_data->view_tree;
3798    dst_data->order = dst_preferences_data->order = src_data->order;
3799    dst_data->direction = dst_preferences_data->direction = src_data->direction;
3800    dst_data->positionEnabled = dst_preferences_data->positionEnabled =
3801                                                     src_data->positionEnabled;
3802    dst_data->show_iconic_path = dst_preferences_data->show_iconic_path =
3803                                                     src_data->show_iconic_path;
3804    dst_data->show_current_dir = dst_preferences_data->show_current_dir =
3805                                                     src_data->show_current_dir;
3806    dst_data->show_status_line = dst_preferences_data->show_status_line =
3807                                                     src_data->show_status_line;
3808
3809
3810    /* Copy the Filter active info from src to dest data */
3811    src_filter_active_data = (FilterData *) src_data->filter_active->data;
3812    dst_filter_active_data = (FilterData *) dst_data->filter_active->data;
3813
3814    dst_filter_active_data->match_flag = src_filter_active_data->match_flag;
3815    dst_filter_active_data->filter = XtNewString(src_filter_active_data->filter);
3816    dst_filter_active_data->show_hidden = src_filter_active_data->show_hidden;
3817    dst_filter_active_data->filetypesFilteredCount =
3818                                 src_filter_active_data->filetypesFilteredCount;
3819    XtFree(dst_filter_active_data->filetypesFiltered);
3820    dst_filter_active_data->filetypesFiltered =
3821                         XtNewString(src_filter_active_data->filetypesFiltered);
3822    dst_filter_active_data->count = ReadInFiletypes(dst_filter_active_data);
3823
3824    /* Copy the Filter edit info from src to dest data */
3825    src_filter_edit_data = (FilterData *) src_data->filter_edit->data;
3826    dst_filter_edit_data = (FilterData *) dst_data->filter_edit->data;
3827
3828    dst_filter_edit_data->match_flag = src_filter_edit_data->match_flag;
3829    dst_filter_edit_data->filter = XtNewString(src_filter_edit_data->filter);
3830    dst_filter_edit_data->show_hidden = src_filter_edit_data->show_hidden;
3831    dst_filter_edit_data->filetypesFilteredCount =
3832                                 src_filter_edit_data->filetypesFilteredCount;
3833    XtFree(dst_filter_edit_data->filetypesFiltered);
3834    dst_filter_edit_data->filetypesFiltered =
3835                         XtNewString(src_filter_edit_data->filetypesFiltered);
3836    dst_filter_edit_data->count = ReadInFiletypes(dst_filter_edit_data);
3837
3838    /* Get the size info (e.g. X, Y) form src to dest data */
3839    XtSetArg (args[0], XmNwidth, &src_width);
3840    XtSetArg (args[1], XmNheight, &src_height);
3841    XtGetValues (((FileMgrRec *) src_data->file_mgr_rec)->shell, args, 2);
3842
3843    dst_data->height = src_height;
3844    dst_data->width = src_width;
3845
3846    /* need to propagate whether its a toolbox or not */
3847    dst_data->toolbox = src_data->toolbox;
3848 }
3849
3850
3851 /************************************************************************
3852  *
3853  *  UpdateBranchList
3854  *      Update the list of open tree branches
3855  *
3856  ************************************************************************/
3857
3858 void
3859 UpdateBranchList(
3860         FileMgrData *file_mgr_data,
3861         DirectorySet *directory_set)
3862 {
3863   int i;
3864   char ** table = NULL;
3865   int table_size = 0;
3866   char *branch_name;
3867   char *branch_entry;
3868
3869   /* check if the given directory set is already in the table */
3870   if (directory_set && file_mgr_data->branch_list) {
3871     for (i = 0; file_mgr_data->branch_list[i]; i++)
3872       if (strcmp(file_mgr_data->branch_list[i] + 2, directory_set->name) == 0)
3873       {
3874         /* just update the TreeShow value for this branch and return */
3875         file_mgr_data->branch_list[i][0] = '0' + directory_set->sub_root->ts;
3876         return;
3877       }
3878   }
3879
3880   /* free old branch_list, if any */
3881   if (file_mgr_data->branch_list) {
3882     for (i = 0; file_mgr_data->branch_list[i]; i++)
3883       XtFree (file_mgr_data->branch_list[i]);
3884     XtFree((char *)file_mgr_data->branch_list);
3885     file_mgr_data->branch_list = NULL;
3886   }
3887
3888   /* create new brach list */
3889   for (i = 0; i < file_mgr_data->directory_count; i++) {
3890
3891     if (file_mgr_data->directory_set[i]->sub_root->ts < tsNotRead)
3892       continue;
3893
3894     /* get the name of the tree branch */
3895     branch_name = file_mgr_data->directory_set[i]->name;
3896
3897     /* generate table entry */
3898     branch_entry = (char *)XtMalloc(2 + strlen(branch_name) + 1);
3899     branch_entry[0] = '0' + file_mgr_data->directory_set[i]->sub_root->ts;
3900     branch_entry[1] = ':';
3901     strcpy(branch_entry + 2, branch_name);
3902
3903     /* add entry to the table */
3904     table_size++;
3905     table = (char **)XtRealloc((char *)table,
3906                                       sizeof(char *) * (table_size + 1));
3907     table[table_size - 1] = branch_entry;
3908     table[table_size] = NULL;
3909   }
3910
3911   file_mgr_data->branch_list = table;
3912 }
3913
3914
3915 /************************************************************************
3916  *
3917  *  GetFileData
3918  *      Read the directory contained in host: current_directory and
3919  *      build the file data list and reset any related information
3920  *
3921  ************************************************************************/
3922
3923 static void
3924 GetFileData(
3925         FileMgrData *file_mgr_data,
3926         Boolean valid,
3927         char **branch_list)
3928 {
3929    FileMgrRec *file_mgr_rec;
3930    int directory_count;
3931    DirectorySet ** directory_set;
3932    DirectorySet ** new_dir_set;
3933    FileViewData ** new_view_data;
3934    FileViewData *new_renaming,*new_popup_menu_icon=NULL;
3935    FileViewData *file_view_data,*new_drag_file_view_data=NULL;
3936    int new_dir_count;
3937    int new_file_count;
3938    ObjectPtr position_info;
3939    register int i;
3940    register int j;
3941    register int k;
3942    Boolean match;
3943
3944
3945    file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
3946    directory_count = file_mgr_data->directory_count;
3947    directory_set = file_mgr_data->directory_set;
3948
3949    /*
3950     * Read the directory and subdirectories given by branch_list.
3951     * Note: if any directory we need isn't yet in the cache,
3952     *       ReadTreeDirectory will just kick off a background process
3953     *       to read the directory and return with
3954     *       file_mgr_data->busy_status set to busy_readdir.
3955     */
3956    ReadTreeDirectory (file_mgr_rec->shell, file_mgr_data->host,
3957                       file_mgr_data->current_directory,
3958                       file_mgr_data, branch_list,
3959                       &new_dir_set, &new_dir_count);
3960
3961    /* if directories not ready yet, don't do anything */
3962    if (file_mgr_data->busy_status != not_busy)
3963    {
3964       return;
3965    }
3966
3967    /*
3968     * Try to preserve the 'widget' and 'position_info' fields in the
3969     * file_view_data structure, for each file.  This will allow us to
3970     * re-use the same Icon widget, to reduce flashing.
3971     * Also preserve ndir & nfile counts (used in FilterFiles to decide
3972     * whether to expand or collapse a tree branch if ndir or nfile
3973     * becomes zero).
3974     */
3975
3976    /* loop through the old directory set */
3977    new_renaming = NULL;
3978    for (i = 0; i < directory_count; i++)
3979    {
3980       /* find a directory with same name in the new directory set */
3981       for (j = 0; j < new_dir_count; j++)
3982          if (strcmp(directory_set[i]->name, new_dir_set[j]->name) == 0)
3983             break;
3984
3985       /* if we couldn't find this directory, continue to the next one */
3986       if (j == new_dir_count)
3987          continue;
3988
3989       new_view_data = new_dir_set[j]->file_view_data;
3990       new_file_count = new_dir_set[j]->file_count;
3991
3992       /* loop throught the old file list */
3993       for (j = 0; j < directory_set[i]->file_count; j++)
3994       {
3995          file_view_data = directory_set[i]->file_view_data[j];
3996          position_info = file_view_data->position_info;
3997
3998          /*
3999           * Find a file by the same name in the new file list.
4000           */
4001          for (k = 0; k < new_file_count; k++)
4002          {
4003             if (new_view_data[k]->file_data == file_view_data->file_data)
4004             {
4005                 /* Fix for defect 5029    */
4006                if(file_mgr_data->popup_menu_icon && file_view_data->file_data==
4007                        file_mgr_data->popup_menu_icon->file_data)
4008                   new_popup_menu_icon = new_view_data[k];
4009
4010                /* Fix for defect 5703 */
4011                 if ( file_mgr_data->drag_file_view_data &&
4012                    file_mgr_data->drag_file_view_data->file_data ==
4013                      file_view_data->file_data)
4014                    new_drag_file_view_data = new_view_data[k];
4015
4016                if (file_view_data == file_mgr_data->renaming)
4017                  new_renaming = new_view_data[k];
4018
4019                /* re-use the old widgets */
4020                new_view_data[k]->widget = file_view_data->widget;
4021                new_view_data[k]->treebtn = file_view_data->treebtn;
4022                new_view_data[k]->registered = file_view_data->registered;
4023
4024                /* preserve ndir, nfile counts */
4025                new_view_data[k]->ndir = file_view_data->ndir;
4026                new_view_data[k]->nfile = file_view_data->nfile;
4027
4028                /* preserve the position info */
4029                if (position_info)
4030                {
4031                   new_view_data[k]->position_info = position_info;
4032                   position_info->file_view_data = new_view_data[k];
4033                }
4034
4035                /* preserve icon_mtime */
4036                new_view_data[k]->icon_mtime = file_view_data->icon_mtime;
4037
4038                break;
4039             }
4040          }
4041
4042          /* if no file by the same name was found in the new file list,
4043             the file must have gone away ... lets eliminate the
4044             position infomation */
4045          if (position_info && k == new_file_count)
4046          {
4047             for (k = 0; k < file_mgr_data->num_objects; k++)
4048             {
4049                if (file_mgr_data->object_positions[k] == position_info)
4050                {
4051                   /* @@@ what does this do? */
4052                   position_info->late_bind = True;
4053                   position_info->y += (file_view_data->widget->core.height / 2);
4054                }
4055             }
4056          }
4057       }
4058    }
4059
4060    /* replace the old directory set */
4061    file_mgr_data->directory_set = new_dir_set;
4062    file_mgr_data->directory_count = new_dir_count;
4063    file_mgr_data->renaming = new_renaming;
4064    file_mgr_data->popup_menu_icon = new_popup_menu_icon;
4065    file_mgr_data->drag_file_view_data = new_drag_file_view_data;
4066
4067    /*  Get the file types and the files sorted and filtered  */
4068    for (i = 0; i < new_dir_count; i++)
4069    {
4070       OrderFiles (file_mgr_data, new_dir_set[i]);
4071       FilterFiles (file_mgr_data, new_dir_set[i]);
4072       file_mgr_data->tree_root->filtered =
4073          file_mgr_data->show_type != MULTIPLE_DIRECTORY;
4074    }
4075    SelectVisible(file_mgr_data);
4076
4077    /* update the branch_list */
4078    UpdateBranchList(file_mgr_data, NULL);
4079
4080    /*  Update the selection list */
4081    j = 0;
4082    while (j < file_mgr_data->selected_file_count)
4083    {
4084       file_view_data = file_mgr_data->selection_list[j];
4085
4086       /*  See if the selected file is still around */
4087       match = False;
4088       for (i = 0; !match && i < new_dir_count; i++)
4089       {
4090          for (k = 0; k < new_dir_set[i]->file_count; k++)
4091          {
4092             if (file_view_data->file_data ==
4093                 new_dir_set[i]->file_view_data[k]->file_data)
4094             {
4095                 match = True;
4096                 file_view_data =
4097                    file_mgr_data->selection_list[j] =
4098                       new_dir_set[i]->file_view_data[k];
4099                 break;
4100             }
4101          }
4102       }
4103       /* Keep the file selected only if it was found in the new
4104        * directory set and if it is not filtered */
4105       if (match && !file_view_data->filtered)
4106          j++;
4107       else
4108          DeselectFile (file_mgr_data, file_view_data, False);
4109    }
4110
4111    /* free the old directory set */
4112    FreeLayoutData(file_mgr_data->layout_data);
4113    file_mgr_data->layout_data = NULL;
4114    FreeDirectorySet(directory_set, directory_count);
4115
4116    /*  Set the menu activation to reflect and changes in the selection.  */
4117
4118    if(file_mgr_data != trashFileMgrData
4119       && file_mgr_data != NULL )
4120    {
4121       if (file_mgr_data->selected_file_count == 0)
4122          ActivateNoSelect ((FileMgrRec *) file_mgr_data->file_mgr_rec);
4123       else if (file_mgr_data->selected_file_count == 1)
4124          ActivateSingleSelect ((FileMgrRec *) file_mgr_data->file_mgr_rec,
4125                    file_mgr_data->selection_list[0]->file_data->logical_type);
4126       else
4127          ActivateMultipleSelect ((FileMgrRec *) file_mgr_data->file_mgr_rec);
4128    }
4129    else
4130       SensitizeTrashBtns();
4131
4132    /* load positional data for this directory */
4133    if ( (file_mgr_data->positionEnabled == RANDOM_ON)
4134         && ( (file_mgr_rec->menuStates & CLEAN_UP_OP) == 0)
4135       )
4136       LoadPositionInfo(file_mgr_data);
4137 }
4138
4139
4140
4141 /************************************************************************
4142  *
4143  *  QueryBranchList
4144  *      Search for a directory in branch list.
4145  *
4146  ************************************************************************/
4147
4148 Boolean
4149 QueryBranchList(
4150         FileMgrData *file_mgr_data,
4151         char **branch_list,
4152         char *directory_name,
4153         TreeShow *tsp)
4154 {
4155   int i;
4156   TreeShow ts;
4157
4158   if (branch_list == NULL)
4159     return False;
4160
4161   for (i = 0; branch_list[i]; i++)
4162     if (strcmp(branch_list[i] + 2, directory_name) == 0) {
4163       ts = branch_list[i][0] - '0';
4164       if (ts == tsNotRead)
4165         return False;
4166
4167       if (ts == tsAll && file_mgr_data->tree_files == TREE_FILES_NEVER)
4168         *tsp = tsDirs;
4169       else if (ts == tsDirs && file_mgr_data->tree_files == TREE_FILES_ALWAYS)
4170         *tsp = tsAll;
4171       else
4172         *tsp = ts;
4173
4174       return True;
4175     }
4176
4177   return False;
4178 }
4179
4180
4181 /************************************************************************
4182  *
4183  *  ReadTreeDirectory
4184  *      Read a directory and sub directories.
4185  *
4186  ************************************************************************/
4187
4188 static FileViewData *
4189 GetTopInfo(
4190         FileMgrData *file_mgr_data,
4191         char *host_name,
4192         char *directory_name,
4193         char **branch_list)
4194 {
4195   FileData *fp;
4196   FileViewData *ip;
4197   char *p;
4198   TreeShow ts;
4199
4200   /* allocate new FileData */
4201   fp = (FileData *) XtMalloc(sizeof(FileData));
4202   memset(fp, 0, sizeof(FileData));
4203
4204   /* get the name */
4205   if (strcmp(directory_name, "/") == 0)
4206     fp->file_name = XtNewString("/");
4207   else
4208   {
4209     p = strrchr(directory_name, '/');
4210     if (p)
4211       fp->file_name = XtNewString(p + 1);
4212     else
4213       fp->file_name = XtNewString(directory_name);
4214   }
4215
4216   /* assume it's a directory for now ... */
4217   fp->is_subdir = True;
4218
4219   /* @@@ do a readlink here ... */
4220
4221   /* allocate FileViewData */
4222   ip = (FileViewData *)XtMalloc(sizeof(FileViewData));
4223   memset(ip, 0, sizeof(FileViewData));
4224   ip->file_data = fp;
4225
4226   if (QueryBranchList(file_mgr_data, branch_list, directory_name, &ts) &&
4227       ts >= tsNone)
4228   {
4229     ip->ts = ts;
4230   }
4231   else if (file_mgr_data->tree_files == TREE_FILES_ALWAYS)
4232     ip->ts = tsAll;
4233   else
4234     ip->ts = tsDirs;
4235
4236   return ip;
4237 }
4238
4239
4240 static void
4241 CountDirectories(
4242         FileViewData *ip,
4243         int *np)
4244 /*
4245  * Recursively count the number of subdirectores we have read.
4246  */
4247 {
4248   FileViewData *dp;
4249
4250   if (ip->file_data->is_subdir && ip->ts != tsNotRead)
4251     (*np)++;
4252
4253   for (dp = ip->desc; dp; dp = dp->next)
4254     CountDirectories(dp, np);
4255 }
4256
4257
4258 static DirectorySet *
4259 NewDirectorySet(
4260         char *name,
4261         FileViewData *ip,
4262         FileMgrData *file_mgr_data)
4263 {
4264   DirectorySet *ds;
4265   FileViewData *dp;
4266   int i;
4267
4268   /* allocate a new directory set entry */
4269   ds = (DirectorySet *)XtMalloc(sizeof(DirectorySet));
4270
4271   /* initialize the directory set entry */
4272   ds->name = XtNewString(name);
4273   ds->sub_root = ip;
4274   ds->file_count = 0;
4275   for (dp = ip->desc; dp; dp = dp->next)
4276     ds->file_count++;
4277   if (ds->file_count != 0)
4278     ds->file_view_data =
4279       (FileViewData **)XtMalloc(ds->file_count*sizeof(FileViewData *));
4280   else
4281     ds->file_view_data = NULL;
4282
4283   for (dp = ip->desc, i = 0; dp; dp = dp->next, i++) {
4284     ds->file_view_data[i] = dp;
4285     dp->directory_set = (XtPointer)ds;
4286   }
4287   ds->order_list = NULL;
4288   ds->filtered_file_count = 0;
4289   ds->invisible_file_count = 0;
4290   ds->file_mgr_data = (XtPointer)file_mgr_data;
4291
4292   return ds;
4293 }
4294
4295
4296 static void
4297 MakeDirectorySets(
4298         FileMgrData *file_mgr_data,
4299         FileViewData *ip,
4300         DirectorySet **directory_set,
4301         int *index)
4302 /*
4303  * Recursively add directores to the directory set array.
4304  */
4305 {
4306   char fullname[MAX_PATH];
4307   FileViewData *dp;
4308
4309   if (ip->file_data->is_subdir && ip->ts != tsNotRead)
4310   {
4311     /* add a new entry to the directory set array */
4312     GetFullName(file_mgr_data, ip, fullname);
4313     directory_set[*index] = NewDirectorySet(fullname, ip, file_mgr_data);
4314     (*index)++;
4315   }
4316
4317   for (dp = ip->desc; dp; dp = dp->next)
4318     MakeDirectorySets(file_mgr_data, dp, directory_set, index);
4319 }
4320
4321
4322 static void
4323 ReadTreeDirectory(
4324         Widget w,
4325         char *host_name,
4326         char *directory_name,
4327         FileMgrData *file_mgr_data,
4328         char **branch_list,
4329         DirectorySet ***directory_set,
4330         int *directory_count)
4331 {
4332   FileViewData *ip, *dp;
4333   int i, rc;
4334
4335   /* eliminate "/." */
4336   if (strcmp(directory_name, "/.") == 0)
4337     directory_name = "/";
4338
4339   /* if not in tree mode, clear branch_list (@@@ really?) */
4340   if (file_mgr_data->show_type != MULTIPLE_DIRECTORY)
4341     branch_list = NULL;
4342
4343   /* get a FileViewData for the tree root */
4344   file_mgr_data->tree_root = ip =
4345      GetTopInfo(file_mgr_data, host_name, directory_name, branch_list);
4346
4347   /* read the directory tree */
4348   rc = ReadDir(w, file_mgr_data, host_name, directory_name, ip,
4349                0, file_mgr_data->tree_preread_level, branch_list);
4350   if (file_mgr_data->busy_status != not_busy)
4351   {
4352      /* No point in continuing any further, free up all 'ip' and return */
4353      XtFree(ip->file_data->file_name);
4354      XtFree((char *)ip->file_data);
4355      XtFree((char *)ip);
4356      file_mgr_data->tree_root = NULL;
4357      return;
4358   }
4359   if (rc)
4360     ip->ts = tsError;
4361
4362   /* update root FileData from "." */
4363   for (dp = ip->desc; dp; dp = dp->next)
4364     if (strcmp(dp->file_data->file_name, ".") == 0) {
4365       ip->file_data->physical_type = dp->file_data->physical_type;
4366       ip->file_data->logical_type  =
4367                        GetDirectoryLogicalType(file_mgr_data, directory_name);
4368       ip->file_data->errnum        = dp->file_data->errnum;
4369       ip->file_data->stat          = dp->file_data->stat;
4370       ip->file_data->is_broken     = dp->file_data->is_broken;
4371       break;
4372     }
4373
4374   *directory_count = 0;
4375   CountDirectories(ip, directory_count);
4376
4377   /* allocate array of directory set pointers */
4378   *directory_set =
4379     (DirectorySet **) XtMalloc ((*directory_count + 1)*sizeof(DirectorySet *));
4380
4381   /* make a fake directory set for the tree root */
4382   {
4383     char fullname[MAX_PATH];
4384     DirectorySet *ds;
4385     char *p;
4386
4387     ds = (DirectorySet *)XtMalloc(sizeof(DirectorySet));
4388     ip->directory_set = (XtPointer)ds;
4389
4390     strcpy(fullname, directory_name);
4391     p = strrchr(fullname, '/');
4392     if (p)
4393       *p = '\0';
4394     ds->name = XtNewString(fullname);
4395     ds->sub_root = NULL;
4396     ds->file_count = 1;
4397     ds->file_view_data =
4398       (FileViewData **)XtMalloc(sizeof(FileViewData *));
4399     ds->file_view_data[0] = ip;
4400     ds->order_list =
4401       (FileViewData **)XtMalloc(sizeof(FileViewData *));
4402     ds->order_list[0] = ip;
4403     ds->filtered_file_count = 1;
4404     ds->file_mgr_data = (XtPointer)file_mgr_data;
4405
4406     (*directory_set)[0] = ds;
4407     (*directory_set)++;
4408   }
4409
4410   /* make directory sets for the current dir and subdirs */
4411   i = 0;
4412   MakeDirectorySets(file_mgr_data, ip, *directory_set, &i);
4413 }
4414
4415
4416 /*--------------------------------------------------------------------
4417  * filtering
4418  *------------------------------------------------------------------*/
4419
4420 static Bool
4421 IsShown(
4422         FileMgrData *fmd,
4423         FileViewData *ip)
4424 /*
4425  * Decide if entry is currently displayed.
4426  */
4427 {
4428   TreeShow ts;
4429
4430   /* filtered files are not shown */
4431   if (ip->filtered)
4432     return False;
4433
4434   /* in flat mode all un-filtered files are shown */
4435   if (fmd->show_type == SINGLE_DIRECTORY)
4436     return True;
4437
4438   /* in tree mode an entry is shown only if user chooses to */
4439   ts = ip->parent? ip->parent->ts: tsDirs;
4440   if (ts == tsAll)
4441     return True;
4442   else if (ts == tsDirs)
4443     return ip->file_data->is_subdir;
4444   else
4445     return False;
4446 }
4447
4448
4449 static void
4450 SetDisplayedRecur(
4451         FileMgrData *fmd,
4452         FileViewData *dp,     /* directory entry being searched */
4453         int level)            /* tree depth level of this entry */
4454 /*
4455  * Recursively determine the display position of a given entry
4456  * Return false if the entry not currently displayed
4457  */
4458 {
4459   FileViewData *ip;
4460
4461   /* skip entries that are not displayed */
4462   if (level > 0 && !IsShown(fmd, dp))
4463     return;
4464
4465   /* this entry is displayed */
4466   dp->displayed = True;
4467
4468   /* traverse subtree */
4469   level++;
4470
4471   for (ip = dp->desc; ip; ip = ip->next)
4472     SetDisplayedRecur(fmd, ip, level);
4473
4474   return;
4475 }
4476
4477
4478 static void
4479 SelectVisible (FileMgrData *file_mgr_data)
4480 {
4481   int i, j;
4482
4483   /* assume nothing displayed */
4484   for (i = 0; i < file_mgr_data->directory_count; i++)
4485     for (j = 0; j < file_mgr_data->directory_set[i]->file_count; j++)
4486       file_mgr_data->directory_set[i]->file_view_data[j]->displayed = False;
4487
4488   /* set the displayed flag for all entries that are actually shown */
4489   SetDisplayedRecur(file_mgr_data, file_mgr_data->tree_root, 0);
4490   if (file_mgr_data->show_type == SINGLE_DIRECTORY)
4491     file_mgr_data->tree_root->displayed = False;
4492 }
4493
4494
4495 /*--------------------------------------------------------------------
4496  * expand tree branches
4497  *------------------------------------------------------------------*/
4498
4499 /*
4500  * UpdateBranchState:
4501  *   Determine new tree brach expansion state after a subdirectory has
4502  *   been re-read (op == BRANCH_UPDATE), or after the user has requested
4503  *   to expand (op == BRANCH_EXPAND) or collapse (op == BRANCH_COLLAPSE)
4504  *   a tree branch.
4505  */
4506 void
4507 UpdateBranchState(
4508         FileMgrData *file_mgr_data,
4509         FileViewData *ip,
4510         int op,
4511         Boolean busy)
4512 {
4513   TreeShow old_ts = ip->ts;
4514
4515   if (ip->ts == tsReading && op == BRANCH_UPDATE)
4516   {
4517      ip->ts = tsNone;
4518      op = BRANCH_EXPAND;
4519   }
4520
4521   if (busy)
4522   {
4523     /* this is a new branch that's currently being read */
4524     ip->ts = tsReading;
4525   }
4526
4527   else if (ip->ts == tsError)
4528   {
4529     /* can't expand or collaps this branch */
4530     ;
4531   }
4532
4533   else if (op == BRANCH_UPDATE) /* update */
4534   {
4535   }
4536
4537   else if (op == BRANCH_EXPAND) /* show more */
4538   {
4539     if (file_mgr_data->tree_files == TREE_FILES_NEVER)
4540     {
4541       if (ip->ts == tsNone || !showEmptySet && ip->ndir == 0)
4542         ip->ts = tsDirs;
4543       else
4544         ip->ts = tsNone;
4545
4546     }
4547     else
4548     {
4549       if (ip->ndir == 0 && ip->nfile == 0)
4550       {
4551         /* the subdir is empty */
4552         if (!showEmptySet)
4553         ip->ts = tsDirs;
4554         else if (ip->ts == tsNone)
4555            ip->ts = tsDirs;
4556         else
4557            ip->ts = tsNone;
4558       }
4559       else if (ip->ts == tsAll)
4560         ip->ts = tsNone;
4561       else if (ip->ts == tsNone &&
4562                ip->ndir > 0 && ip->nfile > 0 &&
4563                file_mgr_data->tree_files == TREE_FILES_CHOOSE)
4564         ip->ts = tsDirs;
4565       else
4566         ip->ts = tsAll;
4567     }
4568
4569     if (showEmptyMsg &&
4570         ip->ndir == 0 &&
4571         (ip->nfile == 0 || file_mgr_data->tree_files == TREE_FILES_NEVER) &&
4572         ip->ts == tsDirs)
4573     {
4574       DirectorySet *directory_set = (DirectorySet *)ip->directory_set;
4575       FileMgrData *file_mgr_data = (FileMgrData *)directory_set->file_mgr_data;
4576       FileMgrRec *file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
4577       char *msg;
4578       char buf[1024];
4579
4580       if (ip->nfile == 0)
4581         msg = GETMESSAGE(12,18, "The folder %s is empty.");
4582       else
4583         msg = GETMESSAGE(12,19, "The folder %s contains no subdirectories.");
4584
4585       sprintf(buf, msg, ip->file_data->file_name);
4586       SetSpecialMsg( file_mgr_rec, file_mgr_data, buf );
4587     }
4588   }
4589
4590   else if (op == BRANCH_COLLAPSE) /* show less */
4591   {
4592
4593
4594     if (file_mgr_data->tree_files == TREE_FILES_NEVER)
4595     {
4596       if (ip->ts == tsNone || !showEmptySet && ip->ndir == 0)
4597         ip->ts = tsDirs;
4598       else
4599         ip->ts = tsNone;
4600     }
4601     else
4602     {
4603       if (ip->ndir == 0 && ip->nfile == 0)
4604       {
4605         /* the subdir is empty */
4606         if (!showEmptySet)
4607         ip->ts = tsDirs;
4608       else if (ip->ts == tsNone)
4609            ip->ts = tsDirs;
4610         else
4611            ip->ts = tsNone;
4612       }
4613       else if (ip->ts == tsNone)
4614         ip->ts = tsAll;
4615       else if (ip->ts == tsAll &&
4616                ip->ndir > 0 && ip->nfile > 0 &&
4617                file_mgr_data->tree_files == TREE_FILES_CHOOSE)
4618         ip->ts = tsDirs;
4619       else
4620         ip->ts = tsNone;
4621     }
4622   }
4623 }
4624
4625
4626 /*
4627  * DirTreeExpand:
4628  *   Expand (expand == True) or collpase (expand == False) a tree branch.
4629  */
4630 void
4631 DirTreeExpand(
4632         FileMgrData *file_mgr_data,
4633         FileViewData *ip,
4634         Boolean expand)
4635 {
4636   FileMgrRec *file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
4637   DirectorySet *directory_set;
4638   int level, i, n, old_count, rc;
4639   char path[1024];
4640   Pixmap px;
4641   Arg args[20];
4642   Boolean new_branch;
4643
4644   GetAncestorInfo(file_mgr_data, ip, &level, path, NULL);
4645   SetSpecialMsg( file_mgr_rec, file_mgr_data, NULL );
4646
4647   if (expand) {
4648     /* show more */
4649
4650     new_branch = (ip->ts == tsNotRead || ip->ts == tsError);
4651     if (new_branch) {
4652
4653       /* we need to read the sub directory */
4654       _DtTurnOnHourGlass (file_mgr_rec->shell);
4655       if (ip->ts == tsError)
4656       {
4657         if (file_mgr_data->busy_status == not_busy)
4658         {
4659            file_mgr_data->busy_detail = 0;
4660            file_mgr_data->busy_status = initiating_readdir;
4661         }
4662         RereadDirectory (file_mgr_rec->shell, file_mgr_data->host, path);
4663         if (file_mgr_data->busy_status == initiating_readdir)
4664            file_mgr_data->busy_status = not_busy;
4665       }
4666       rc = ReadDir(file_mgr_rec->shell, file_mgr_data,
4667                    file_mgr_data->host, path, ip,
4668                    level, level, NULL);
4669
4670       /* create new directory set entry */
4671       directory_set = NewDirectorySet(path, ip, file_mgr_data);
4672
4673       /* if this is a new entry, add it to the directory set */
4674       if (ip->ts == tsNotRead)
4675       {
4676         file_mgr_data->directory_set =
4677          ((DirectorySet **)
4678            XtRealloc((char *)(file_mgr_data->directory_set - 1),
4679             (file_mgr_data->directory_count + 2)*sizeof(DirectorySet *))) + 1;
4680         file_mgr_data->directory_set[file_mgr_data->directory_count] =
4681             directory_set;
4682         file_mgr_data->directory_count++;
4683       }
4684       else
4685       {
4686         /* otherwise, replace the existing entry */
4687         for (i = 0; i < file_mgr_data->directory_count; i++)
4688           if (strcmp(file_mgr_data->directory_set[i]->name, path) == 0)
4689             break;
4690         XtFree(file_mgr_data->directory_set[i]->name);
4691         file_mgr_data->directory_set[i]->name = NULL;
4692         if (file_mgr_data->directory_set[i]->file_view_data != NULL)
4693           XtFree((char *)file_mgr_data->directory_set[i]->file_view_data);
4694         file_mgr_data->directory_set[i]->file_view_data = NULL;
4695         XtFree((char *)file_mgr_data->directory_set[i]);
4696         file_mgr_data->directory_set[i] = directory_set;
4697       }
4698
4699       if (rc != 0 ||
4700           ip->ts == tsError && file_mgr_data->busy_status == busy_readdir)
4701          ip->ts = tsError;
4702       else
4703          ip->ts = tsNone;
4704
4705       if (file_mgr_data->busy_status != busy_readdir)
4706       {
4707          OrderFiles (file_mgr_data, directory_set);
4708          FilterFiles (file_mgr_data, directory_set);
4709          file_mgr_data->newSize = True;
4710          AddFileIcons(file_mgr_rec, file_mgr_data, directory_set);
4711       }
4712     }
4713
4714     /* expand the branch */
4715     UpdateBranchState(file_mgr_data, ip, BRANCH_EXPAND,
4716                     new_branch && file_mgr_data->busy_status == busy_readdir);
4717   }
4718   else
4719   {
4720     /* collaps the branch */
4721     UpdateBranchState(file_mgr_data, ip, BRANCH_COLLAPSE, False);
4722   }
4723
4724   /* change tree button */
4725   if (file_mgr_data->busy_status != busy_readdir)
4726   {
4727      px = GetTreebtnPixmap(file_mgr_data, ip);
4728      XtSetArg(args[0], XmNlabelPixmap, px);
4729      XtSetValues (ip->treebtn, args, 1);
4730   }
4731
4732   for (i = 0; i < file_mgr_data->directory_count; i++)
4733     if (strcmp(file_mgr_data->directory_set[i]->name, path) == 0)
4734       break;
4735
4736   SelectVisible(file_mgr_data);
4737   UpdateBranchList(file_mgr_data, file_mgr_data->directory_set[i]);
4738
4739   UnmanageFileIcons(file_mgr_rec, file_mgr_data, ip);
4740   EraseTreeLines(file_mgr_rec, file_mgr_data, ip);
4741
4742   /* update the "Hidden" count */
4743   UpdateHeaders(file_mgr_rec, file_mgr_data, False);
4744 }
4745
4746
4747 /************************************************************************
4748  *
4749  *  FreeDirectorySet
4750  *      Free up the directory set data.
4751  *
4752  ************************************************************************/
4753
4754 static void
4755 FreeDirectorySet(
4756         DirectorySet ** directory_set,
4757         int directory_count)
4758 {
4759    register int i, j;
4760
4761    if (!directory_set)
4762      return;
4763
4764    for (i = -1; i < directory_count; i++)
4765    {
4766       if (directory_set[i] == NULL)
4767         continue;
4768
4769       XtFree ((char *) directory_set[i]->name);
4770       for (j = 0; j < directory_set[i]->file_count; j++)
4771       {
4772          if( (char *) directory_set[i]->file_view_data[j]->label)
4773          {
4774             XtFree ((char *) directory_set[i]->file_view_data[j]->label);
4775             directory_set[i]->file_view_data[j]->label = NULL;
4776          }
4777          XtFree ((char *) directory_set[i]->file_view_data[j]);
4778          directory_set[i]->file_view_data[j] = NULL;
4779       }
4780       if (directory_set[i]->file_view_data != NULL)
4781          XtFree ((char *) directory_set[i]->file_view_data);
4782       XtFree ((char *) directory_set[i]->order_list);
4783       XtFree ((char *) directory_set[i]);
4784    }
4785
4786    XtFree ((char *) (directory_set - 1));
4787 }
4788
4789
4790 /************************************************************************
4791  *
4792  *  FreeDirectoryData
4793  *      Free up the current directory and the directory set data.
4794  *
4795  ************************************************************************/
4796
4797 static void
4798 FreeDirectoryData(
4799         FileMgrData *file_mgr_data )
4800 {
4801    if(file_mgr_data->object_positions)
4802       FreePositionInfo(file_mgr_data);
4803
4804    if (file_mgr_data->current_directory != NULL)
4805       XtFree ((char *) file_mgr_data->current_directory);
4806    file_mgr_data->current_directory = NULL;
4807
4808    if (file_mgr_data->host != NULL)
4809       XtFree ((char *) file_mgr_data->host);
4810    file_mgr_data->host = NULL;
4811
4812    FreeLayoutData(file_mgr_data->layout_data);
4813    file_mgr_data->layout_data = NULL;
4814    FreeDirectorySet(file_mgr_data->directory_set,
4815                     file_mgr_data->directory_count);
4816    file_mgr_data->directory_set = NULL;
4817 }
4818
4819
4820
4821
4822 /************************************************************************
4823  *
4824  *  Close
4825  *      Close (destroy) the file browser view.  This callback is issued
4826  *      from both the Close menu item and the Close system menu.
4827  *
4828  ************************************************************************/
4829
4830 void
4831 Close(
4832         Widget w,
4833         XtPointer client_data,
4834         XtPointer call_data )
4835 {
4836    FileMgrRec * file_mgr_rec;
4837    DialogData * dialog_data;
4838    Arg args[1];
4839    Widget mbar = XmGetPostedFromWidget(XtParent(w));
4840
4841
4842    XmUpdateDisplay (w);
4843
4844    XtSetArg(args[0], XmNuserData, &file_mgr_rec);
4845    XtGetValues(mbar, args, 1);
4846    /* Ignore accelerator received after we're unposted */
4847    if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
4848       return;
4849
4850    CloseView (dialog_data);
4851 }
4852
4853
4854
4855
4856 /************************************************************************
4857  *
4858  *  SystemClose
4859  *      Function called from a close on the system menu.
4860  *
4861  ************************************************************************/
4862
4863 static void
4864 SystemClose(
4865         Widget w,
4866         XtPointer data )
4867 {
4868    FileMgrRec * file_mgr_rec;
4869    DialogData * dialog_data;
4870
4871
4872    file_mgr_rec = (FileMgrRec *) data;
4873    dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
4874
4875    CloseView (dialog_data);
4876 }
4877
4878
4879
4880 /************************************************************************
4881  *
4882  *  SetIconAttributes
4883  *      Set the icon name and icon to be used for a file manager view.
4884  *
4885  ************************************************************************/
4886
4887 static void
4888 SetIconAttributes(
4889         FileMgrRec *file_mgr_rec,
4890         FileMgrData *file_mgr_data,
4891         char *directory_name )
4892 {
4893    static Pixmap tool_icon = XmUNSPECIFIED_PIXMAP;
4894    static Pixmap dir_icon = XmUNSPECIFIED_PIXMAP;
4895    static Pixmap tool_mask = XmUNSPECIFIED_PIXMAP;
4896    static Pixmap dir_mask = XmUNSPECIFIED_PIXMAP;
4897    char * new_directory_name;
4898    Pixel background, foreground, top_shadow, bottom_shadow, select;
4899    Colormap colormap;
4900    unsigned int width;
4901    unsigned int height;
4902    Pixmap pixmap;
4903    Arg args[3];
4904    Boolean havePixmap = False;
4905    Boolean haveMask = False;
4906    Boolean root = False;
4907    char * tmpStr;
4908    char *ptr, *fileLabel, *fileName;
4909
4910    if (tool_icon == XmUNSPECIFIED_PIXMAP)
4911    {
4912       XtSetArg (args[0], XmNbackground, &background);
4913       XtSetArg (args[1], XmNcolormap,  &colormap);
4914       XtGetValues (file_mgr_rec->main, args, 2);
4915
4916       XmGetColors (XtScreen (file_mgr_rec->main), colormap, background,
4917                    &foreground, &top_shadow, &bottom_shadow, &select);
4918
4919       /* first get the File Manager's Icon */
4920       pixmap = XmGetPixmap (XtScreen (file_mgr_rec->main), fileMgrIcon,
4921                                         foreground, background);
4922       if( pixmap != XmUNSPECIFIED_PIXMAP)
4923          dir_icon = pixmap;
4924
4925       /* now let's get the mask for the File Manager */
4926       pixmap = _DtGetMask (XtScreen (file_mgr_rec->main), fileMgrIcon);
4927       if( pixmap != XmUNSPECIFIED_PIXMAP)
4928          dir_mask = pixmap;
4929
4930       /* Let's get the Application Manager's Icon */
4931       pixmap = XmGetPixmap (XtScreen (file_mgr_rec->main), appMgrIcon,
4932                                         foreground, background);
4933       if( pixmap != XmUNSPECIFIED_PIXMAP)
4934          tool_icon = pixmap;
4935
4936       /* now let's get the mask for the Application Manager */
4937       pixmap = _DtGetMask (XtScreen (file_mgr_rec->main), appMgrIcon);
4938       if( pixmap != XmUNSPECIFIED_PIXMAP)
4939          tool_mask = pixmap;
4940    }
4941
4942    /* set icon name */
4943
4944    if (fileLabel = DtDtsFileToAttributeValue(directory_name, DtDTS_DA_LABEL))
4945       ptr = fileLabel;
4946    else if (fileName = strrchr(directory_name, '/'))
4947       ptr = fileName + 1;
4948    else
4949       ptr = "";
4950
4951    if(file_mgr_data->title)
4952    {
4953       if(file_mgr_data->toolbox)
4954       {
4955          if(strcmp(directory_name, file_mgr_data->restricted_directory) == 0)
4956          {
4957             new_directory_name =
4958               (char *)XtMalloc(strlen(file_mgr_data->title) + 1);
4959             strcpy( new_directory_name, file_mgr_data->title );
4960          }
4961          else
4962          {
4963             new_directory_name = (char *)XtMalloc( strlen(ptr) + 1 );
4964             sprintf(new_directory_name, "%s", ptr);
4965          }
4966       }
4967       else
4968       {
4969          new_directory_name = (char *)XtMalloc( strlen(ptr) + 1);
4970          sprintf(new_directory_name, "%s",  ptr);
4971       }
4972       root = True;
4973    }
4974    else
4975    {
4976      if (strcmp (directory_name, "/") == 0 && !fileLabel)
4977      {
4978        new_directory_name = (char *)XtMalloc(strlen(file_mgr_data->host) +
4979                                              strlen(root_title) + 3);
4980        sprintf( new_directory_name, "%s:%s", file_mgr_data->host, root_title );
4981        root = True;
4982      }
4983      else
4984        new_directory_name = ptr;
4985    }
4986
4987    XtSetArg (args[0], XmNiconName, new_directory_name);
4988
4989    if(file_mgr_data->toolbox && tool_icon != XmUNSPECIFIED_PIXMAP)
4990    {
4991       havePixmap = True;
4992       XtSetArg (args[1], XmNiconPixmap, tool_icon);
4993       if( tool_mask != XmUNSPECIFIED_PIXMAP)
4994       {
4995          haveMask = True;
4996          XtSetArg (args[2], XmNiconMask, tool_mask);
4997       }
4998    }
4999    else if (dir_icon != XmUNSPECIFIED_PIXMAP)
5000    {
5001       havePixmap = True;
5002       XtSetArg (args[1], XmNiconPixmap, dir_icon);
5003       if( dir_mask != XmUNSPECIFIED_PIXMAP)
5004       {
5005          haveMask = True;
5006          XtSetArg (args[2], XmNiconMask, dir_mask);
5007       }
5008    }
5009
5010    if(havePixmap)
5011    {
5012       if(haveMask)
5013          XtSetValues (file_mgr_rec->shell, args, 3);
5014       else
5015          XtSetValues (file_mgr_rec->shell, args, 2);
5016    }
5017    else
5018       XtSetValues (file_mgr_rec->shell, args, 1);
5019
5020    if (fileLabel)
5021       DtDtsFreeAttributeValue(fileLabel);
5022    if(root)
5023       XtFree(new_directory_name);
5024 }
5025
5026
5027
5028 /*
5029  * Menu callback for the fast change directory toggle.  Toggles the text
5030  * field up and down.
5031  */
5032 void
5033 ShowChangeDirField (
5034    Widget  w,
5035    XtPointer client_data,
5036    XtPointer callback)
5037 {
5038    FileMgrRec  * file_mgr_rec;
5039    DialogData  * dialog_data;
5040    FileMgrData * file_mgr_data;
5041    Arg args[1];
5042    Widget mbar;
5043    int begin_x;
5044
5045
5046    /*  Set the menu item to insensitive to prevent multiple  */
5047    /*  dialogs from being posted and get the area under the  */
5048    /*  menu pane redrawn.                                    */
5049
5050    if (w)
5051    {
5052       if((int)client_data == FM_POPUP)
5053          mbar = XtParent(w);
5054       else
5055          mbar = XmGetPostedFromWidget(XtParent(w));
5056       XmUpdateDisplay (w);
5057       XtSetArg(args[0], XmNuserData, &file_mgr_rec);
5058       XtGetValues(mbar, args, 1);
5059    }
5060    else
5061    {
5062       /* Done only during a restore session */
5063       file_mgr_rec = (FileMgrRec *)client_data;
5064    }
5065
5066    /* Got an accelerator after we were unposted */
5067    if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
5068       return;
5069    file_mgr_data = (FileMgrData *) dialog_data->data;
5070
5071    /* Toggle the state of the text field */
5072    if (XtIsManaged(file_mgr_rec->current_directory_text))
5073    {
5074       XtSetArg (args[0], XmNallowShellResize, False);
5075       XtSetValues(file_mgr_rec->shell, args, 1);
5076       XtUnmanageChild(file_mgr_rec->current_directory_text);
5077       XtSetArg (args[0], XmNallowShellResize, True);
5078       XtSetValues(file_mgr_rec->shell, args, 1);
5079       file_mgr_data->fast_cd_enabled = False;
5080    }
5081    else
5082      ShowFastChangeDir(file_mgr_rec, file_mgr_data);
5083 }
5084
5085
5086
5087 /*
5088  * Class function for forcing the focus to the text field, if visible, each
5089  * time the FileMgr dialog is posted.
5090  */
5091
5092 static void
5093 SetFocus (
5094    FileMgrRec  * file_mgr_rec,
5095    FileMgrData * file_mgr_data)
5096 {
5097    /* Force the focus to the text field */
5098    if (file_mgr_data->fast_cd_enabled)
5099    {
5100       XRaiseWindow(XtDisplay(file_mgr_rec->current_directory_text),
5101                    XtWindow(file_mgr_rec->current_directory_text));
5102       XmProcessTraversal(file_mgr_rec->current_directory_text,
5103                          XmTRAVERSE_CURRENT);
5104    }
5105 }
5106
5107
5108 /*
5109  * This function free up any position information associated with the
5110  * dtfile view, and nulls out the associated data fields.
5111  */
5112
5113 void
5114 FreePositionInfo (
5115    FileMgrData * file_mgr_data)
5116 {
5117    int i, j;
5118    FileViewData **file_view_data;
5119
5120    /* free object positions */
5121    for (i = 0; i < file_mgr_data->num_objects; i++)
5122    {
5123       XtFree(file_mgr_data->object_positions[i]->name);
5124       XtFree((char *)file_mgr_data->object_positions[i]);
5125       file_mgr_data->object_positions[i] = NULL;
5126    }
5127
5128    XtFree((char *)file_mgr_data->object_positions);
5129
5130    file_mgr_data->object_positions = NULL;
5131    file_mgr_data->num_objects = 0;
5132
5133    /* clear references to object positions in file_view_data */
5134    for (i = 0; i < file_mgr_data->directory_count; i++)
5135    {
5136       file_view_data = file_mgr_data->directory_set[i]->file_view_data;
5137       for (j = 0; j < file_mgr_data->directory_set[i]->file_count; j++)
5138          file_view_data[j]->position_info = NULL;
5139    }
5140 }
5141
5142
5143 /*
5144  * This function determines whether random positioning is currently enabled
5145  * for this view.  The decision is based upon they type of the view, and
5146  * the current preferences settings.
5147  */
5148
5149 Boolean
5150 PositioningEnabledInView (
5151    FileMgrData * file_mgr_data)
5152
5153 {
5154    if ((file_mgr_data->show_type == SINGLE_DIRECTORY) &&
5155         (file_mgr_data->view != BY_ATTRIBUTES) &&
5156         (file_mgr_data->positionEnabled == RANDOM_ON))
5157    {
5158       return(True);
5159    }
5160
5161    return(False);
5162 }
5163
5164
5165 /*
5166  * This function is similar to the above function, but is less restrictive;
5167  * this function does not require that the view currently have positioning
5168  * enabled; it simply returns whether the view has positioning info.
5169  */
5170
5171 Boolean
5172 PositionFlagSet (
5173    FileMgrData * file_mgr_data)
5174
5175 {
5176    if ((file_mgr_data->object_positions) &&
5177         (file_mgr_data->positionEnabled == RANDOM_ON))
5178    {
5179       return(True);
5180    }
5181
5182    return(False);
5183 }
5184
5185
5186 /*
5187  * When a new view of a directory is spun off of an existing view of that
5188  * directory, we want the new view to inherit the positioning information
5189  * associated with the original view.  This function takes care of that.
5190  */
5191
5192 void
5193 InheritPositionInfo (
5194    FileMgrData * src_file_mgr_data,
5195    FileMgrData * dest_file_mgr_data)
5196 {
5197    int i;
5198    ObjectPosition *ptr;
5199    ObjectPosition **temp_stack;
5200
5201    if (!PositionFlagSet(src_file_mgr_data))
5202    {
5203       /* Nothing to inherit */
5204       dest_file_mgr_data->num_objects = 0;
5205       dest_file_mgr_data->object_positions = NULL;
5206       return;
5207    }
5208
5209    dest_file_mgr_data->num_objects = src_file_mgr_data->num_objects;
5210    dest_file_mgr_data->object_positions = (ObjectPosition **) XtMalloc(
5211             sizeof(ObjectPosition *) * dest_file_mgr_data->num_objects);
5212
5213    temp_stack = (ObjectPosition **) XtMalloc(
5214             sizeof(ObjectPosition *) * dest_file_mgr_data->num_objects);
5215
5216    for (i = 0; i < dest_file_mgr_data->num_objects; i++)
5217    {
5218       ptr = dest_file_mgr_data->object_positions[i] = (ObjectPosition *)
5219            XtMalloc(sizeof(ObjectPosition));
5220
5221       *ptr = *(src_file_mgr_data->object_positions[i]);
5222       ptr->name = XtNewString(ptr->name);
5223       ptr->file_view_data = NULL;
5224       ptr->next = NULL;
5225       ptr->prev = NULL;
5226
5227       temp_stack[ptr->stacking_order - 1] = ptr;
5228    }
5229
5230    for(i = 0; i < dest_file_mgr_data->num_objects; i++)
5231    {
5232       if(dest_file_mgr_data->object_positions[i]->stacking_order == 1)
5233       {
5234          dest_file_mgr_data->object_positions[i]->next =
5235             temp_stack[dest_file_mgr_data->object_positions[i]->stacking_order];
5236
5237       }
5238       else if(dest_file_mgr_data->object_positions[i]->stacking_order ==
5239                                               dest_file_mgr_data->num_objects)
5240       {
5241          dest_file_mgr_data->object_positions[i]->prev =
5242             temp_stack[dest_file_mgr_data->object_positions[i]->
5243                                                             stacking_order - 2];
5244       }
5245       else
5246       {
5247          dest_file_mgr_data->object_positions[i]->prev =
5248             temp_stack[dest_file_mgr_data->object_positions[i]->
5249                                                             stacking_order - 2];
5250          dest_file_mgr_data->object_positions[i]->next =
5251             temp_stack[dest_file_mgr_data->object_positions[i]->stacking_order];
5252       }
5253    }
5254
5255    XtFree((char *)temp_stack);
5256 }
5257
5258
5259 /*
5260  * This function saves the current position information (if any) in the
5261  * associated directory; if there is no positional data, then any old
5262  * position files in this directory are removed.  The entries are written
5263  * according to their position (left to right, top to bottom), not according
5264  * to their relative stacking order.
5265  */
5266
5267 void
5268 SavePositionInfo (
5269    FileMgrData * file_mgr_data)
5270
5271 {
5272    PositionInfo *position_info;
5273    ObjectPosition * ptr;
5274    int i;
5275
5276    /* Copy object positions into position info array */
5277    if (file_mgr_data->num_objects <= 0)
5278       position_info = NULL;
5279    else
5280    {
5281       position_info = (PositionInfo *)
5282                    XtMalloc(file_mgr_data->num_objects * sizeof(PositionInfo));
5283       for (i = 0; i < file_mgr_data->num_objects; i++)
5284       {
5285          ptr = file_mgr_data->object_positions[i];
5286
5287          position_info[i].name = ptr->name;
5288          position_info[i].x = ptr->x;
5289          position_info[i].y = ptr->y;
5290          position_info[i].stacking_order = ptr->stacking_order;
5291       }
5292    }
5293
5294    SetDirectoryPositionInfo(file_mgr_data->host,
5295                             file_mgr_data->current_directory,
5296                             file_mgr_data->num_objects, position_info);
5297
5298    XtFree((char *)position_info);
5299 }
5300
5301
5302 /*
5303  * This function will attempt to load any positional data associated with
5304  * the directory to be viewed.  Within the positioning file, the entries
5305  * are order in left-to-right, top-to-bottom order, not according to the
5306  * stacking order.
5307  */
5308
5309 void
5310 LoadPositionInfo (
5311    FileMgrData * file_mgr_data)
5312 {
5313    PositionInfo *position_info;
5314    ObjectPosition * ptr;
5315    int numObjects;
5316    int i;
5317
5318    /* don't do anything if we already have position information */
5319    if (file_mgr_data->object_positions != NULL)
5320       return;
5321
5322    /* Load the number of entries */
5323    numObjects = GetDirectoryPositionInfo(file_mgr_data->host,
5324                              file_mgr_data->current_directory, &position_info);
5325
5326    if (numObjects <= 0)
5327    {
5328       file_mgr_data->object_positions = NULL;
5329       file_mgr_data->num_objects = 0;
5330       return;
5331    }
5332
5333    if (numObjects > 0)
5334    {
5335       /* Proceed with the loading */
5336       file_mgr_data->object_positions = (ObjectPosition **)XtMalloc(
5337               sizeof(ObjectPosition *) * numObjects);
5338
5339       for (i = 0; i < numObjects; i++)
5340       {
5341          ptr = file_mgr_data->object_positions[i] = (ObjectPosition *)
5342                       XtMalloc(sizeof(ObjectPosition));
5343          ptr->name = XtNewString(position_info[i].name);
5344          ptr->x = position_info[i].x;
5345          ptr->y = position_info[i].y;
5346          ptr->in_use = False;
5347          ptr->late_bind = False;
5348          ptr->stacking_order = position_info[i].stacking_order;
5349          ptr->file_view_data = NULL;
5350          ptr->next = NULL;
5351          ptr->prev = NULL;
5352       }
5353
5354       /* Repair all of the next and prev pointers */
5355       file_mgr_data->num_objects = i;
5356       RepairStackingPointers(file_mgr_data);
5357       /* OrderChildrenList(file_mgr_data); */
5358    }
5359
5360    return;
5361 }
5362
5363 /************************************************************************
5364  *
5365  *  MoveOkCB - the user wishes to actually do the move even though its
5366  *             not the desktop object that is actually getting moved.
5367  *             This function calls the routines which do the moves.  It
5368  *             depends on the view type to determine how it does it.
5369  *              view types are:
5370  *                     DESKTOP - the drop happened on a Desktop object
5371  *                              and the object was a directory
5372  *                     NOT_DESKTOP_DIR - the drop happened on a directory
5373  *                              but it wasn't a directory on the desktop.
5374  *                     NOT_DESKTOP - drop happened in a FileManager view
5375  *                              and not on a directory.
5376  *
5377  *
5378  ************************************************************************/
5379 static void
5380 MoveOkCB(
5381         Widget w,
5382         XtPointer client_data,
5383         XtPointer call_data )
5384 {
5385    XtUnmanageChild((Widget)client_data);
5386    XmUpdateDisplay((Widget)client_data);
5387    XtDestroyWidget((Widget)client_data);
5388
5389    DoTheMove(DESKTOP);
5390 }
5391
5392 /************************************************************************
5393  *
5394  *  MoveCancelCB - function called when the user cancels out of the
5395  *                 Move file question dialog.  Just deleted the dialog.
5396  *
5397  ************************************************************************/
5398 static void
5399 MoveCancelCB(
5400         Widget w,
5401         XtPointer client_data,
5402         XtPointer call_data )
5403 {
5404    FileMgrRec *file_mgr_rec;
5405
5406    XtUnmanageChild((Widget)client_data);
5407    XmUpdateDisplay((Widget)client_data);
5408    XtDestroyWidget((Widget)client_data);
5409
5410    if(view_type == NOT_DESKTOP)
5411    {
5412       file_mgr_rec = (FileMgrRec *)fm->file_mgr_rec;
5413       LayoutFileIcons(file_mgr_rec, fm, False, True);
5414    }
5415 }
5416
5417 static void
5418 RemoveIconInWorkspace(
5419          char * fileName,
5420          char * workspaceName )
5421 {
5422   DesktopRec *desktopWin;
5423   int i, j;
5424   char iconName[MAX_PATH];
5425
5426
5427   for(i = 0; i < desktop_data->numIconsUsed; i++)
5428   {
5429     desktopWin = desktop_data->desktopWindows[i];
5430
5431     if( strcmp( desktopWin->dir_linked_to, "/" ) == 0 )
5432       sprintf( iconName, "/%s", desktopWin->file_name );
5433     else
5434       sprintf( iconName, "%s/%s", desktopWin->dir_linked_to, desktopWin->file_name );
5435
5436     DtEliminateDots( iconName );
5437
5438     if( strcmp( fileName, iconName ) == 0
5439         && strcmp( workspaceName, desktopWin->workspace_name ) == 0 )
5440     {
5441       RemoveDT( desktopWin->shell, (XtPointer) desktopWin,
5442                 (XtPointer)NULL );
5443
5444     }
5445   }
5446 }
5447
5448 /*************************************************************************
5449  *
5450  *  CheckMoveType - function used to determine:
5451  *                    1) is the file being moved have a reference to a
5452  *                       Desktop Object?
5453  *                    2) if yes: is the file being moved dragged from
5454  *                               the Desktop (check widget_dragged)?
5455  *                      2a) if yes: set up global varibles used by message
5456  *                                  dialog callback
5457  *                      2b) if no: execute the move, then if one of the objects
5458  *                                 is on the Desktop, move the link to the
5459  *                                 new directory.
5460  *                    3) question 1 answer is no:  just exectute the move
5461  *                                                 command.
5462  *                 Other information:
5463  *                         view types are:
5464  *                           DESKTOP - the drop happened on a Desktop object
5465  *                                    and the object was a directory
5466  *                           NOT_DESKTOP_DIR - the drop happened on a directory
5467  *                                    but it wasn't a directory on the desktop.
5468  *                           NOT_DESKTOP - drop happened in a FileManager view
5469  *                                    and not on a directory.
5470  *
5471  *
5472  **************************************************************************/
5473 void
5474 CheckMoveType(
5475         FileMgrData *file_mgr_data,
5476         FileViewData *file_view_data,
5477         DirectorySet * directory_data,
5478         DesktopRec * desktopWindow,
5479         char **file_set,
5480         char **host_set,
5481         unsigned int modifiers,
5482         int file_count,
5483         Position drop_x,
5484         Position drop_y,
5485         int view )
5486 {
5487    char * tmpStr;
5488    char *Str;
5489    int number;
5490    int i, j;
5491    char *target_host;
5492    char directory[MAX_PATH];
5493    Window   rootWindow;
5494    Atom     pCurrent;
5495    Screen   *currentScreen;
5496    int      screen;
5497    char * workspace_name;
5498    Display  *display;
5499    Boolean value;
5500
5501 #ifdef _CHECK_FOR_SPACES
5502    if (_DtSpacesInFileNames(file_set, file_count))
5503    {
5504      char * tmpStr = (GETMESSAGE(27,94, "The File Manager does not support objects\nwith spaces in their names, so we cannot delete them.\nTo delete these objects:\n  - select 'Open Terminal' from the File Manager menu\n  - then issue the remove command to delete them."));
5505      char * msg = XtNewString(tmpStr);
5506      FileOperationError (toplevel, msg, NULL);
5507      XtFree(msg);
5508      return;
5509    }
5510 #endif
5511
5512    display = XtDisplay(toplevel);
5513    screen = XDefaultScreen(display);
5514    currentScreen = XScreenOfDisplay(display, screen);
5515    rootWindow = RootWindowOfScreen(currentScreen);
5516
5517    if( DtWsmGetCurrentWorkspace(display,rootWindow,&pCurrent) == Success )
5518    {
5519      workspace_name = XGetAtomName (display, pCurrent);
5520      CleanUpWSName(workspace_name);
5521    }
5522
5523    /* Fix for the case, when you drop an object from App. Manager on to desktop
5524       and try to move it to File Manager.  It must copied for this operation
5525       (modifers == ControlMask). */
5526    {
5527      Boolean IsToolBox;
5528
5529      Str = (char *)IsAFileOnDesktop2(file_set, file_count, &number,&IsToolBox);
5530      if(IsToolBox)
5531        modifiers = ControlMask;
5532    }
5533
5534    /*
5535     * If number is comes back greater than 0 then at least one of the files
5536     * dropped has a reference to a Desktop object
5537     *
5538     * If widget_dragged is != NULL then the files dragged are from the
5539     * desktop; in this case set up globals, and post a confirmation dialog.
5540     */
5541    modifiers &= ~Button2Mask;
5542    modifiers &= ~Button1Mask;
5543    if (number > 0 &&
5544        modifiers != ControlMask  && modifiers != ShiftMask &&
5545        widget_dragged != NULL)
5546    {
5547       char *message = NULL;
5548       char *title;
5549       char *from, *to, *filename;
5550
5551       global_file_count = file_count;
5552       _DtCopyDroppedFileInfo(file_count, file_set, host_set,
5553                              &global_file_set, &global_host_set);
5554       G_dropx = drop_x;
5555       G_dropy = drop_y;
5556       fv = file_view_data;
5557       view_type = view;
5558       mod = modifiers;
5559       switch( view )
5560       {
5561           case DESKTOP:
5562               /* desktop object dropped on a desktop directory */
5563               dtWindow = desktopWindow;
5564               fm = (FileMgrData *)NULL;
5565               dd = (DirectorySet *)NULL;
5566               to = (char *)XtMalloc(strlen(directory_data->name) +
5567                                          strlen(fv->file_data->file_name)+ 2);
5568               sprintf(to, "%s/%s", directory_data->name,
5569                                                    fv->file_data->file_name );
5570               DtEliminateDots(to);
5571               break;
5572           case NOT_DESKTOP_DIR:
5573               /* desktop object dropped on a file view directory icon */
5574               dtWindow = (DesktopRec *)NULL;
5575               fm = file_mgr_data;
5576               dd = directory_data;
5577               to = (char *)XtMalloc(strlen(dd->name) +
5578                                     strlen(fv->file_data->file_name) + 2);
5579               sprintf( to, "%s/%s",dd->name , fv->file_data->file_name );
5580               (void) DtEliminateDots(to);
5581               break;
5582           default:/* view == NOT_DESKTOP */
5583               /* desktop object dropped in a file manager view */
5584               dtWindow = (DesktopRec *)NULL;
5585               fm = file_mgr_data;
5586               dd = (DirectorySet *)NULL;
5587               to = (char *)XtMalloc(strlen(file_mgr_data->current_directory)
5588                                     + 1);
5589               strcpy(to, file_mgr_data->current_directory);
5590               break;
5591       }
5592
5593       for(i=0; i<file_count; i++)
5594       {
5595          if(strcmp(file_set[i], to) == 0)
5596          {
5597             char *msg;
5598             FileMgrRec *file_mgr_rec;
5599             tmpStr =
5600                   GETMESSAGE(11,16,"A folder cannot be moved into itself.\n%s");
5601             msg = XtNewString(tmpStr);
5602             if(file_view_data == NULL)
5603             {
5604                file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
5605                FileOperationError(file_mgr_rec->shell, msg, file_set[i]);
5606             }
5607             else
5608             {
5609                FileOperationError(file_view_data->widget, msg, file_set[i]);
5610             }
5611             XtFree(msg);
5612             XtFree(Str);
5613             XtFree(to);
5614             XtFree(workspace_name);
5615             return;
5616          }
5617       }
5618
5619       tmpStr = (GETMESSAGE(12,3, "Move File(s)"));
5620       title = XtNewString(tmpStr);
5621       if(number == 1)
5622       {
5623          int len = strlen(to);
5624          char *ptr, *ptr1;
5625
5626          if( file_mgr_data
5627              && file_mgr_data->toolbox )
5628          {
5629            ptr = strrchr(file_set[0], '/');
5630            ptr1 = (char *)XtMalloc(strlen(to) + strlen(ptr) + 1);
5631            sprintf(ptr1, "%s%s", to, ptr);
5632            ptr1 = _DtResolveAppManPath( ptr1,
5633                                   file_mgr_data->restricted_directory);
5634
5635            if (strncmp(ptr1, file_set[0], len) == 0)
5636            {
5637              DoTheMove(DESKTOP);
5638              XtFree(ptr1);
5639              XtFree(title);
5640              XtFree(to);
5641              XtFree(Str);
5642              return;
5643            }
5644            from = XtNewString( file_set[0] );
5645            ptr = strrchr( from, '/' );
5646            *ptr = 0x0;
5647            filename = XtNewString("");
5648          }
5649          else
5650          {
5651            ptr = strrchr(file_set[0], '/');
5652            if (ptr)
5653            {
5654              *ptr = '\0';
5655              from = (char *)XtMalloc(strlen(file_set[0]) + 1);
5656              strcpy(from, file_set[0]);
5657              *ptr = '/';
5658              ptr++;
5659              filename = (char *)XtMalloc(strlen(ptr) + 1);
5660              strcpy(filename, ptr);
5661            }
5662            else
5663            {
5664              from = (char *)XtMalloc(strlen(ptr) + 1);
5665              strcpy(from, ptr);
5666              filename = XtNewString("");
5667            }
5668          }
5669
5670          if( strcmp( from, to ) == 0 )
5671          {
5672            RemoveIconInWorkspace( file_set[0], workspace_name );
5673            XtFree(title);
5674            XtFree(to);
5675            XtFree(Str);
5676            XtFree(workspace_name);
5677            return;
5678          }
5679
5680 #ifdef sun /* This format statement core dumps on SunOS 4.0.3 and 4.1 */
5681          tmpStr = (GETMESSAGE(12,4, "The object %s is currently in folder %s.\nYou are moving the object to folder %s.\nIs this what you want to do?"));
5682 #else
5683          tmpStr = (GETMESSAGE(12,5, "The object %1$s is currently in folder %2$s.\nYou are moving the object to folder %3$s.\nIs this what you want to do?"));
5684 #endif
5685          message = (char *)XtMalloc(strlen(tmpStr) + strlen(filename) +
5686                                             strlen(to) + strlen(from) + 1);
5687
5688          sprintf(message, tmpStr, filename, from, to);
5689          XtFree(filename);
5690          XtFree(to);
5691          XtFree(from);
5692       }
5693       else
5694       {
5695         int len = strlen(to);
5696         char notHere = 0x0;
5697         int workspace_num;
5698
5699         for( i = 0; i < desktop_data->numWorkspaces; ++i )
5700         {
5701           if( strcmp( workspace_name, desktop_data->workspaceData[i]->name) == 0 )
5702           {
5703             workspace_num = desktop_data->workspaceData[i]->number;
5704             break;
5705           }
5706         }
5707
5708         DeselectAllDTFiles( desktop_data->workspaceData[workspace_num -1] );
5709
5710         {
5711            char *ptr;
5712
5713            if( file_mgr_data
5714                && file_mgr_data->toolbox)
5715            {
5716              to = _DtResolveAppManPath( to,
5717                           file_mgr_data->restricted_directory );
5718              for( i = 0; i < number; ++i )
5719              {
5720                char *ptr, *ptr1;
5721
5722                from = (char *)XtNewString( file_set[i] );
5723                ptr = strrchr( from, '/' );
5724                *ptr = 0x0;
5725                from = _DtResolveAppManPath( from,
5726                               file_mgr_data->restricted_directory );
5727
5728
5729                if( strcmp( from, to ) == 0 )
5730                  RemoveIconInWorkspace( file_set[i], workspace_name );
5731                else
5732                  notHere = 0x1;
5733                XtFree( from );
5734              }
5735            }
5736            else
5737            {
5738               for( i = 0; i < number; ++i )
5739               {
5740                 ptr = strrchr(file_set[i], '/');
5741                 if (ptr)
5742                 {
5743                   *ptr = '\0';
5744                   from = (char *)XtMalloc(strlen(file_set[i]) + 1);
5745                   strcpy(from, file_set[i]);
5746                   *ptr = '/';
5747                 }
5748                 else
5749                 {
5750                   from = (char *)XtMalloc(strlen(ptr) + 1);
5751                   strcpy(from, ptr);
5752                 }
5753
5754                 if( strcmp( to, from ) == 0 )
5755                 {
5756                   RemoveIconInWorkspace( file_set[i], workspace_name );
5757                 }
5758                 else
5759                 {
5760                   notHere = 0x1;
5761                 }
5762                 XtFree(from);
5763               }
5764            }
5765         }
5766
5767         if( notHere )
5768         {
5769           tmpStr = (GETMESSAGE(12,6, "At least one of the files you dropped is from a different\nfolder.  You are moving all these files to %s.\nIs this what you want to do?"));
5770           message = (char *)XtMalloc(strlen(tmpStr) + strlen(to) + 1);
5771
5772           sprintf(message, tmpStr, to);
5773           XtFree(to);
5774         }
5775         else
5776         {
5777         }
5778       }
5779
5780       if( message )
5781       {
5782         _DtMessageDialog(toplevel, title, message, NULL, TRUE,
5783                          MoveCancelCB, MoveOkCB, NULL, HelpRequestCB, False,
5784                          QUESTION_DIALOG);
5785
5786         XtFree(message);
5787       }
5788       XtFree(title);
5789       XtFree(Str);
5790       XtFree(workspace_name);
5791       return;
5792    }
5793
5794     XtFree(Str);  /* No longer used, so free it up */
5795     XtFree(workspace_name);
5796    /*
5797     * Files are not dragged from the desktop.
5798     *
5799     * Just execute the operation.  The target directory dependings on
5800     * the view type (i.e. DESKTOP, NOT_DESKTOP, or NOT_DESKTOP_DIR).
5801     */
5802    switch( view )
5803    {
5804        case DESKTOP:
5805            target_host = desktopWindow->host;
5806            sprintf( directory, "%s/%s", directory_data->name,
5807                     file_view_data->file_data->file_name );
5808            DtEliminateDots(directory);
5809            value = FileMoveCopyDesktop (file_view_data, directory,
5810                                         host_set, file_set, file_count,
5811                                         modifiers, desktopWindow,
5812                                         NULL, NULL);
5813            break;
5814
5815        case NOT_DESKTOP_DIR:
5816            target_host = file_mgr_data->host;
5817            sprintf( directory, "%s/%s", directory_data->name,
5818                     file_view_data->file_data->file_name );
5819            DtEliminateDots(directory);
5820            value = FileMoveCopy (file_mgr_data,
5821                                  NULL, directory, target_host,
5822                                  host_set, file_set, file_count,
5823                                  modifiers, NULL, NULL);
5824            break;
5825
5826        default:/* view == NOT_DESKTOP */
5827            target_host = file_mgr_data->host;
5828            strcpy(directory, file_mgr_data->current_directory);
5829            G_dropx = drop_x;
5830            G_dropy = drop_y;
5831 /*
5832            RepositionIcons(file_mgr_data, file_set, file_count, drop_x,
5833                            drop_y, True);
5834 */
5835            value = FileMoveCopy(file_mgr_data,
5836                                 NULL, directory, target_host,
5837                                 host_set, file_set, file_count,
5838                                 modifiers, NULL, NULL);
5839            break;
5840    }
5841
5842
5843 #ifdef FOO
5844    /*
5845     * If this was a move and any of the files is referenced by a
5846     * Desktop object we need to change the reference to the new
5847     * location that the file moved to.
5848     *
5849     * @@@ This should really be done in the pipe callback!
5850     */
5851    if (number > 0 &&
5852        value &&
5853        modifiers != ControlMask  && modifiers != ShiftMask)
5854    {
5855       Tt_status tt_status;
5856
5857       for(j = 0; j < file_count; j++)
5858       {
5859          char *fileName;
5860          DesktopRec *desktopWin;
5861
5862          /*
5863           * loop through each desktop object to see if the file
5864           * being operated on has a reference to a desktop object.
5865           * If it does change the reference in the desktop object
5866           * structure.
5867           * NOTE:  if we find a desktop object the file references,
5868           *        after we've changed the DT object we can't break
5869           *        because there might be more than one DT object which
5870           *        references it.
5871           */
5872          for(i = 0; i < desktop_data->numIconsUsed; i++)
5873          {
5874             desktopWin = desktop_data->desktopWindows[i];
5875             fileName = ResolveLocalPathName( desktopWin->host, desktopWin->dir_linked_to,
5876                                              desktopWin->file_name, home_host_name, &tt_status);
5877             if( TT_OK == tt_status && strcmp(fileName, file_set[j]) == 0 )
5878             {
5879               /*
5880                * if fileName == file_set[j] then the file is on the
5881                * Desktop so change the dir_linked to reference.  What the
5882                * new reference is depends on which view type is being
5883                * exectuted.
5884                */
5885               XtFree(desktopWin->host);
5886               desktopWin->host = XtNewString(target_host);
5887
5888               XtFree(desktopWin->dir_linked_to);
5889               desktopWin->dir_linked_to = XtNewString(directory);
5890
5891               XtFree(desktopWin->restricted_directory);
5892               if(file_mgr_data->restricted_directory != NULL)
5893                 desktopWin->restricted_directory =
5894                   XtNewString(file_mgr_data->restricted_directory);
5895               else
5896                 desktopWin->restricted_directory = NULL;
5897
5898               XtFree(desktopWin->title);
5899               if(file_mgr_data->title != NULL)
5900                 desktopWin->title = XtNewString(file_mgr_data->title);
5901               else
5902                 desktopWin->title = NULL;
5903
5904               XtFree(desktopWin->helpVol);
5905               if(file_mgr_data->helpVol != NULL)
5906                 desktopWin->helpVol = XtNewString(file_mgr_data->helpVol);
5907               else
5908                 desktopWin->helpVol = NULL;
5909
5910               desktopWin->toolbox = file_mgr_data->toolbox;
5911               XtFree(fileName);
5912             }
5913          } /* for ( i = 0 ...) */
5914       }  /* for (j = 0 ...) */
5915
5916       /* since at least one of the file has been moved lets update
5917          the !dtdesktop file */
5918       SaveDesktopInfo(NORMAL_RESTORE);
5919    }
5920 #endif
5921 }
5922
5923
5924 /*
5925  * This function returns the current working directory settings, used when
5926  * invoking an action.  The caller passes in the current directory for the
5927  * command, and we will simply copy it and return new pointers, unless the
5928  * path specifies a directory which is part of the tool/apps area; in this
5929  * case, the cwd is set to the user's home directory.
5930  *
5931  * The application must free up these two return pointers.
5932  */
5933
5934 void
5935 SetPWD(
5936         char *viewHost,
5937         char *viewDir,
5938         char **pwdHostRet,
5939         char **pwdDirRet,
5940         char *type )
5941
5942 {
5943    if ((strcmp(home_host_name, viewHost) == 0) && type != NULL)
5944    {
5945       char *ptr;
5946
5947       /* Force app dir and any of its subdirs to use $HOME */
5948       if(strcmp(users_home_dir, "/") != 0)
5949       {
5950          ptr = strrchr(users_home_dir, '/');
5951          *ptr = '\0';
5952          *pwdDirRet = XtNewString(users_home_dir);
5953          *ptr = '/';
5954       }
5955       else
5956          *pwdDirRet = XtNewString(users_home_dir);
5957       *pwdHostRet = XtNewString(home_host_name);
5958    }
5959    else
5960    {
5961       /* Simply use the passed in cwd */
5962       *pwdHostRet = XtNewString(viewHost);
5963       *pwdDirRet = XtNewString(viewDir);
5964    }
5965 }
5966
5967 static void
5968 CreateFmPopup (Widget w)
5969 {
5970    Widget popupBtns[FM_POPUP_CHILDREN];
5971    XmString label_string;
5972    char * mnemonic;
5973    Arg args[2];
5974    int n;
5975    int i = 0;
5976
5977
5978    /* Create file manager popup menu */
5979    n = 0;
5980    XtSetArg(args[n],XmNmenuAccelerator,"   "); n++;
5981    XtSetArg(args[n],XmNwhichButton, bMenuButton); n++;
5982    fileMgrPopup.menu = XmCreatePopupMenu(w, "FMPopup", args, n);
5983    XtAddCallback(fileMgrPopup.menu, XmNhelpCallback,
5984                        (XtCallbackProc)HelpRequestCB,
5985                        HELP_POPUP_MENU_STR);
5986
5987
5988    /* Create file manager title */
5989    fileMgrPopup.title = popupBtns[i] =
5990      (Widget)XmCreateLabelGadget(fileMgrPopup.menu, "fmtitle", NULL, 0);
5991    i++;
5992
5993
5994    /* Create title separators */
5995    popupBtns[i++] = XmCreateSeparatorGadget(fileMgrPopup.menu, "sep2",
5996                                                                      NULL, 0);
5997
5998
5999    /* Create 'Properties' option - white space popup */
6000    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 150, "Change Permissions...")));
6001    XtSetArg (args[0], XmNlabelString, label_string);
6002    mnemonic = ((char *)GETMESSAGE(20, 17, "P"));
6003    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6004
6005    fileMgrPopup.wsPopup[BTN_PROPERTIES] = popupBtns[i] =
6006           XmCreatePushButtonGadget (fileMgrPopup.menu, "permissions", args, 2);
6007    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6008                                   (XtCallbackProc)HelpRequestCB,
6009                                   HELP_POPUP_MENU_STR);
6010
6011    XmStringFree (label_string);
6012
6013
6014    /* Create 'Find' option -- white space popup */
6015    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 18, "Find...")));
6016    XtSetArg (args[0], XmNlabelString, label_string);
6017    mnemonic = ((char *)GETMESSAGE(20, 19, "F"));
6018    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6019
6020    fileMgrPopup.wsPopup[BTN_FIND] = popupBtns[i] =
6021           XmCreatePushButtonGadget (fileMgrPopup.menu, "find", args, 2);
6022    XtAddCallback (popupBtns[i], XmNactivateCallback,
6023                                 ShowFindDialog, (XtPointer) FM_POPUP);
6024    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6025                                   (XtCallbackProc)HelpRequestCB,
6026                                   HELP_FILE_MENU_STR);
6027
6028    XmStringFree (label_string);
6029
6030
6031    /* Create 'Clean Up' option -- white space popup */
6032    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 99, "Clean Up")));
6033    XtSetArg (args[0], XmNlabelString, label_string);
6034    mnemonic = ((char *)GETMESSAGE(20, 100, "C"));
6035    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6036
6037    fileMgrPopup.wsPopup[BTN_CLEANUP] = popupBtns[i] =
6038           XmCreatePushButtonGadget (fileMgrPopup.menu, "cleanUp", args, 2);
6039    XtAddCallback (popupBtns[i], XmNactivateCallback,
6040                                 CleanUp, (XtPointer) FM_POPUP);
6041    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6042                                   (XtCallbackProc)HelpRequestCB,
6043                                   HELP_CLEAN_UP_COMMAND_STR);
6044
6045    XmStringFree (label_string);
6046
6047
6048    /* Create 'Select All' option -- white space popup */
6049    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 48, "Select All")));
6050    XtSetArg (args[0], XmNlabelString, label_string);
6051    mnemonic = ((char *)GETMESSAGE(20, 51, "S"));
6052    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6053
6054    fileMgrPopup.wsPopup[BTN_SELECTALL] = popupBtns[i] =
6055           XmCreatePushButtonGadget (fileMgrPopup.menu, "selectAll", args, 2);
6056    XtAddCallback (popupBtns[i], XmNactivateCallback,
6057                                 SelectAll, (XtPointer) FM_POPUP);
6058    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6059                                   (XtCallbackProc)HelpRequestCB,
6060                                   HELP_SELECT_ALL_COMMAND_STR);
6061
6062    XmStringFree (label_string);
6063
6064
6065    /* Create 'Unselect All' option -- white space popup */
6066    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 52, "Deselect All")));
6067    XtSetArg (args[0], XmNlabelString, label_string);
6068    mnemonic = ((char *)GETMESSAGE(20, 55, "D"));
6069    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6070
6071    fileMgrPopup.wsPopup[BTN_UNSELECTALL] = popupBtns[i] =
6072           XmCreatePushButtonGadget (fileMgrPopup.menu, "deselectAll", args, 2);
6073    XtAddCallback (popupBtns[i], XmNactivateCallback,
6074                                 UnselectAll, (XtPointer) FM_POPUP);
6075    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6076                                   (XtCallbackProc)HelpRequestCB,
6077                                   HELP_UNSELECT_ALL_COMMAND_STR);
6078
6079    XmStringFree (label_string);
6080
6081
6082    /* Create 'Show Hidden Files' option -- white space popup */
6083    label_string = XmStringCreateLocalized((GETMESSAGE(20, 156, "Show Hidden Objects")));
6084    XtSetArg (args[0], XmNlabelString, label_string);
6085    mnemonic = ((char *)GETMESSAGE(20, 102, "H"));
6086    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6087
6088    fileMgrPopup.wsPopup[BTN_SHOWHIDDEN] = popupBtns[i] =
6089           XmCreateToggleButtonGadget (fileMgrPopup.menu, "showHiddenObjects", args, 2);
6090    XtAddCallback (popupBtns[i], XmNvalueChangedCallback,
6091                                 ShowHiddenFiles, (XtPointer) FM_POPUP);
6092    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6093                                   (XtCallbackProc)HelpRequestCB,
6094                                   HELP_SHOW_HIDDEN_COMMAND_STR);
6095
6096    XmStringFree (label_string);
6097
6098
6099    /* Manage white space popup buttons -- since XmNadjustMargin defaults */
6100    /* to true, we manage these buttons now so that they will be aligned  */
6101    /* according to the 'ShowHiddenFiles' toggle button                   */
6102    XtManageChildren(fileMgrPopup.wsPopup, WS_BTNS);
6103
6104
6105    /* Adjust XmNadjustMargin such that the rest of the popup buttons will */
6106    /* NOT be forced to align with the 'ShowHiddenFiles' toggle button     */
6107    XtSetArg(args[0], XmNadjustMargin, False);
6108    XtSetValues(fileMgrPopup.menu, args, 1);
6109
6110
6111    /* Create 'Properties' option - object popup */
6112    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 150, "Change Permissions...")));
6113    XtSetArg (args[0], XmNlabelString, label_string);
6114    mnemonic = ((char *)GETMESSAGE(20, 17, "P"));
6115    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6116
6117    fileMgrPopup.objPopup[BTN_PROPERTIES] = popupBtns[i] =
6118           XmCreatePushButtonGadget (fileMgrPopup.menu, "permissions", args, 2);
6119    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6120                                   (XtCallbackProc)HelpRequestCB,
6121                                   HELP_POPUP_MENU_STR);
6122
6123    XmStringFree (label_string);
6124
6125
6126    /* Create 'Put In Workspace' option -- object popup */
6127    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 84, "Put in Workspace")));
6128    XtSetArg (args[0], XmNlabelString, label_string);
6129    mnemonic = ((char *)GETMESSAGE(20, 85, "W"));
6130    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6131
6132    fileMgrPopup.objPopup[BTN_PUTON] = popupBtns[i] =
6133           XmCreatePushButtonGadget (fileMgrPopup.menu, "putInWorkspace", args, 2);
6134    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6135                                   (XtCallbackProc)HelpRequestCB,
6136                                   HELP_POPUP_MENU_STR);
6137
6138    XmStringFree (label_string);
6139
6140
6141    /* Create 'Delete To Trash' option -- object popup */
6142    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 151, "Put in Trash")));
6143    XtSetArg (args[0], XmNlabelString, label_string);
6144    mnemonic = ((char *)GETMESSAGE(20, 91, "T"));
6145    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6146
6147    fileMgrPopup.objPopup[BTN_TRASH] = popupBtns[i] =
6148           XmCreatePushButtonGadget (fileMgrPopup.menu, "trash", args, 2);
6149    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6150                                  (XtCallbackProc)HelpRequestCB,
6151                                  HELP_POPUP_MENU_STR);
6152
6153    XmStringFree (label_string);
6154
6155    /* Create 'Help' option -- object popup */
6156    label_string = XmStringCreateLocalized ((GETMESSAGE(20, 123, "Help")));
6157    XtSetArg (args[0], XmNlabelString, label_string);
6158    mnemonic = ((char *)GETMESSAGE(20, 102, "H"));
6159    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6160
6161    fileMgrPopup.objPopup[BTN_HELP] = popupBtns[i] =
6162           XmCreatePushButtonGadget (fileMgrPopup.menu, "popupHelp", args, 2);
6163    XtAddCallback (popupBtns[i++], XmNhelpCallback,
6164                                  (XtCallbackProc)HelpRequestCB,
6165                                  HELP_HELP_MENU_STR);
6166
6167    XmStringFree (label_string);
6168
6169    /* Create 'Restore' option -- trash popup */
6170    label_string = XmStringCreateLocalized ((GETMESSAGE(27, 24, "Put back")));
6171    XtSetArg (args[0], XmNlabelString, label_string);
6172    mnemonic = ((char *)GETMESSAGE(27, 26, "P"));
6173    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6174    fileMgrPopup.trash_objPopup[BTN_RESTORE] = popupBtns[i] =
6175           XmCreatePushButtonGadget (fileMgrPopup.menu, "putBack", args, 2);
6176    XtAddCallback(popupBtns[i++], XmNhelpCallback,
6177                                  (XtCallbackProc)HelpRequestCB,
6178                                  HELP_TRASH_DIALOG_STR);
6179    XmStringFree (label_string);
6180
6181
6182    /* Create 'Remove' option -- trash popup */
6183    label_string = XmStringCreateLocalized ((GETMESSAGE(27, 28, "Shred")));
6184    XtSetArg (args[0], XmNlabelString, label_string);
6185    mnemonic = ((char *)GETMESSAGE(27, 30, "h"));
6186    XtSetArg (args[1], XmNmnemonic, mnemonic[0]);
6187    fileMgrPopup.trash_objPopup[BTN_REMOVE] = popupBtns[i] =
6188           XmCreatePushButtonGadget (fileMgrPopup.menu, "shred", args, 2);
6189    XtAddCallback(popupBtns[i++], XmNhelpCallback,
6190                                  (XtCallbackProc)HelpRequestCB,
6191                                  HELP_TRASH_DIALOG_STR);
6192    XmStringFree (label_string);
6193
6194
6195    /* Create separator -- white space popup and object popup */
6196    fileMgrPopup.action_separator = popupBtns[i++] =
6197        XmCreateSeparatorGadget(fileMgrPopup.menu, "sep2", NULL, 0);
6198
6199
6200    /* Manage popup buttons */
6201    XtManageChildren(popupBtns, i);
6202
6203 }
6204
6205
6206 /************************************************************************
6207  *
6208  *  DoTheMove - the user wishes to actually do the move even though its
6209  *             not the desktop object that is actually getting moved.
6210  *             This function calls the routines which do the moves.  It
6211  *             depends on the view type to determine how it does it.
6212  *              view types are:
6213  *                     DESKTOP - the drop happened on a Desktop object
6214  *                              and the object was a directory
6215  *                     NOT_DESKTOP_DIR - the drop happened on a directory
6216  *                              but it wasn't a directory on the desktop.
6217  *                     NOT_DESKTOP - drop happened in a FileManager view
6218  *                              and not on a directory.
6219  *
6220  *             if the type passed in is DESKTOP, then remove the corresponding
6221  *             desktop object.
6222  *
6223  ************************************************************************/
6224 static void
6225 DoTheMove(
6226    int type)
6227 {
6228    int file_count;
6229    char **file_set;
6230    char **host_set;
6231    register int i, j;
6232    char *file, *next, *end;
6233    char directory[MAX_PATH];
6234    Boolean result = True;
6235
6236    file_count = global_file_count;
6237    file_set = global_file_set;
6238    host_set = global_host_set;
6239
6240    switch( view_type )
6241    {
6242        case NOT_DESKTOP:
6243 /*
6244            RepositionIcons(fm, file_set, file_count, dx, dy, True);
6245 */
6246            result = FileMoveCopy(fm,
6247                                  NULL, fm->current_directory, fm->host,
6248                                  host_set, file_set, file_count,
6249                                  (unsigned int)0, NULL, NULL);
6250 #ifdef FOO
6251            CheckDesktop();
6252            if(type == DESKTOP)
6253            {
6254              for(j = 0; j < file_count; j++)
6255              {
6256                /* remove the Desktop object which corresponds to this move */
6257                for(i = 0; i < desktop_data->numIconsUsed; i++)
6258                {
6259                  char *fileName;
6260                  DesktopRec *desktopWin;
6261
6262                  desktopWin = desktop_data->desktopWindows[i];
6263                  if (strcmp(desktopWin->host, host_set[j]) != 0)
6264                    continue;
6265
6266                  fileName = (char *)XtMalloc(strlen(desktopWin->dir_linked_to)+
6267                                              strlen(desktopWin->file_name) + 3);
6268                  sprintf( fileName, "%s/%s", desktopWin->dir_linked_to,
6269                           desktopWin->file_name );
6270                  /*
6271                   * if fileName == file_set[j] then the file is on the
6272                   * Desktop so change the dir_linked to reference.  What the
6273                   * new reference is depends on which view type is being
6274                   * exectuted.
6275                   */
6276                  if(strcmp(fileName, file_set[j]) == 0)
6277                  {
6278                    Window   rootWindow;
6279                    Atom     pCurrent;
6280                    Screen   *currentScreen;
6281                    int      screen;
6282                    char     *workspace_name;
6283
6284                    screen = XDefaultScreen(XtDisplay(desktopWin->shell));
6285                    currentScreen =
6286                      XScreenOfDisplay(XtDisplay(desktopWin->shell), screen);
6287                    rootWindow = RootWindowOfScreen(currentScreen);
6288
6289                    if(DtWsmGetCurrentWorkspace(XtDisplay(desktopWin->shell),
6290                                              rootWindow, &pCurrent) == Success)
6291                      workspace_name =
6292                        XGetAtomName (XtDisplay(desktopWin->shell), pCurrent);
6293                    else
6294                      workspace_name = XtNewString("One");
6295                    if (strcmp(workspace_name, desktopWin->workspace_name) == 0)
6296                    {
6297                      RemoveDT (desktopWin->shell, (XtPointer) desktopWin,
6298                                (XtPointer)NULL);
6299                      XtFree(workspace_name);
6300                      workspace_name = NULL;
6301                      break;
6302                    }
6303                    XtFree(workspace_name);
6304                    workspace_name = NULL;
6305                  }
6306                }
6307              }
6308            }
6309 #endif
6310            break;
6311
6312        case NOT_DESKTOP_DIR:
6313            sprintf( directory, "%s/%s", dd->name, fv->file_data->file_name );
6314
6315            result = FileMoveCopy (fm,
6316                                   NULL, directory, fm->host,
6317                                   host_set, file_set, file_count,
6318                                   (unsigned int) 0, NULL, NULL);
6319
6320            CheckDesktop();
6321            break;
6322
6323        default:
6324            {
6325              DirectorySet * directory_data = (DirectorySet *)fv->directory_set;
6326
6327              sprintf( directory, "%s/%s", directory_data->name,
6328                       fv->file_data->file_name );
6329
6330              result = FileMoveCopyDesktop (fv, directory, host_set, file_set,
6331                                            file_count, mod, dtWindow,
6332                                            NULL, NULL);
6333            }
6334            break;
6335    }
6336
6337    _DtFreeDroppedFileInfo(file_count, file_set, host_set);
6338 }
6339
6340 static void
6341 FMInput(
6342         Widget wid,
6343         XEvent *event,
6344         String *params,
6345         Cardinal *num_params )
6346 {
6347   XmDrawingAreaCallbackStruct cb ;
6348   FileMgrRec * fileMgrRec;
6349   int x, y ;
6350   Widget input_on_gadget ;
6351
6352     if ((event->type == KeyPress)
6353         ||(event->type == KeyRelease))
6354     {
6355         x = event->xkey.x ;
6356         y = event->xkey.y ;
6357     }
6358     else
6359       return ;
6360
6361     cb.reason = XmCR_INPUT ;
6362     cb.event = event ;
6363
6364     if( *(params[0]) != '@' )
6365     {
6366 #ifdef __osf__
6367         sscanf( params[0], "%lx", &fileMgrRec );
6368 #else
6369         sscanf( params[0], "%p", &fileMgrRec );
6370 #endif
6371       FileWindowInputCallback( wid, (XtPointer)fileMgrRec, (XtPointer)&cb );
6372     }
6373
6374     return ;
6375 }