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