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