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