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