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