Last of the spelling fixed
[oweals/cde.git] / cde / programs / dtfile / Main.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: Main.c /main/29 1999/09/17 13:35:04 mgreess $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  *
27  *   FILE:           Main.c
28  *
29  *   COMPONENT_NAME: Desktop File Manager (dtfile)
30  *
31  *   Description:    This file contains the main program for dtfile.
32  *                   It also contains functions for session management and
33  *                   directory view control.
34  *
35  *   FUNCTIONS: BlackPixelOfScreen
36  *              BuildAndShowIconName
37  *              CheckForOpenDirectory
38  *              CheckOpenDir
39  *              CleanUp
40  *              CloseView
41  *              DirectoryChanged
42  *              DisplayHeight
43  *              DisplayWidth
44  *              DtfileCvtStringToDTIcon
45  *              DtfileCvtStringToDirection
46  *              DtfileCvtStringToGrid
47  *              DtfileCvtStringToObjPlace
48  *              DtfileCvtStringToOpenDir
49  *              DtfileCvtStringToOrder
50  *              DtfileCvtStringToTree
51  *              DtfileCvtStringToTreeFiles
52  *              DtfileCvtStringToView
53  *              DtfileStringToDirection
54  *              DtfileStringToGrid
55  *              DtfileStringToOrder
56  *              DtfileStringToTree
57  *              DtfileStringToTreeFiles
58  *              DtfileStringToView
59  *              ErrorHandler
60  *              ExitApp
61  *              ExitHandler
62  *              ForceMyIconClosed
63  *              ForceMyIconOpen
64  *              GetNewView
65  *              GetPWD
66  *              GetRestrictedDirectory
67  *              HandleTtRequest
68  *              LoadViews
69  *              MarqueeSelect
70  *              MoveDefaultSettings
71  *              ObserveTtNotice
72  *              OpenDirectories
73  *              ReloadDatabases
74  *              RemoveTextFields
75  *              RestoreSession
76  *              RestoreSettingsFile
77  *              RestrictModeUsage
78  *              ReturnDesktopPtr
79  *              RootWindowOfScreen
80  *              SaveDefaultCancelCB
81  *              SaveDefaultOkCB
82  *              SaveSession
83  *              SaveSessionCallback
84  *              SaveSettingsCB
85  *              SetupSendRequestArgs
86  *              Stop
87  *              ToolkitErrorHandler
88  *              Usage
89  *              ViewAccept
90  *              ViewDirectoryHandler
91  *              ViewDirectoryProc
92  *              ViewHomeDirectoryHandler
93  *              ViewSessionHandler
94  *              ViewToolsDirectoryHandler
95  *              WaitForResponseAndExit
96  *              WhitePixelOfScreen
97  *              XtMalloc
98  *              _DtNextToken
99  *              _DtWsmAddMarqueeSelectionCallback
100  *              if
101  *              main
102  *              strcmp
103  *              strlen
104  *
105  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
106  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
107  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
108  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
109  *
110  ****************************************************************************
111  ************************************<+>*************************************/
112
113 #include <sys/types.h>
114 #include <stdio.h>
115 #include <stdlib.h>
116 #include <sys/stat.h>
117 #include <signal.h>
118
119 #if defined(__osf__) || defined(CSRG_BASED)
120 #include <sys/wait.h>
121 #endif /* __osf__ */
122
123 #include <errno.h>
124 #include <pwd.h>
125 #include <stdlib.h>
126 #include <ctype.h>
127
128 #ifndef sun /* don't need the nl_types.h file */
129 #include <nl_types.h>
130 #endif /* !sun */
131
132 #include <locale.h>
133
134 #include <Xm/XmP.h>
135 #include <Xm/DrawingA.h>
136 #include <Xm/DrawingAP.h>
137 #include <Xm/MessageB.h>
138 #include <Xm/RowColumn.h>
139 #include <Xm/MwmUtil.h>
140
141 #include <Xm/IconFileP.h>
142 #include <Dt/Icon.h>
143 #include <Dt/IconP.h>
144 #include <Dt/IconFile.h>
145
146 #include <Dt/HelpDialog.h>
147
148 #ifdef SHAPE
149 #include <X11/extensions/shape.h>
150 #endif
151
152 #include <X11/Shell.h>
153 #include <X11/Xatom.h>
154 #include <Xm/Protocols.h>
155 #ifdef HAVE_EDITRES
156 #include <X11/Xmu/Editres.h>
157 #endif
158 #include <Dt/Session.h>
159 #include <Dt/Dt.h>
160 #include <Dt/DtP.h>
161 #include <Dt/Connect.h>
162 #include <Dt/FileM.h>
163 #include <Dt/Indicator.h>
164 #include <Dt/Lock.h>
165 #include <Dt/UserMsg.h>
166 #include <Dt/Wsm.h>
167 #include <Dt/WsmP.h>
168 #include <Dt/DtNlUtils.h>
169 #include <Dt/CommandM.h>
170 #include <Dt/EnvControlP.h>
171 #include <Dt/Dts.h>
172 #include <Dt/SharedProcs.h>
173
174 #include "Encaps.h"
175 #include "SharedProcs.h"
176
177 #include <Tt/tttk.h>
178
179 #include "Help.h"
180 #include "FileMgr.h"
181 #include "Desktop.h"
182 #include "Main.h"
183 #include "ChangeDir.h"
184 #include "Prefs.h"
185 #include "Common.h"
186 #include "Filter.h"
187 #include "Find.h"
188 #include "ModAttr.h"
189
190 /* From Command.c */
191 extern void MoveCopyLinkHandler(Tt_message ttMsg, int opType);
192
193 /* From Desktop.c */
194 extern void PutOnWorkspaceHandler(Tt_message ttMsg);
195
196 /* From Filter.c */
197 extern void UpdateFilterAfterDBReread (DialogData * dialog_data);
198
199 /* From ToolTalk.c */
200 extern int InitializeToolTalkSession( Widget topLevel, int ttFd );
201 extern Tt_status InitializeToolTalkProcid( int *ttFd, Widget topLevel, Boolean sendStarted );
202 extern void FinalizeToolTalkSession();
203 /* From Trash.c */
204 void CloseTrash(Widget w, XtPointer client_data, XtPointer call_data) ;
205
206
207
208 /* When openDir resource is set to NEW
209    File Manager will use this prefix to find for a different icon
210    to display.
211 */
212 #define ICON_OPEN_PREFIX "OPEN_"
213
214 /* THESE ARE ONLY STRINGS WHICH DO NOT NEED TO BE LOCALIZED */
215 /* Don't use '#define' since you end up with multiple copies */
216 char DTFILE_CLASS_NAME[] = "Dtfile";
217 char DTFILE_HELP_NAME[] = "Filemgr";
218 char DESKTOP_DIR[] = ".dt/Desktop";
219
220 static char WS_RES_HEADER[] = ".Workspace.";
221 static char SEC_HELP_RES_HEADER[] = ".secondaryHelpDialogCount: ";
222 static char WS_LOAD_RES_HEADER[] = "Workspace";
223 static char SEC_LOAD_HELP_RES_HEADER[] = "secondaryHelpDialogCount";
224 static char RESTRICTED_HEADER[] = "-restricted";
225 static char VIEW_HEADER[] = "-view";
226
227
228 /*  Structure, resource definitions, for View's optional parameters.  */
229
230 typedef struct
231 {
232    char * no_view;
233    char * session;
234    char * directories;
235    int tree_view;
236    int tree_files;
237    int view;
238    int order;
239    int direction;
240    int grid;
241    int instanceIconWidth;
242    int instanceIconHeight;
243    XmFontList user_font;
244    Dimension tool_width;
245    Dimension tool_height;
246    Dimension dir_width;
247    Dimension dir_height;
248    Boolean prompt_user;
249    char * root_title;
250    char * title;
251    char * help_volume;
252    char * restricted;
253    int dragThreshold;
254    int rereadTime;
255    int checkBrokenLink;
256    int maxDirectoryProcesses;
257    int maxRereadProcesses;
258    int maxRereadProcsPerTick;
259    int trashWait;
260    int desktopIconType;
261    Boolean showFilesystem;
262    Boolean showDropZone;
263    Boolean showEmptySet;
264    Boolean showEmptyMsg;
265    int openDirType;
266    Boolean restrictMode;
267    int desktopPlacement;
268    Boolean freezeOnConfig;
269 #if defined(__hpux) || defined(sun)
270    Boolean follow_links;
271 #endif
272    char * fileMgrIcon;
273    char * appMgrIcon;
274    char * trashIcon;
275    int retryLoadDesktop;
276    int smallIconWidth;
277    int smallIconHeight;
278    int largeIconWidth;
279    int largeIconHeight;
280    Boolean emptyTrashOnExit;
281 } ApplicationArgs, *ApplicationArgsPtr;
282
283 static ApplicationArgs application_args;
284
285 /********    Static Function Declarations    ********/
286
287 static void ErrorHandler(
288                         Display *disp,
289                         XErrorEvent *event) ;
290 static void ToolkitErrorHandler(
291                         char *message) ;
292 static void Usage(
293                         char **argv) ;
294 static void RestrictModeUsage(
295                         char **argv) ;
296 static void Stop( void ) ;
297 static void RestoreSettingsFile( void ) ;
298 static void MoveDefaultSettings(
299                         int mode) ;
300 static void SaveDefaultCancelCB(
301                         Widget w,
302                         XtPointer client_data,
303                         XtPointer call_data) ;
304 static void SaveDefaultOkCB(
305                         Widget w,
306                         XtPointer client_data,
307                         XtPointer call_data) ;
308 static void SaveSession(
309                         char *path) ;
310 static int RestoreSession(
311                         char *path,
312                         int type_of_restore,
313                         char *directory) ;
314 static void GetPWD(
315                         char current_directory[]) ;
316 static void OpenDirectories(
317                         char *directory_set,
318                         char *type) ;
319 static Tt_callback_action ObserveTtNotice(
320                         Tt_message msg,
321                         Tt_pattern pat) ;
322 static void ViewSessionHandler(
323                         Tt_message msg);
324 static void ViewDirectoryHandler(
325                         Tt_message msg);
326 static void ViewHomeDirectoryHandler(
327                         Tt_message msg);
328 static void ViewToolsDirectoryHandler(
329                         Tt_message msg);
330 static void ExitHandler(
331                         Tt_message msg,
332                         XtPointer clientData,
333                         String * messageFields,
334                         int numFields);
335 static void ReloadDatabases( void );
336 static void ViewAccept(
337                         View *view,
338                         Tt_message msg);
339 static void LoadViews (
340                         int num_views,
341                         XrmDatabase db,
342                         char *host_name,
343                         char *directory_name,
344                         char *type,
345                         Tt_message msg);
346 static void RemoveTextFields (
347                         XtPointer client_data,
348                         DialogData * old_dialog_data,
349                         DialogData * new_dialog_data) ;
350 static void DtfileCvtStringToObjPlace (
351                         XrmValue *args,
352                         Cardinal numArgs,
353                         XrmValue *fromVal,
354                         XrmValue *toVal) ;
355 static unsigned char *_DtNextToken (
356                         unsigned char *pchIn,
357                         int *pLen,
358                         unsigned char **ppchNext) ;
359 static void DtfileCvtStringToOpenDir (
360                         XrmValue *args,
361                         Cardinal numArgs,
362                         XrmValue *fromVal,
363                         XrmValue *toVal) ;
364 static void DtfileCvtStringToDTIcon (
365                         XrmValue *args,
366                         Cardinal numArgs,
367                         XrmValue *fromVal,
368                         XrmValue *toVal) ;
369 static void DtfileCvtStringToTree (
370                         XrmValue *args,
371                         Cardinal numArgs,
372                         XrmValue *fromVal,
373                         XrmValue *toVal) ;
374 static void DtfileCvtStringToTreeFiles (
375                         XrmValue *args,
376                         Cardinal numArgs,
377                         XrmValue *fromVal,
378                         XrmValue *toVal) ;
379 static void DtfileCvtStringToView (
380                         XrmValue *args,
381                         Cardinal numArgs,
382                         XrmValue *fromVal,
383                         XrmValue *toVal) ;
384 static void DtfileCvtStringToOrder (
385                         XrmValue *args,
386                         Cardinal numArgs,
387                         XrmValue *fromVal,
388                         XrmValue *toVal) ;
389 static void DtfileCvtStringToDirection (
390                         XrmValue *args,
391                         Cardinal numArgs,
392                         XrmValue *fromVal,
393                         XrmValue *toVal) ;
394 static void DtfileCvtStringToGrid (
395                         XrmValue *args,
396                         Cardinal numArgs,
397                         XrmValue *fromVal,
398                         XrmValue *toVal) ;
399 static void DtfileStringToTree(
400                         char *str,
401                         int *type) ;
402 static void DtfileStringToTreeFiles(
403                         char *str,
404                         int *type) ;
405 static void DtfileStringToView(
406                         char *str,
407                         int *type) ;
408 static void DtfileStringToOrder(
409                         char *str,
410                         int *type) ;
411 static void DtfileStringToDirection(
412                         char *str,
413                         int *type) ;
414 static void DtfileStringToGrid(
415                         char *str,
416                         int *type) ;
417 static void SetupSendRequestArgs(
418                         ApplicationArgs application_args,
419                         Tt_message msg) ;
420 static void BuildAndShowIconName(
421                         char *file_type_name,
422                         unsigned char view,
423                         unsigned char show_type,
424                         Widget widget) ;
425 static void MarqueeSelect (
426                         Widget w,
427                         int type,
428                         Position x,
429                         Position y,
430                         Dimension width,
431                         Dimension height,
432                         XtPointer client_data);
433 static void WaitForResponseAndExit( void ) ;
434 static void ExitApp(
435                         XtPointer clientData,
436                         String *words,
437                         int num_fields) ;
438 static Widget post_dialog(
439                         Widget parent,
440                         char *title,
441                         char *msg,
442                         void (*callback)());
443 static void DtErrExitCB(
444                         Widget widget,
445                         XtPointer client_data,
446                         XtPointer call_data);
447
448 /********    End Static Function Declarations    ********/
449
450 /*  debugging flag  */
451 #ifdef DEBUG
452 int debug = 0;
453 #endif
454
455 /*  performance flag  */
456 #ifdef DT_PERFORMANCE
457 int perform = 0;
458 #endif
459
460 /*  The id's of the dialogs registered by main  */
461
462 int file_mgr_dialog;
463 int change_dir_dialog;
464 int preferences_dialog;
465 int filter_dialog;
466 int find_dialog;
467 int mod_attr_dialog;
468 int help_dialog;
469
470 /* The shared menu button and pane Id's */
471
472 Widget * create_dataBtn;
473 Widget * renameBtn;
474 Widget * moveBtn;
475 Widget * duplicateBtn;
476 Widget * linkBtn;
477 Widget * findBtn;
478 Widget * create_directoryBtn;
479 Widget * change_directoryBtn;
480 Widget * showHiddenMenu;
481 Widget * preferencesBtn;
482 Widget * filterBtn;
483 Widget * defaultEnvBtn;
484 Widget * homeBarBtn;
485 Widget * upBarBtn;
486 Widget * newViewBtn;
487 Widget * cleanUpBtn;
488 Widget * separator1;
489 Widget * separator2;
490 Widget * terminalBtn;
491 Widget * usingHelp = NULL;
492 Widget * fileManagerHelp = NULL;
493 Widget * applicationManagerHelp = NULL;
494 Widget * usingHelpTrash = NULL;
495
496
497 /* Bitmask used to indicate the current sensitivity state of shared menu btns */
498
499 unsigned int currentMenuStates = ( RENAME | MOVE | DUPLICATE | LINK | TRASH |
500                                  MODIFY | CHANGEDIR | PREFERENCES | FILTER |
501                                  FIND | CREATE_DIR | CREATE_FILE |
502                                  PUT_ON_DESKTOP | PUTBACK |
503                                  CLEAN_UP | MOVE_UP |
504                                  HOME | CHANGE_DIR | TERMINAL);
505
506 /* Drag manager globals */
507 Boolean b1Drag;
508 Boolean dragActive = False;
509
510 /* Desktop Globals */
511 int numColumns;
512 int numRows;
513
514 /*  Globally referenced application name.  Set to argv[0] in main  */
515
516 char * application_name = NULL;
517
518
519 /*  uid for root user; used when we are checking access permissions  */
520
521 long root_user = -1;
522
523
524 /*  Home host name  */
525
526 char home_host_name[MAX_PATH];
527 char users_home_dir[MAX_PATH];
528
529
530 /*  Toolbox directory  */
531
532 char * desktop_dir = NULL;
533 char * trash_dir = NULL;
534 char * remote_sys_dir = NULL;
535
536 /* Restor type */
537
538 int restoreType = NORMAL_RESTORE;
539
540
541 /*  Black and White pixels  */
542
543 Pixel black_pixel;
544 Pixel white_pixel;
545
546
547 /*  File manager view set before a new view is created and   */
548 /*  used to propagate visual attributes from the initiating  */
549 /*  view to the new view.                                    */
550
551 XtPointer initiating_view = NULL;
552 Boolean special_view = False;
553 Boolean TrashView = False;
554
555
556 /*  system wide user font  */
557
558 XmFontList user_font;
559
560
561 /* Global localizable strings */
562
563 String openInPlace;
564 String openNewView;
565
566
567 /* Global dialog button labels, as XmStrings */
568
569 XmString okXmString;
570 XmString cancelXmString;
571 XmString helpXmString;
572 XmString applyXmString;
573 XmString closeXmString;
574
575
576 /* Global top level widget  */
577
578 Widget toplevel;
579
580 /* Global Application resources */
581 Boolean showFilesystem;
582 Boolean showDropZone;
583 Boolean showEmptySet;
584 Boolean showEmptyMsg;
585 Boolean restrictMode;
586 int openDirType;
587 char *root_title;
588 char *fileMgrTitle;
589 char *fileMgrHelpVol;
590 int desktopIconType;
591 int rereadTime;
592 int checkBrokenLink;
593 int trashWait;
594 int desktopPlacement;
595 Boolean freezeOnConfig;
596 #if defined(__hpux) || defined(sun)
597 Boolean follow_links;
598 #endif
599 int treeType;
600 int treeFiles;
601 int viewType;
602 int orderType;
603 int directionType;
604 int randomType;
605 int instanceWidth;
606 int instanceHeight;
607 unsigned char keybdFocusPolicy;
608 int special_treeType;
609 int special_treeFiles;
610 int special_viewType;
611 int special_orderType;
612 int special_directionType;
613 int special_randomType;
614 char *special_restricted;
615 char *special_title;
616 char *special_helpVol;
617 char *fileMgrIcon;
618 char *appMgrIcon;
619 char *trashIcon;
620 int retryLoadDesktopInfo;
621
622 int smallIconWidth;
623 int smallIconHeight;
624 int largeIconWidth;
625 int largeIconHeight;
626
627 Boolean emptyTrashOnExit;
628
629 #ifdef SHAPE
630 Boolean shapeExtension;
631 #endif
632
633 /* Drag state variables */
634 Boolean B1DragPossible = False;
635 Boolean B2DragPossible = False;
636 Boolean ProcessBtnUp = False;
637 Boolean ProcessBtnUpCD = True;
638 int initialDragX;
639 int initialDragY;
640 int dragThreshold;
641 int xErrorDetected = False;
642
643 /* BMenu button binding */
644 int bMenuButton;
645
646 View ** view_set = NULL;
647 int view_count = 0;
648 int view_set_size = 0;
649
650 /*  Globals used within this file.  */
651
652 static Display * display;
653 char * dt_path = NULL;
654 static Boolean message_display_enabled = True;
655
656
657 static Atom save_yourself_atom;
658 static Atom command_atom;
659 static Atom wm_state_atom;
660 static Atom save_mode;
661
662 /*  Structure used on a save session to see if a dt is iconic  */
663
664 typedef struct
665 {
666    int state;
667    Window icon;
668 } WM_STATE;
669
670
671 /*  Application resource list definition  */
672
673 static XrmOptionDescRec option_list[] =
674 {
675    {  "-noview",            "noView",          XrmoptionIsArg,   NULL  },
676    {  "-session",           "session",         XrmoptionSepArg,  NULL  },
677    {  "-dir",               "folder",          XrmoptionSepArg,  NULL  },
678    {  "-folder",            "folder",          XrmoptionSepArg,  NULL  },
679    {  "-tree",              "treeView",        XrmoptionSepArg,  NULL  },
680    {  "-tree_files",        "treeFiles",       XrmoptionSepArg,  NULL  },
681    {  VIEW_HEADER,          "view",            XrmoptionSepArg,  NULL  },
682    {  "-order",             "order",           XrmoptionSepArg,  NULL  },
683    {  "-direction",         "direction",       XrmoptionSepArg,  NULL  },
684    {  "-grid",              "grid",            XrmoptionSepArg,  NULL  },
685    {  RESTRICTED_HEADER,    "restricted",      XrmoptionIsArg,   NULL  },
686    {  "-title",             "title",           XrmoptionSepArg,  NULL  },
687    {  "-help_volume",       "help_volume",     XrmoptionSepArg,  NULL  },
688    {  "-noprompt",          "promptUser",      XrmoptionNoArg,  "False"  },
689    {  "-small_icon_width",  "smallIconWidth",  XrmoptionSepArg,  NULL  },
690    {  "-small_icon_height", "smallIconHeight", XrmoptionSepArg,  NULL  },
691    {  "-large_icon_width",  "largeIconWidth",  XrmoptionSepArg,  NULL  },
692    {  "-large_icon_height", "largeIconHeight", XrmoptionSepArg,  NULL  },
693 };
694
695
696 static XtResource resources[] =
697 {
698    {
699      "noView", "NoView", XmRString, sizeof (char *),
700      XtOffset (ApplicationArgsPtr, no_view), XmRImmediate, (XtPointer) NULL,
701    },
702
703    {
704      "session", "Session", XmRString, sizeof (char *),
705      XtOffset (ApplicationArgsPtr, session), XmRImmediate, (XtPointer) NULL,
706    },
707
708    {
709      "folder", "Folder", XmRString, sizeof (char *),
710      XtOffset (ApplicationArgsPtr, directories), XmRImmediate, (XtPointer) NULL,
711    },
712
713    {
714      "treeView", "TreeView", "Tree", sizeof (int),
715      XtOffset (ApplicationArgsPtr, tree_view), XmRImmediate,
716      (XtPointer) UNSET_VALUE,
717    },
718
719    {
720      "treeFiles", "TreeFiles", "TreeFiles", sizeof (int),
721      XtOffset (ApplicationArgsPtr, tree_files), XmRImmediate,
722      (XtPointer) UNSET_VALUE,
723    },
724
725    {
726      "view", "View", "View", sizeof (int),
727      XtOffset (ApplicationArgsPtr, view), XmRImmediate, (XtPointer) UNSET_VALUE,
728    },
729
730    {
731      "order", "Order", "Order", sizeof (int),
732      XtOffset (ApplicationArgsPtr, order), XmRImmediate, (XtPointer) UNSET_VALUE,
733    },
734
735    {
736      "direction", "Direction", "Direction", sizeof (int),
737      XtOffset (ApplicationArgsPtr, direction), XmRImmediate,
738      (XtPointer) UNSET_VALUE,
739    },
740
741    {
742      "grid", "Grid", "Grid", sizeof (int),
743      XtOffset (ApplicationArgsPtr, grid), XmRImmediate, (XtPointer) UNSET_VALUE,
744    },
745
746    {
747      "instanceIconWidth", "InstanceIconWidth", XmRInt, sizeof (int),
748      XtOffset (ApplicationArgsPtr, instanceIconWidth), XmRImmediate,
749      (XtPointer) 256,
750    },
751
752    {
753      "instanceIconHeight", "InstanceIconHeight", XmRInt, sizeof (int),
754      XtOffset (ApplicationArgsPtr, instanceIconHeight), XmRImmediate,
755      (XtPointer) 256,
756    },
757
758    {
759      "restricted", "Restricted", XmRString, sizeof (char *),
760      XtOffset (ApplicationArgsPtr, restricted), XmRImmediate, (XtPointer) NULL,
761    },
762
763    {
764      "title", "Title", XmRString, sizeof (char *),
765      XtOffset (ApplicationArgsPtr, title), XmRImmediate, (XtPointer)NULL,
766    },
767
768    {
769      "help_volume", "Help_volume", XmRString, sizeof (char *),
770      XtOffset (ApplicationArgsPtr, help_volume), XmRImmediate, (XtPointer)NULL,
771    },
772
773    {
774      "userFont", "XmCFontList", XmRFontList, sizeof (XmFontList),
775      XtOffset (ApplicationArgsPtr, user_font), XmRString, (XtPointer) "Fixed",
776    },
777
778    {
779      "toolWidth", "ToolWidth", XmRHorizontalDimension, sizeof (Dimension),
780      XtOffset (ApplicationArgsPtr, tool_width), XmRImmediate, (XtPointer) 700,
781    },
782
783    {
784      "toolHeight", "ToolHeight", XmRVerticalDimension, sizeof (Dimension),
785      XtOffset (ApplicationArgsPtr, tool_height), XmRImmediate, (XtPointer) 250,
786    },
787
788    {
789      "dirWidth", "DirWidth", XmRHorizontalDimension, sizeof (Dimension),
790      XtOffset (ApplicationArgsPtr, dir_width), XmRImmediate, (XtPointer) 555,
791    },
792
793    {
794      "dirHeight", "DirHeight", XmRVerticalDimension, sizeof (Dimension),
795      XtOffset (ApplicationArgsPtr, dir_height), XmRImmediate, (XtPointer) 400,
796    },
797
798    {
799      "promptUser", "PromptUser", XmRBoolean, sizeof (Boolean),
800      XtOffset (ApplicationArgsPtr, prompt_user), XmRImmediate, (XtPointer) True,
801    },
802
803    {
804      "rootTitle", "RootTitle", XmRString, sizeof (char *),
805      XtOffset (ApplicationArgsPtr, root_title), XmRImmediate, (XtPointer)"ROOT",
806    },
807
808    {
809      "moveThreshold", "MoveThreshold", XmRInt, sizeof (int),
810      XtOffset (ApplicationArgsPtr, dragThreshold), XmRImmediate, (XtPointer) 4,
811    },
812
813    {
814      "rereadTime", "RereadTime", XmRInt, sizeof (int),
815      XtOffset (ApplicationArgsPtr, rereadTime), XmRImmediate, (XtPointer) 3,
816    },
817
818    {
819      "checkBrokenLink", "CheckBrokenLink", XmRInt, sizeof (int),
820      XtOffset (ApplicationArgsPtr, checkBrokenLink), XmRImmediate,
821      (XtPointer) 180,
822    },
823
824    {
825      "maxDirectoryProcesses", "MaxDirectoryProcesses", XmRInt, sizeof (int),
826      XtOffset (ApplicationArgsPtr, maxDirectoryProcesses), XmRImmediate,
827      (XtPointer) 10,
828    },
829
830    {
831      "maxRereadProcesses", "MaxRereadProcesses", XmRInt, sizeof (int),
832      XtOffset (ApplicationArgsPtr, maxRereadProcesses), XmRImmediate,
833      (XtPointer) 5,
834    },
835
836    {
837      "maxRereadProcsPerTick", "MaxRereadProcsPerTick", XmRInt, sizeof (int),
838      XtOffset (ApplicationArgsPtr, maxRereadProcsPerTick), XmRImmediate,
839      (XtPointer) 1,
840    },
841
842    {
843      "trashWait", "TrashWait", XmRInt, sizeof (int),
844      XtOffset (ApplicationArgsPtr, trashWait), XmRImmediate, (XtPointer) 1,
845    },
846
847    {
848      "desktopIcon", "DesktopIcon", "DesktopIcon", sizeof (int),
849      XtOffset (ApplicationArgsPtr, desktopIconType), XmRImmediate,
850      (XtPointer)LARGE,
851    },
852
853    {
854      "showFilesystem", "ShowFilesystem", XmRBoolean, sizeof (Boolean),
855      XtOffset (ApplicationArgsPtr, showFilesystem), XmRImmediate,
856      (XtPointer)True,
857    },
858
859    {
860      "showDropZone", "ShowDropZone", XmRBoolean, sizeof (Boolean),
861      XtOffset (ApplicationArgsPtr, showDropZone), XmRImmediate,
862      (XtPointer)False,
863    },
864
865    {
866      "showEmptySet", "ShowEmptySet", XmRBoolean, sizeof (Boolean),
867      XtOffset (ApplicationArgsPtr, showEmptySet), XmRImmediate,
868      (XtPointer)False,
869    },
870
871    {
872      "showEmptyMsg", "ShowEmptyMsg", XmRBoolean, sizeof (Boolean),
873      XtOffset (ApplicationArgsPtr, showEmptyMsg), XmRImmediate,
874      (XtPointer)False,
875    },
876
877    {
878      "openFolder", "OpenFolder", "OpenFolder", sizeof (int),
879      XtOffset (ApplicationArgsPtr, openDirType), XmRImmediate,
880      (XtPointer)CURRENT,
881    },
882
883    {
884      "restrictMode", "RestrictMode", XmRBoolean, sizeof (Boolean),
885      XtOffset (ApplicationArgsPtr, restrictMode), XmRImmediate,
886      (XtPointer)False,
887    },
888
889    {
890      "objectPlacement", "ObjectPlacement", "ObjectPlacement", sizeof (int),
891      XtOffset (ApplicationArgsPtr, desktopPlacement), XmRImmediate,
892      (XtPointer)(OBJ_PLACE_TOP_PRIMARY | OBJ_PLACE_RIGHT_SECONDARY),
893    },
894
895    {
896      "freezeOnConfig", "FreezeOnConfig", XmRBoolean, sizeof (Boolean),
897      XtOffset (ApplicationArgsPtr, freezeOnConfig), XmRImmediate,
898      (XtPointer)True,
899    },
900
901    {
902      "fileManagerIcon", "FileManagerIcon", XmRString, sizeof (char *),
903      XtOffset (ApplicationArgsPtr, fileMgrIcon), XmRImmediate,
904      (XtPointer) HOME_ICON_NAME,
905    },
906
907    {
908      "appManagerIcon", "AppManagerIcon", XmRString, sizeof (char *),
909      XtOffset (ApplicationArgsPtr, appMgrIcon), XmRImmediate,
910      (XtPointer) TOOL_ICON_NAME,
911    },
912
913    {
914      "trashIcon", "TrashIcon", XmRString, sizeof (char *),
915      XtOffset (ApplicationArgsPtr, trashIcon), XmRImmediate,
916      (XtPointer) TRASH_ICON_NAME,
917    },
918
919    {
920      "retryLoadDesktop", "RetryLoadDesktop", XmRInt, sizeof (int),
921      XtOffset (ApplicationArgsPtr, retryLoadDesktop), XmRImmediate,
922      (XtPointer) 10,
923    },
924
925    {
926      "smallIconWidth", "SmallIconWidth", XmRInt, sizeof (int),
927      XtOffset (ApplicationArgsPtr, smallIconWidth), XmRImmediate,
928      (XtPointer) 24,
929    },
930
931    {
932      "smallIconHeight", "SmallIconHeight", XmRInt, sizeof (int),
933      XtOffset (ApplicationArgsPtr, smallIconHeight), XmRImmediate,
934      (XtPointer) 24,
935    },
936
937    {
938      "largeIconWidth", "LargeIconWidth", XmRInt, sizeof (int),
939      XtOffset (ApplicationArgsPtr, largeIconWidth), XmRImmediate,
940      (XtPointer) 38,
941    },
942
943    {
944      "largeIconHeight", "LargeIconHeight", XmRInt, sizeof (int),
945      XtOffset (ApplicationArgsPtr, largeIconHeight), XmRImmediate,
946      (XtPointer) 38,
947    },
948
949    {
950      "emptyTrashOnExit", "EmptyTrashOnExit", XmRBoolean, sizeof (Boolean),
951      XtOffset (ApplicationArgsPtr, emptyTrashOnExit), XmRImmediate,
952      (XtPointer)False,
953    },
954
955 #if defined(__hpux) || defined(sun)
956    { "followLinks", "FollowLinks", XmRBoolean, sizeof(Boolean),
957      XtOffset(ApplicationArgsPtr, follow_links), XmRImmediate,
958      (XtPointer) False,
959    },
960 #endif
961
962 };
963
964 XtActionsRec actionTable[] = {
965    {"Space", (XtActionProc)VFTextChangeSpace},
966    {"EscapeFM", (XtActionProc)CancelOut},
967 };
968
969 /************************************************************************
970  *
971  *  DT File
972  *      The main program for the file manager.
973  *
974  ************************************************************************/
975
976 extern XtInputId ProcessToolTalkInputId;
977
978 #if defined(__osf__) || defined(CSRG_BASED)
979 extern void sigchld_handler(int);
980 #endif /* __osf__ */
981
982 int
983 main(
984         int argc,
985         char **argv )
986 {
987 #ifdef DT_PERFORMANCE
988    struct timeval update_time_s;
989    struct timeval update_time_f;
990    struct timeval update_time_ss;
991    struct timeval update_time_fs;
992 #endif
993    struct passwd * pw;
994    char current_directory[MAX_PATH] = {0};
995    struct passwd * pwInfo;
996    char * homeDir;
997    XEvent event;
998    XtInputMask pending;
999    Boolean eventDebugging;
1000    int offset;
1001    int displayHeight;
1002    int displayWidth;
1003    Arg args[10];
1004    int n;
1005    char * tmpStr;
1006    XSetWindowAttributes sAttributes;
1007    Window root;
1008 #ifdef SHAPE
1009    int base1, base2;
1010 #endif
1011    XrmValue resource_value;
1012    XrmDatabase db;
1013    char *rep_type;
1014    char *string, *str;
1015    int i;
1016    int ttFd;    /* ToolTalk file descriptor */
1017    char *sessId;
1018    Tt_pattern events2Watch;
1019    Tt_pattern requests2Handle;
1020    Tt_message msg;
1021    Tt_status status;
1022 #if defined(__osf__) || defined(CSRG_BASED)
1023    struct sigaction sa, osa;
1024 #endif /* __osf__ */
1025    int session_flag = 0;
1026
1027 #ifdef DT_PERFORMANCE
1028    printf("  Start\n");
1029    gettimeofday(&update_time_ss, NULL);
1030 #endif
1031    (void) signal (SIGINT, (void (*)())Stop);
1032
1033    /* We don't want any zombie children, do we? */
1034 #if defined(__osf__) || defined(CSRG_BASED)
1035     sa.sa_handler = sigchld_handler;
1036     sigemptyset(&sa.sa_mask);
1037     sa.sa_flags   =  0;
1038
1039     if (sigaction(SIGCHLD, &sa, &osa) < 0)
1040     /* error handling follows, none for now */
1041         ;
1042 #else
1043    (void) signal (SIGCHLD, SIG_IGN);
1044 #endif /* __osf__ */
1045    XtSetLanguageProc( NULL, NULL, NULL );
1046
1047 #ifdef DT_PERFORMANCE
1048 { /* Initialize the checkpoint protocol  - Aloke Gupta */
1049 Display *display;
1050 display = XOpenDisplay("");
1051 _DtPerfChkpntInit(display, RootWindow(display, DefaultScreen(display)),
1052                     argv[0], True);
1053 }
1054 #endif
1055
1056
1057    _DtEnvControl(DT_ENV_SET);
1058
1059 #ifdef DT_PERFORMANCE
1060    printf("  XtInitalize\n");
1061    gettimeofday(&update_time_s, NULL);
1062
1063    /* Added by Aloke Gupta */
1064 _DtPerfChkpntMsgSend("Begin XtInitialize");
1065 #endif
1066
1067    /*  Initialize the toolkit and open the display  */
1068    toplevel = XtInitialize (argv[0], DTFILE_CLASS_NAME,
1069                             option_list, XtNumber(option_list),
1070                             (int *)&argc, argv);
1071
1072 /* MERGE START: May not need
1073 #ifdef __osf__
1074    _XmColorObjCreate ( toplevel, NULL, NULL );
1075 #endif
1076 */
1077
1078 #ifdef DT_PERFORMANCE
1079    gettimeofday(&update_time_f, NULL);
1080    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1081       update_time_f.tv_usec += 1000000;
1082       update_time_f.tv_sec--;
1083    }
1084    printf("    done XtInitialize, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1085
1086    /* Added by Aloke Gupta */
1087    _DtPerfChkpntMsgSend("Done  XtInitialize");
1088 #endif
1089
1090    /* Initialize the function ptr for alphabetic sorting */
1091    FMStrcoll = GetStrcollProc();
1092
1093    /* Open the message catalog - DO NOT PERFORM until after XtInitialize! */
1094    {
1095       char * foo = ((char *)GETMESSAGE(18, 1, ""));
1096    }
1097
1098    /* set application name for later */
1099    str = strrchr(argv[0], '/');
1100    if(str != NULL)
1101       application_name = XtNewString (str + 1);
1102    else
1103       application_name = XtNewString (argv[0]);
1104
1105    n = 0;
1106    XtSetArg(args[n], XmNallowShellResize, True); n++;
1107    XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
1108    XtSetArg(args[n], XmNheight, 1); n++;
1109    XtSetArg(args[n], XmNwidth, 1); n++;
1110    XtSetValues(toplevel, args, n);
1111    XtRealizeWidget(toplevel);
1112    display = XtDisplay (toplevel);
1113 #ifdef HAVE_EDITRES
1114     XtAddEventHandler(toplevel, 0, True,
1115                       (XtEventHandler) _XEditResCheckMessages,
1116                       (XtPointer) NULL);
1117 #endif
1118
1119    /* Initialize BMenu button binding */
1120    {
1121         int numMouseButtons = XGetPointerMapping(display,
1122                                         (unsigned char *)NULL, 0);
1123         bMenuButton = (numMouseButtons < 3) ? Button2 : Button3;
1124    }
1125
1126    /* initialize debugging flag */
1127 #ifdef DEBUG
1128    if ((tmpStr = getenv("DTFILE_DEBUG")) != NULL)
1129    {
1130       debug = atoi(tmpStr);
1131       if (debug <= 0)
1132          debug = 1;
1133    }
1134    if (getenv("DTFILE_XSYNC") != NULL)
1135    {
1136       XSynchronize(display, True);
1137    }
1138 #endif
1139
1140    /* initialize performance flag */
1141 #ifdef DT_PERFORMANCE
1142    if ((tmpStr = getenv("DTFILE_PERFORM")) != NULL)
1143    {
1144       perform = atoi(tmpStr);
1145       if (perform <= 0)
1146          perform = 1;
1147    }
1148    if (getenv("DTFILE_XSYNC") != NULL)
1149    {
1150       XSynchronize(display, True);
1151    }
1152 #endif
1153
1154    /*  Create the atom set used by save and restore session  */
1155    save_yourself_atom = XmInternAtom (display, "WM_SAVE_YOURSELF", False);
1156    wm_state_atom = XmInternAtom (display, "WM_STATE", False);
1157    command_atom = XA_WM_COMMAND;
1158    save_mode = XmInternAtom (display, _XA_DT_RESTORE_MODE, False);
1159
1160    root = RootWindowOfScreen(XtScreen(toplevel));
1161
1162    /* Set session property on the top level window */
1163    XmAddWMProtocols(toplevel, &save_yourself_atom, 1);
1164    XmAddWMProtocolCallback(toplevel, save_yourself_atom, SaveSessionCallback,
1165                            NULL);
1166
1167    XSetErrorHandler ((int (*)())ErrorHandler);
1168    XtAppSetErrorHandler (XtWidgetToApplicationContext(toplevel),
1169                          ToolkitErrorHandler);
1170
1171    /* get the keyboard focus policy so we know how we want to set up the */
1172    /*  Icon gadgets */
1173    XtSetArg(args[0], XmNkeyboardFocusPolicy, &keybdFocusPolicy);
1174    XtGetValues(toplevel, args, 1);
1175
1176    /*  If all of the command line parameters were not processed  */
1177    /*  out, print out a usage message set and exit.              */
1178
1179    if (argc != 1) Usage (argv);
1180
1181    displayWidth = DisplayWidth(display, DefaultScreen(display));
1182    displayHeight = DisplayHeight(display, DefaultScreen(display));
1183
1184    /*  Get Dt initialized  */
1185
1186    if (DtInitialize (display, toplevel, argv[0], FILE_MANAGER_TOOL_CLASS) == False)
1187    {
1188       /* Fatal Error: could not connect to the messaging system. */
1189       /* DtInitialize() has already logged an appropriate error msg */
1190       exit(-1);
1191    }
1192
1193 #ifdef DT_PERFORMANCE
1194    printf("  Setup Converters and get resources\n");
1195    gettimeofday(&update_time_s, NULL);
1196
1197    /* Added by Aloke Gupta */
1198    _DtPerfChkpntMsgSend("Begin Setup Converters");
1199
1200 #endif
1201
1202    /* First lets add the resource converters needed */
1203    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1204                        XtRString, "ObjectPlacement",
1205                        (XtConverter)DtfileCvtStringToObjPlace, NULL, 0);
1206    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1207                        XtRString, "OpenFolder",
1208                        (XtConverter)DtfileCvtStringToOpenDir, NULL, 0);
1209    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1210                        XtRString, "DesktopIcon",
1211                        (XtConverter)DtfileCvtStringToDTIcon, NULL, 0);
1212    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1213                        XtRString, "Tree",
1214                        (XtConverter)DtfileCvtStringToTree, NULL, 0);
1215    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1216                        XtRString, "TreeFiles",
1217                        (XtConverter)DtfileCvtStringToTreeFiles, NULL, 0);
1218    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1219                        XtRString, "View",
1220                        (XtConverter)DtfileCvtStringToView, NULL, 0);
1221    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1222                        XtRString, "Order",
1223                        (XtConverter)DtfileCvtStringToOrder, NULL, 0);
1224    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1225                        XtRString, "Direction",
1226                        (XtConverter)DtfileCvtStringToDirection, NULL, 0);
1227    XtAppAddConverter (XtWidgetToApplicationContext (toplevel),
1228                        XtRString, "Grid",
1229                        (XtConverter)DtfileCvtStringToGrid, NULL, 0);
1230
1231    /*  Get the application defined resources of session and  */
1232    /*  directory, and get the processes host.                */
1233
1234    XtGetApplicationResources(toplevel, &application_args,
1235                              resources, XtNumber(resources), NULL,0);
1236
1237 #ifdef DT_PERFORMANCE
1238    gettimeofday(&update_time_f, NULL);
1239    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1240       update_time_f.tv_usec += 1000000;
1241       update_time_f.tv_sec--;
1242    }
1243    printf("    done Setting up Converters and got resources, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1244
1245    /* Added by Aloke Gupta */
1246    _DtPerfChkpntMsgSend("Done  Setup Converters");
1247 #endif
1248
1249 #ifdef DT_PERFORMANCE
1250    printf("  DtDbLoad\n");
1251    gettimeofday(&update_time_s, NULL);
1252    /* Added by Aloke Gupta */
1253    _DtPerfChkpntMsgSend("Begin DtDbLoad");
1254
1255 #endif
1256
1257    /*  Set up the messaging and file types  */
1258
1259    DtDbLoad();
1260 #ifdef DT_PERFORMANCE
1261    gettimeofday(&update_time_f, NULL);
1262    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1263       update_time_f.tv_usec += 1000000;
1264       update_time_f.tv_sec--;
1265    }
1266    printf("    done DtDbLoad, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1267
1268    /* Added by Aloke Gupta */
1269    _DtPerfChkpntMsgSend("Done  DtDbLoad");
1270
1271 #endif
1272
1273
1274    /* Create some global strings */
1275    db = XtDatabase(display);
1276    if (XrmGetResource (db, "dttypes.defaultActions",
1277                        "Dttypes.DefaultActions", &rep_type,
1278                        &resource_value))
1279    {
1280      string = XtNewString(resource_value.addr);
1281      for(str = DtStrtok(string, ",") ,i = 0; str != NULL && i < 2 ;
1282      str = DtStrtok(NULL, ","), i++) {
1283        if(i == 0)
1284          openInPlace = XtNewString(str);
1285        else
1286          openNewView = XtNewString(str);
1287      }
1288      XtFree(string);
1289    }
1290    if(openInPlace == NULL || strlen(openInPlace) == 0)
1291        openInPlace = XtNewString("OpenInPlace");
1292    if(openNewView == NULL || strlen(openNewView) == 0)
1293        openNewView = XtNewString("OpenNewView");
1294
1295    DtGetShortHostname (home_host_name, MAX_PATH);
1296
1297    /*  Get the lock established to ensure only one dtfile process  */
1298    /*  is running.                                                  */
1299    if (_DtGetLock (display, DTFILE_CLASS_NAME) == 0)
1300    {
1301       status = InitializeToolTalkProcid( &ttFd, toplevel, False );
1302       if (TT_OK != status)
1303       {
1304           char *errfmt, *errmsg, *title, *statmsg;
1305           title = GETMESSAGE(21,38,"File Manager Error");
1306           errfmt = GETMESSAGE(18, 40,
1307                    "Could not connect to ToolTalk:\n%s\nExiting ...");
1308           statmsg = tt_status_message(status);
1309
1310           errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
1311           fprintf(stderr, errfmt, statmsg);
1312           sprintf(errmsg, errfmt, statmsg);
1313
1314           /* put up error dialog and loop,
1315            * application will exit in dialog callback
1316            */
1317           post_dialog(toplevel, title, errmsg, DtErrExitCB); 
1318       }
1319
1320       if (application_args.session != NULL)
1321       {
1322          msg = tttk_message_create( 0, TT_REQUEST, TT_SESSION, 0,
1323                                     "DtFileSession_Run",
1324                                     (Tt_message_callback)ExitApp );
1325          tt_message_file_set( msg, application_args.session );
1326          tt_message_send( msg );
1327       }
1328       else if (application_args.directories != NULL)
1329       {
1330          msg = tttk_message_create( 0, TT_REQUEST, TT_SESSION, 0,
1331                                     "DtFolder_Show",
1332                                     (Tt_message_callback)ExitApp );
1333          tt_message_file_set( msg, application_args.directories );
1334          SetupSendRequestArgs( application_args, msg );
1335          tt_message_send( msg );
1336       }
1337       else
1338       {
1339          /* Default action: Open up pwd or home dir */
1340          GetPWD(current_directory);
1341
1342          if (current_directory[0] != '\0')
1343          {
1344             msg = tttk_message_create( 0, TT_REQUEST, TT_SESSION, 0,
1345                                        "DtFolder_Show",
1346                                        (Tt_message_callback)ExitApp );
1347             tt_message_file_set( msg, current_directory );
1348          }
1349          else
1350          {
1351             msg = tttk_message_create( 0, TT_REQUEST, TT_SESSION, 0,
1352                                        "DtHome_Show",
1353                                        (Tt_message_callback)ExitApp );
1354          }
1355          SetupSendRequestArgs( application_args, msg );
1356          tt_message_send( msg );
1357       }
1358       WaitForResponseAndExit();
1359    }
1360
1361    /*  Initialize the encapsulation mechanism and install the dialogs  */
1362    /*  used by the file manager.                                       */
1363
1364    _DtInitializeEncapsulation (display, argv[0], DTFILE_CLASS_NAME);
1365    topPositionOffset = -8;
1366
1367    status = InitializeToolTalkProcid( &ttFd, toplevel, True );
1368    if (TT_OK != status)
1369    {
1370        char *errfmt, *errmsg, *title, *statmsg;
1371        title = GETMESSAGE(21,38,"File Manager Error");
1372        errfmt = GETMESSAGE(18, 40,
1373                 "Could not connect to ToolTalk:\n%s\nExiting ...");
1374        statmsg = tt_status_message(status);
1375
1376        errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
1377        fprintf(stderr, errfmt, statmsg);
1378        sprintf(errmsg, errfmt, statmsg);
1379
1380        /* put up error dialog and loop,
1381         * application will exit in dialog callback
1382         */
1383        post_dialog(toplevel, title, errmsg, DtErrExitCB); 
1384    }
1385
1386
1387 #ifdef DT_PERFORMANCE
1388    printf("  Setup Callbacks (messaging)\n");
1389    gettimeofday(&update_time_s, NULL);
1390
1391    /* Added by Aloke Gupta */
1392    _DtPerfChkpntMsgSend("Begin Setup Callbacks");
1393
1394 #endif
1395    events2Watch = tt_pattern_create();
1396    tt_pattern_category_set( events2Watch, TT_OBSERVE );
1397    tt_pattern_class_add( events2Watch, TT_NOTICE );
1398    tt_pattern_scope_add( events2Watch, TT_SESSION );
1399    sessId = tt_default_session();
1400    tt_pattern_session_add( events2Watch, sessId );
1401    tt_free( sessId );
1402    tt_pattern_op_add( events2Watch, "DtTypes_Reloaded" );
1403    tt_pattern_op_add( events2Watch, "XSession_Ending" );
1404    tt_pattern_callback_add( events2Watch, ObserveTtNotice );
1405    tt_pattern_register( events2Watch );
1406
1407    requests2Handle = tt_pattern_create();
1408    tt_pattern_category_set( requests2Handle, TT_HANDLE );
1409    tt_pattern_class_add( requests2Handle, TT_REQUEST );
1410    tt_pattern_scope_add( requests2Handle, TT_SESSION );
1411    sessId = tt_default_session();
1412    tt_pattern_session_add( requests2Handle, sessId );
1413    tt_free( sessId );
1414    tt_pattern_op_add( requests2Handle, "DtFileSession_Run" );
1415    tt_pattern_op_add( requests2Handle, "DtFolder_Show" );
1416    tt_pattern_op_add( requests2Handle, "DtHome_Show" );
1417    tt_pattern_op_add( requests2Handle, "DtTools_Show" );
1418    tt_pattern_op_add( requests2Handle, "DtTrash_Show" );
1419    tt_pattern_op_add( requests2Handle, "DtTrash_Remove" );
1420    tt_pattern_op_add( requests2Handle, "DtTrash_Empty" );
1421    tt_pattern_op_add( requests2Handle, "DtTrash_File" );
1422    tt_pattern_op_add( requests2Handle, "DtTrash_Restore" );
1423    tt_pattern_op_add( requests2Handle, "DtFile_PutOnWorkspace" );
1424    tt_pattern_op_add( requests2Handle, "DtFile_Move" );
1425    tt_pattern_op_add( requests2Handle, "DtFile_Copy" );
1426    tt_pattern_op_add( requests2Handle, "DtFile_Link" );
1427    tt_pattern_callback_add( requests2Handle, HandleTtRequest );
1428    tt_pattern_register( requests2Handle );
1429
1430    /* Setup the settings file if any to setup */
1431
1432    _DtWsmAddMarqueeSelectionCallback(toplevel,
1433                                      (DtWsmMarqueeSelectionProc) MarqueeSelect,
1434                                      NULL);
1435
1436 #ifdef DT_PERFORMANCE
1437    gettimeofday(&update_time_f, NULL);
1438    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1439       update_time_f.tv_usec += 1000000;
1440       update_time_f.tv_sec--;
1441    }
1442    printf("    done Setting Callbacks (messaging), time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1443
1444     /* Added by Aloke Gupta */
1445    _DtPerfChkpntMsgSend("Done  Setup Callbacks");
1446
1447 #endif
1448
1449    smallIconWidth = application_args.smallIconWidth;
1450    smallIconHeight = application_args.smallIconHeight;
1451    largeIconWidth = application_args.largeIconWidth;
1452    largeIconHeight = application_args.largeIconHeight;
1453    user_font = application_args.user_font;
1454    dragThreshold = application_args.dragThreshold;
1455    rereadTime = application_args.rereadTime;
1456    checkBrokenLink = application_args.checkBrokenLink;
1457    maxDirectoryProcesses = application_args.maxDirectoryProcesses;
1458    maxRereadProcesses = application_args.maxRereadProcesses;
1459    maxRereadProcsPerTick = application_args.maxRereadProcsPerTick;
1460    trashWait = application_args.trashWait;
1461    showFilesystem = application_args.showFilesystem;
1462    showDropZone = application_args.showDropZone;
1463    showEmptySet = application_args.showEmptySet;
1464    showEmptyMsg = application_args.showEmptyMsg;
1465    restrictMode = application_args.restrictMode;
1466    openDirType = application_args.openDirType;
1467    desktopIconType = application_args.desktopIconType;
1468    desktopPlacement = application_args.desktopPlacement;
1469    freezeOnConfig = application_args.freezeOnConfig;
1470    emptyTrashOnExit = application_args.emptyTrashOnExit;
1471 #if defined(__hpux) || defined(sun)
1472    follow_links = application_args.follow_links;
1473 #endif
1474    instanceWidth = application_args.instanceIconWidth;
1475    instanceHeight = application_args.instanceIconHeight;
1476    fileMgrIcon = application_args.fileMgrIcon;
1477    appMgrIcon = application_args.appMgrIcon;
1478    trashIcon = application_args.trashIcon;
1479    retryLoadDesktopInfo = application_args.retryLoadDesktop;
1480    if( application_args.directories != NULL
1481        || (strcmp (application_args.restricted, RESTRICTED_HEADER) == 0)
1482        || restrictMode )
1483    {
1484       special_view = True;
1485       if(strcmp (application_args.restricted, RESTRICTED_HEADER) == 0)
1486       {
1487          if(application_args.directories != NULL)
1488             special_restricted = XtNewString(application_args.directories);
1489          else
1490          {
1491             /* Get users pwd so we can set the restricted dir to it */
1492             GetPWD(current_directory);
1493
1494             if (current_directory[0] != '\0')
1495                special_restricted = XtNewString(current_directory);
1496             else
1497                special_restricted = XtNewString("~");
1498          }
1499       }
1500       else if( restrictMode )
1501          special_restricted = XtNewString("~");
1502       else
1503          special_restricted = NULL;
1504       special_treeType = treeType = application_args.tree_view;
1505       special_treeFiles = treeFiles = application_args.tree_files;
1506       special_viewType = viewType = application_args.view;
1507       special_orderType = orderType = application_args.order;
1508       special_directionType = directionType = application_args.direction;
1509       special_randomType = randomType = application_args.grid;
1510       special_title = XtNewString(application_args.title);
1511       if(application_args.help_volume == NULL)
1512       {
1513          special_helpVol = XtNewString(DTFILE_HELP_NAME);
1514          fileMgrHelpVol = XtNewString(DTFILE_HELP_NAME);
1515       }
1516       else
1517       {
1518          special_helpVol = XtNewString(application_args.help_volume);
1519          fileMgrHelpVol = XtNewString(application_args.help_volume);
1520       }
1521       fileMgrTitle = application_args.title;
1522    }
1523    else
1524    {
1525       special_view = False;
1526       treeType = application_args.tree_view;
1527       treeFiles = application_args.tree_files;
1528       viewType = application_args.view;
1529       orderType = application_args.order;
1530       directionType = application_args.direction;
1531       randomType = application_args.grid;
1532       fileMgrTitle = application_args.title;
1533       if(application_args.help_volume == NULL)
1534          fileMgrHelpVol = XtNewString(DTFILE_HELP_NAME);
1535       else
1536          fileMgrHelpVol = XtNewString(application_args.help_volume);
1537    }
1538
1539
1540    if(desktopIconType == LARGE)
1541    {
1542       numRows = displayHeight / PIXELS_PER_ROW_LARGE;
1543       numColumns = displayWidth / PIXELS_PER_COLUMN_LARGE;
1544    }
1545    else /* small */
1546    {
1547       numRows = displayHeight / PIXELS_PER_ROW_SMALL;
1548       numColumns = displayWidth / PIXELS_PER_COLUMN_SMALL;
1549    }
1550
1551 #ifdef SHAPE
1552    /* determine whether the Server has the shape extension */
1553    if(XShapeQueryExtension(display, &base1, &base2) == True)
1554       shapeExtension = True;
1555    else
1556       shapeExtension = False;
1557 #endif
1558
1559    /* get the name for the root directory */
1560    root_title = (char *)XtMalloc(strlen(application_args.root_title) + 1);
1561    strcpy(root_title, application_args.root_title);
1562
1563    if ((homeDir = getenv("HOME")) == NULL || strlen (homeDir) == 0)
1564    {
1565       pwInfo = getpwuid (getuid());
1566       homeDir = pwInfo->pw_dir;
1567    }
1568    strncpy(users_home_dir, homeDir, MAX_PATH - 1);
1569    if(restrictMode)
1570    {
1571       if(application_args.directories != NULL &&
1572                            strncmp(application_args.directories, "~", 1) != 0 )
1573       {
1574          if(strncmp(application_args.directories, users_home_dir,
1575                                                   strlen(users_home_dir)) != 0)
1576             RestrictModeUsage (argv);
1577       }
1578       else if (application_args.directories == NULL)
1579           application_args.directories = XtNewString("~");
1580    }
1581    if (strcmp(users_home_dir, "/") != 0)
1582       strcat(users_home_dir, "/");
1583
1584    XtAppAddActions(XtWidgetToApplicationContext (toplevel), actionTable, 2);
1585
1586    /* Create some global Xm strings for our dialog buttons */
1587
1588    okXmString = XmStringCreateLocalized((char*)_DtOkString);
1589    cancelXmString = XmStringCreateLocalized((char*)_DtCancelString);
1590    helpXmString = XmStringCreateLocalized((char*)_DtHelpString);
1591    applyXmString = XmStringCreateLocalized((char*)_DtApplyString);
1592    closeXmString = XmStringCreateLocalized((char*)_DtCloseString);
1593
1594    /*  Get the dt path created and initialized  */
1595
1596    dt_path = _DtCreateDtDirs (display);
1597
1598    if (dt_path == NULL)
1599    {
1600       Widget dialog;
1601       char *msg, *title;
1602       title = XtNewString((GETMESSAGE(21,38,"File Manager Error")));
1603       tmpStr = GETMESSAGE(18, 2, "Could not create the ~/.dt folder or sub folders.");
1604       msg = XtNewString(tmpStr);
1605
1606       /* put up error dialog and loop, application will exit in 
1607          dialog callback */
1608
1609       dialog = post_dialog(toplevel, title, msg, DtErrExitCB); 
1610       XtFree(msg);
1611       XtFree(title);
1612
1613       while (TRUE)
1614       {
1615         XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );
1616       }
1617     }
1618
1619    /*  Set the black and white pixel globals.  */
1620
1621    black_pixel = BlackPixelOfScreen (XtScreen (toplevel));
1622    white_pixel = WhitePixelOfScreen (XtScreen (toplevel));
1623
1624    /*
1625     * Take over the drawing area's redisplay functions, so that we can get
1626     * the dtfile views to redraw according to stacking order, using our own
1627     * redraw function.
1628     */
1629    xmDrawingAreaWidgetClass->core_class.expose = DrawingAreaRedisplay;
1630
1631
1632    /* Get the root user id */
1633
1634    if ((pw = getpwnam("root")) == NULL)
1635       root_user = 0;          /* Assume root is uid 0 */
1636    else
1637       root_user = pw->pw_uid;
1638
1639
1640    file_mgr_dialog = _DtInstallDialog (fileMgrClass, True, True);
1641    change_dir_dialog = _DtInstallDialog (changeDirClass, True, True);
1642    preferences_dialog = _DtInstallDialog (preferencesClass, True, True);
1643    filter_dialog = _DtInstallDialog (filterClass, True, True);
1644    find_dialog = _DtInstallDialog (findClass, True, True);
1645    mod_attr_dialog = _DtInstallDialog (modAttrClass, True, True);
1646    help_dialog = _DtInstallDialog (helpClass, False, False);
1647
1648    if(special_view == True && special_restricted != NULL) {
1649       if(strncmp(special_restricted, "~", 1) == 0)
1650       {
1651          char *ptr, *ptr1;
1652
1653          special_restricted = _DtChangeTildeToHome(special_restricted);
1654          ptr = strrchr(special_restricted, '/');
1655          ptr1 = ptr + 1;
1656          if(ptr1[0] == '\0')
1657             *ptr = '\0';
1658       }
1659    }
1660
1661    /* Setup the settings file if any to setup */
1662    RestoreSettingsFile();
1663
1664 #ifdef DT_PERFORMANCE
1665    printf("  TrashCreateDialog\n");
1666    gettimeofday(&update_time_s, NULL);
1667
1668    /* Added by Aloke Gupta */
1669    _DtPerfChkpntMsgSend("Begin TrashCreateDialog");
1670
1671 #endif
1672    if( InitializeTrash( application_args.prompt_user ) )
1673
1674 #ifdef DEFER_TRASH_CREATION
1675 ;
1676 #else
1677      TrashCreateDialog (display);
1678 #endif
1679
1680 #ifdef DT_PERFORMANCE
1681    gettimeofday(&update_time_f, NULL);
1682    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1683       update_time_f.tv_usec += 1000000;
1684       update_time_f.tv_sec--;
1685    }
1686    printf("    done TrashCreateDialog, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1687
1688    /* Added by Aloke Gupta */
1689    _DtPerfChkpntMsgSend("Done  TrashCreateDialog");
1690 #endif
1691
1692    /* lets go empty the trash if there is any */
1693 /*
1694    TrashEmpty();
1695 */
1696
1697 #ifdef DT_PERFORMANCE
1698    printf("  Setup Desktop\n");
1699    gettimeofday(&update_time_s, NULL);
1700    /* Added by Aloke Gupta */
1701    _DtPerfChkpntMsgSend("Begin Setup Desktop");
1702
1703 #endif
1704    /* go build 10 desktop windows */
1705    desktop_data = NULL;
1706    InitializeDesktopWindows(10, display);
1707    InitializeDesktopGrid(displayWidth, displayHeight);
1708
1709    LoadDesktopInfo(application_args.session);
1710
1711    /* Install WorkSpaceRemoved handler.
1712       This handler will be called when a workspace is being removed
1713       so File Manager can go through its desktop icons and clean up.
1714    */
1715    DtWsmAddWorkspaceModifiedCallback( toplevel, WorkSpaceRemoved, NULL );
1716
1717 #ifdef DT_PERFORMANCE
1718    gettimeofday(&update_time_f, NULL);
1719    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1720       update_time_f.tv_usec += 1000000;
1721       update_time_f.tv_sec--;
1722    }
1723    printf("    done Setting up Desktop, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1724
1725    /* Added by Aloke Gupta */
1726    _DtPerfChkpntMsgSend("Done  Setup Desktop");
1727 #endif
1728
1729
1730    /*  Process the application resources to restore a session, dt  */
1731    /*  a directory set or display the users home directory.         */
1732
1733 #ifdef DT_PERFORMANCE
1734    printf("  Bring up View\n");
1735    gettimeofday(&update_time_s, NULL);
1736
1737    /* Added by Aloke Gupta */
1738    _DtPerfChkpntMsgSend("Begin Bring up View");
1739
1740 #endif
1741
1742    if (strcmp (application_args.no_view, "-noview") != 0)
1743    {
1744      if (application_args.session != NULL)
1745         session_flag =
1746           RestoreSession (application_args.session, NORMAL_RESTORE, NULL);
1747      else if (application_args.directories != NULL)
1748      {
1749         restoreType = CURRENT_DIR_RESTORE;
1750         OpenDirectories (application_args.directories, NULL);
1751      }
1752    }
1753
1754 #ifdef DT_PERFORMANCE
1755    gettimeofday(&update_time_f, NULL);
1756    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1757       update_time_f.tv_usec += 1000000;
1758       update_time_f.tv_sec--;
1759    }
1760    printf("    done Bringing up view, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);  fflush(stdout);
1761
1762    /* Added by Aloke Gupta */
1763     _DtPerfChkpntMsgSend("Done  Bring up View");
1764 #endif
1765
1766
1767    /*  If no views were opened upon invocation, display the  */
1768    /*  current directory.                                    */
1769
1770    if ( (strcmp (application_args.no_view, "-noview") != 0) &&
1771         ((application_args.session == NULL) ||
1772          (session_flag != 0)) )
1773    {
1774       if (view_count == 0)
1775       {
1776          /* Get users pwd so we can create a fileviewer window of it */
1777          GetPWD(current_directory);
1778
1779          if (current_directory[0] != '\0')
1780          {
1781            if (!GetNewView (home_host_name, current_directory, NULL, NULL, 0))
1782               ViewHomeDirectoryHandler (0);
1783          }
1784          else
1785          {
1786            ViewHomeDirectoryHandler (0);
1787          }
1788       }
1789    }
1790
1791
1792    /*  Set up the timer based directory reading.      */
1793    InitializeDirectoryRead (toplevel);
1794
1795    /* Process and dispatch incoming events */
1796    eventDebugging = getenv("EVENT_DEBUGGING") != NULL;
1797
1798 #ifdef DT_PERFORMANCE
1799    printf("  InitializeToolTalkSession\n");
1800    gettimeofday(&update_time_s, NULL);
1801 #endif
1802    (void) InitializeToolTalkSession( toplevel, ttFd );
1803 #ifdef DT_PERFORMANCE
1804    gettimeofday(&update_time_f, NULL);
1805    if (update_time_s.tv_usec > update_time_f.tv_usec) {
1806       update_time_f.tv_usec += 1000000;
1807       update_time_f.tv_sec--;
1808    }
1809    printf("    done InitializeToolTalkSession, time: %ld.%ld\n\n", update_time_f.tv_sec - update_time_s.tv_sec, update_time_f.tv_usec - update_time_s .tv_usec);
1810 #endif
1811
1812  #ifdef DT_PERFORMANCE
1813    gettimeofday(&update_time_fs, NULL);
1814    if (update_time_ss.tv_usec > update_time_fs.tv_usec) {
1815       update_time_fs.tv_usec += 1000000;
1816       update_time_fs.tv_sec--;
1817    }
1818    printf("    Finish, time: %ld.%ld\n\n", update_time_fs.tv_sec - update_time_ss.tv_sec, update_time_fs.tv_usec - update_time_ss .tv_usec);
1819 #endif
1820
1821    while (1)
1822    {
1823       XtNextEvent(&event);
1824
1825       if (event.type != 0)
1826          XtDispatchEvent(&event);
1827    }
1828
1829    return EXIT_SUCCESS;
1830 }
1831
1832
1833
1834 /************************************************************************
1835  *
1836  *  ErrorHandler
1837  *
1838  ************************************************************************/
1839
1840 static void
1841 ErrorHandler(
1842         Display *disp,
1843         XErrorEvent *event )
1844 {
1845   #define _DTFILE_BUFSIZE 1024
1846   char errmsg[_DTFILE_BUFSIZE];
1847
1848   _DtPrintDefaultErrorSafe (disp, event, errmsg, _DTFILE_BUFSIZE);
1849   _DtSimpleError(application_name, DtWarning, NULL, errmsg, NULL);
1850   xErrorDetected = True;
1851
1852   /* We do not want to exit here lets try to continue... */
1853
1854 }
1855
1856 static void
1857 ToolkitErrorHandler(
1858         char *message )
1859 {
1860     char * msg;
1861     char * tmpStr;
1862
1863     tmpStr = GETMESSAGE(18, 6, "An X Toolkit error occurred... Exiting.\n");
1864     msg = (char *)malloc(strlen(tmpStr) + strlen(message) + 3);
1865     strcpy(msg, message);
1866     strcat(msg, "\n");
1867     strcat(msg, tmpStr);
1868     _DtSimpleError (application_name, DtError, NULL, msg);
1869     printf ("%s",msg);
1870     XtFree(msg);
1871     FinalizeToolTalkSession( );
1872     exit (1);
1873 }
1874
1875
1876
1877
1878 /************************************************************************
1879  *
1880  *  Usage
1881  *      When incorrect parameters have been specified on the command
1882  *      line, print out a set of messages detailing the correct use
1883  *      and exit.
1884  *
1885  ************************************************************************/
1886
1887 static void
1888 Usage(
1889         char **argv )
1890 {
1891    char * template;
1892    char * message_string1 = "\nUsage: %s...\n\n"
1893                          "   -noview\n\n\t"
1894                          "Dtfile runs in server mode.\n\n"
1895                          "   -session SessionFile\n\n\t"
1896                          "Dtfile runs with the session file specified in the SessionFile\n\t"
1897                          "parameter.\n\n"
1898                          "   -folder Folder[,Folder,Folder]\n"
1899                          "   -dir Folder[,Folder,Folder]\n\n\t"
1900                          "Dtfile displays a window for each folder specified in the\n\t"
1901                          "Folder parameter.  The Folder parameter may contain many\n\t"
1902                          "folders separated by commas.  Folders may be in the form\n\t"
1903                          "'path'.\n\n"
1904                          "   -title Title\n\n\t"
1905                          "Dtfile uses the string specified in the Title parameter as the\n\t"
1906                          "title for its windows.\n\n"
1907                          "   -help_volume HelpVolume\n\n\t"
1908                          "Dtfile uses the help volume specified in the HelpVolume parameter.\n\n"
1909                          "   -restricted\n\n\t"
1910                          "Dtfile will not display folders above the restricted folder.\n\t"
1911                          "If the -dir option is used, the folder specified in that option\n\t"
1912                          "is the restricted folder.  If the -dir option is not used, the\n\t"
1913                          "user's current folder is the restricted folder.\n\n"
1914                          "   -grid on/off\n\n\t"
1915                          "on     = Files are displayed in a grid pattern.\n\t"
1916                          "off    = Files are displayed as placed.\n\n"
1917                          "   -tree on/off\n\n\t"
1918                          "on     = Files are displayed in single folder mode.\n";
1919
1920    char * message_string2 = "\toff    = Files are displayed in folder tree mode.\n\n"
1921                          "   -tree_files never/always/choose\n\n\t"
1922                          "never  = Tree mode has two states: partially expanded or collapsed.\n\t"
1923                          "always = Tree mode has two states: fully expanded or collapsed.\n\t"
1924                          "choose = Tree mode has three states: partially expanded, fully\n\t"
1925                          "         expanded, or collapsed.\n\n"
1926                          "   -order alphabetical/file_type/date/size\n\n\t"
1927                          "Files are displayed in the specified order: alphabetical, by file\n\t"
1928                          "type, by date, or by size.\n\n"
1929                          "   -view no_icon/large_icon/small_icon/attributes\n\n\t"
1930                          "Files are displayed in the specified format: text only, text and\n\t"
1931                          "large icons, text and small icons, with attributes.\n\n"
1932                          "   -direction ascending/descending\n\n\t"
1933                          "Files are displayed in the specified direction: ascending or\n\t"
1934                          "descending.\n\n"
1935                          "   -large_icon_width  <size>\n\n"
1936                          "   -large_icon_height <size>\n\n"
1937                          "   -small_icon_width  <size>\n\n"
1938                          "   -small_icon_height <size>\n\n"
1939                          "        The display area size for the icon images in File Manager\n"
1940                          "        Icon images larger than this size will be clipped to this size\n"
1941                          "        The default display area size for large is 38 and small is 24\n\n"
1942                          "\n"
1943 ;
1944
1945    template = (GETMESSAGE(18,23, message_string1));
1946    fprintf (stderr, template, argv[0]);
1947    template = (GETMESSAGE(18,24, message_string2));
1948    fprintf (stderr, "%s", template);
1949
1950    exit (0);
1951 }
1952
1953 static void
1954 RestrictModeUsage(
1955         char **argv )
1956 {
1957    char * template;
1958    char * message_string = "\nRestricted Mode Usage: %s...\n\n"
1959                          "   -folder Folder[,Folder,Folder]\n"
1960                          "   -dir Folder[,Folder,Folder]\n\n\t"
1961                          "Where Folder is a Folder below and/or including\n\t"
1962                          "the user's Home Folder.\n\n";
1963
1964    template = (GETMESSAGE(18,26, message_string));
1965
1966    fprintf (stderr, template, argv[0]);
1967
1968    FinalizeToolTalkSession( );
1969    exit (0);
1970 }
1971
1972
1973
1974
1975 /************************************************************************
1976  *
1977  *  Stop
1978  *      Catches Ctrl C's and exits.
1979  *
1980  ************************************************************************/
1981
1982 static void
1983 Stop( void )
1984 {
1985   FinalizeToolTalkSession( );
1986   exit(0);
1987 }
1988
1989
1990
1991
1992
1993
1994
1995 /***********************************************************************
1996  *
1997  * RestoreSettingsFile
1998  *         Used to restore the save settings files from
1999  *         either $HOME/.dt/$DISPLAY/current or $HOME/.dt/$DISPLAY/home.
2000  *
2001  ***********************************************************************/
2002 static void
2003 RestoreSettingsFile( void )
2004 {
2005    int             status, fd;
2006    char            *dtPath=NULL;
2007    char            *homeSavePath=NULL;
2008    char            *homeHomePath=NULL;
2009    char            *toolSavePath=NULL;
2010    char            *toolHomePath=NULL;
2011    char            *dirName=NULL;
2012    Atom            actualType;
2013    int             actualFormat;
2014    unsigned long   nitems;
2015    unsigned long   leftover;
2016    unsigned char   *data = NULL;
2017
2018
2019   /* go get the dt path */
2020   /* _DtCreateDtDirs returs a path of MaxPath Length */
2021    dtPath = (char *)_DtCreateDtDirs(display);
2022
2023   /* Determin which type of session we are running HOME or CURRENT */
2024
2025   /* get the root window property of SaveMode */
2026   XGetWindowProperty(display, RootWindow(display,0),
2027                          save_mode, 0L, (long)BUFSIZ,False,
2028                          XA_STRING, &actualType,
2029                          &actualFormat,&nitems,&leftover,
2030                          &data);
2031
2032   if(strcmp((char *)data, "home") == 0)
2033     dirName = XtNewString("home");
2034   else if(strcmp((char *)data, "current") == 0)
2035     dirName = XtNewString("current");
2036   else
2037   {
2038     XtFree(dtPath);
2039     return;  /* we are coming up in a system mode (e.g. default) */
2040   }
2041
2042
2043   /* Build the paths to read the files from */
2044
2045   toolSavePath = (char *)XtMalloc(strlen(dtPath) +
2046                   strlen(TOOL_SETTINGS_FILENAME) +
2047                   strlen(dirName) + 4);
2048
2049   homeSavePath = (char *)XtMalloc(strlen(dtPath) +
2050                   strlen(HOME_SETTINGS_FILENAME) +
2051                   strlen(dirName) + 4);
2052
2053   sprintf( homeSavePath, "%s/%s/%s", dtPath, dirName, HOME_SETTINGS_FILENAME );
2054   sprintf( toolSavePath, "%s/%s/%s", dtPath, dirName, TOOL_SETTINGS_FILENAME );
2055
2056   /* open the home settings file to see if its there */
2057   if((fd = open(homeSavePath, O_RDONLY)) != -1)
2058   {
2059       close(fd);
2060      /* create where the saved file is going to go */
2061
2062       homeHomePath = (char *)XtMalloc(strlen(dtPath) +
2063                      strlen(HOME_SETTINGS_FILENAME) + 2);
2064
2065       sprintf( homeHomePath, "%s/%s", dtPath, HOME_SETTINGS_FILENAME );
2066
2067      /* remove any existing dtfile.home (e.g. HOME_SETTINGS_FILENAME) */
2068       unlink(homeHomePath);
2069
2070      /* copy the saved one into $HOME/.dt/$DISPLAY ... this is the one that
2071       * will be used by the dtfile
2072       */
2073       status = link(homeSavePath, homeHomePath);
2074       if(status != 0)
2075       {
2076         char *tmpStr, *msg;
2077
2078         tmpStr = GETMESSAGE(18,27, "Unable to recover the saved default home settings file, will use default.\n");
2079         msg = XtNewString(tmpStr);
2080         _DtSimpleErrnoError(application_name, DtWarning, NULL, msg, NULL);
2081         XtFree(msg);
2082       }
2083
2084    }
2085
2086  /* open the tool settings file to see if its there */
2087   if((fd = open(toolSavePath, O_RDONLY)) != -1)
2088   {
2089       close(fd);
2090      /* create where the saved file is going to go */
2091       toolHomePath = (char *)XtMalloc(strlen(dtPath) +
2092                      strlen(TOOL_SETTINGS_FILENAME) + 2);
2093
2094       sprintf( toolHomePath, "%s/%s", dtPath, TOOL_SETTINGS_FILENAME );
2095
2096      /* remove any existing dtfile.tool (e.g. TOOL_SETTINGS_FILENAME) */
2097       unlink(toolHomePath);
2098
2099      /* copy the saved one into $HOME/.dt/$DISPLAY ... this is the one that
2100       * will be used by the dtfile
2101       */
2102       status = link(toolSavePath, toolHomePath);
2103       if(status != 0)
2104       {
2105         char *tmpStr, *msg;
2106
2107         tmpStr = GETMESSAGE(18,28, "Unable to recover the saved default tool settings file, will use default.\n");
2108         msg = XtNewString(tmpStr);
2109         _DtSimpleErrnoError(application_name, DtWarning, NULL, msg, NULL);
2110         XtFree(msg);
2111       }
2112    }
2113
2114
2115   /* free up space */
2116    XFree(data);
2117    XtFree(dtPath);
2118    XtFree(dirName);
2119    XtFree(homeSavePath);
2120    XtFree(toolSavePath);
2121    XtFree(toolHomePath);
2122    XtFree(homeHomePath);
2123
2124
2125 }
2126
2127
2128
2129
2130
2131 /***********************************************************************
2132  *
2133  * MoveDefaultSettings
2134  *         Used to save the dtfile.tool and dtfile.home settings files to
2135  *         either $HOME/.dt/$DISPLAY/current or $HOME/.dt/$DISPLAY/home.
2136  *         The parameter mode determines whether it is home or
2137  *         current.
2138  *
2139  ***********************************************************************/
2140 static void
2141 MoveDefaultSettings(
2142         int mode )
2143 {
2144    int status;
2145    char *toolSavePath=NULL;
2146    char *homeSavePath=NULL;
2147    char *dirName=NULL;
2148    char *toolMovePath=NULL;
2149    char *homeMovePath=NULL;
2150    char *dtPath;
2151
2152    /* determine whether home or current */
2153    if(mode == HOME_DIR_RESTORE)
2154      dirName = XtNewString("home");
2155    else
2156      dirName = XtNewString("current");
2157
2158   /* go get the dt path */
2159   /* _DtCreateDtDirs returs a path of MaxPath Length */
2160   dtPath = (char *)_DtCreateDtDirs(display);
2161
2162
2163   /* Build the paths to save the files to */
2164
2165   toolSavePath = (char *)XtMalloc(strlen(dtPath) +
2166                   strlen(TOOL_SETTINGS_FILENAME) +
2167                   strlen(dirName) + 4);
2168
2169   homeSavePath = (char *)XtMalloc(strlen(dtPath) +
2170                   strlen(HOME_SETTINGS_FILENAME) +
2171                   strlen(dirName) + 4);
2172
2173
2174    /* create the directory and filename of where its going to be saved */
2175   sprintf( homeSavePath, "%s/%s/%s", dtPath, dirName, HOME_SETTINGS_FILENAME );
2176   sprintf( toolSavePath, "%s/%s/%s", dtPath, dirName, TOOL_SETTINGS_FILENAME );
2177
2178    /* Setup the paths used to GET the old files */
2179
2180    toolMovePath= (char *)XtMalloc(strlen(dtPath) +
2181                    strlen(TOOL_SETTINGS_FILENAME) + 3);
2182
2183    homeMovePath= (char *)XtMalloc(strlen(dtPath) +
2184                    strlen(HOME_SETTINGS_FILENAME) + 3);
2185
2186    /* create the filename of where its going to be saved from */
2187
2188    /* Tool File location */
2189    sprintf( toolMovePath, "%s/%s", dtPath, TOOL_SETTINGS_FILENAME );
2190
2191    /* Home File location */
2192    sprintf( homeMovePath, "%s/%s", dtPath, HOME_SETTINGS_FILENAME );
2193
2194
2195   /* get rid of the tool settings file that is already in home or current */
2196    status = unlink(toolSavePath);
2197
2198   /* get rid of the home settings file that is already in home or current */
2199    status = unlink(homeSavePath);
2200
2201
2202   /* now save tool settings file in home or current determined by savePath */
2203    status = link(toolMovePath, toolSavePath);
2204
2205   /* now save home settings file in home or current determined by savePath */
2206    status = link(homeMovePath, homeSavePath);
2207
2208    /* free up space */
2209    XtFree(homeMovePath);
2210    XtFree(toolMovePath);
2211    XtFree(homeSavePath);
2212    XtFree(toolSavePath);
2213    XtFree(dirName);
2214    XtFree(dtPath);
2215 }
2216
2217
2218 /************************************************************************
2219  *
2220  *  SaveSettingsCB
2221  *      Callback for the Save Settings menupick.
2222  *
2223  ************************************************************************/
2224 void
2225 SaveSettingsCB(
2226         Widget w,
2227         XtPointer client_data,
2228         XtPointer call_data )
2229 {
2230    Widget dlog;
2231    Widget mbar;
2232    Arg args[1];
2233    char * message;
2234    char * title;
2235    FileMgrRec * file_mgr_rec;
2236    DialogData * dialog_data;
2237    FileMgrData * file_mgr_data;
2238    char * tmpStr;
2239
2240    /* Strip the file_mgr_rec from the current widget
2241    * and attach it to the ok callback button
2242    */
2243
2244
2245    /* Get the file_mgr_rec hanging off the menubar */
2246    mbar = XmGetPostedFromWidget(XtParent(w));
2247    XmUpdateDisplay (w);
2248    XtSetArg(args[0], XmNuserData, &file_mgr_rec);
2249    XtGetValues(mbar, args, 1);
2250
2251
2252    /* Ignore accelerators when we're insensitive */
2253    if ((file_mgr_rec->menuStates & SETTINGS) == 0)
2254    {
2255      XSetInputFocus(XtDisplay(w),
2256                     XtWindow(file_mgr_rec->defaultEnvBtn_child),
2257                     RevertToParent, CurrentTime);
2258      return;
2259    }
2260
2261    /* Desensatize the save settings menu pick here */
2262    file_mgr_rec->menuStates &= ~SETTINGS;
2263
2264
2265    /* Get the file_mgr_rec dialog data info */
2266    if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
2267      return;
2268    file_mgr_data = (FileMgrData *) dialog_data->data;
2269
2270
2271    /* Based on the path we must determine if we are saving a Tools or
2272     * HomeDir dtfile view.
2273     */
2274    if (file_mgr_data->restricted_directory != NULL && file_mgr_data->toolbox)
2275      file_mgr_data->restoreKind = TOOL_RESTORE;
2276    else
2277      file_mgr_data->restoreKind = HOME_RESTORE;
2278
2279
2280    /* Setup and call the _DtMessageDialog procedure to post the dialog */
2281
2282    if (file_mgr_data->restoreKind == HOME_RESTORE)
2283    {
2284      tmpStr = (GETMESSAGE(18,29, "Save the current File Manager View window size,\npreferences, and filter settings?\n\nThey will be used for any new File Manager View windows\nstarted from the Front Panel."));
2285    }
2286    else
2287    {
2288      tmpStr = (GETMESSAGE(18,35, "Save the current Application Manager\nView window size, preferences, and filter settings?\n\nThey will be used for any new Application Manager\nwindows started from the Front Panel."));
2289    }
2290    message = XtNewString(tmpStr);
2291
2292    if(file_mgr_data->title != NULL &&
2293                strcmp(file_mgr_data->helpVol, DTFILE_HELP_NAME) != 0)
2294    {
2295       tmpStr = GETMESSAGE(18, 16, "Save As Default Options");
2296       title = (char *)XtMalloc(strlen(tmpStr) +
2297                                  strlen(file_mgr_data->title) + 5);
2298       sprintf(title, "%s - %s", file_mgr_data->title, tmpStr);
2299    }
2300    else
2301    {
2302       tmpStr = GETMESSAGE(18, 32, "File Manager - Save As Default Options");
2303       title = XtNewString(tmpStr);
2304    }
2305    dlog = (Widget)_DtMessageDialog(mbar, title, message, NULL, TRUE,
2306                                    SaveDefaultCancelCB, SaveDefaultOkCB, NULL,
2307                                    HelpRequestCB, False, QUESTION_DIALOG);
2308    file_mgr_rec->defaultEnvBtn_child=dlog;
2309    XtFree (message);
2310    XtFree (title);
2311
2312
2313    /* Add array as userdata on the dialog. */
2314
2315    XtSetArg(args[0], XmNuserData, file_mgr_rec);
2316    XtSetValues(dlog, args, 1);
2317
2318 }
2319
2320 /************************************************************************
2321  *
2322  *  SaveDefaultCancelCB
2323  *      Cleanup and unmanage the save settings dialog.
2324  *
2325  ************************************************************************/
2326 static void
2327 SaveDefaultCancelCB(
2328         Widget w,
2329         XtPointer client_data,
2330         XtPointer call_data )
2331 {
2332   FileMgrRec * file_mgr_rec;
2333   Arg args[1];
2334
2335     /* Update the display, and un-post the dialog */
2336     XtUnmanageChild((Widget)client_data);
2337     XmUpdateDisplay((Widget)client_data);
2338     XtSetArg(args[0], XmNuserData, &file_mgr_rec);
2339     XtGetValues((Widget)client_data, args, 1);
2340
2341
2342     /* Re-sensatize the save settings menu pick */
2343     file_mgr_rec->menuStates |= SETTINGS;
2344
2345
2346     XtDestroyWidget((Widget)client_data);
2347
2348 }
2349
2350
2351 /************************************************************************
2352  *
2353  *  SaveDefaultOkCB
2354  *      Save the current dtfile view as the default environment for
2355  *      new dtfiles created.
2356  *
2357  ************************************************************************/
2358 static void
2359 SaveDefaultOkCB(
2360         Widget w,
2361         XtPointer client_data,
2362         XtPointer call_data )
2363 {
2364
2365    FileMgrRec * file_mgr_rec;
2366    static char * name_list[] = { DTFILE_CLASS_NAME, NULL, NULL };
2367    char view_number[5];
2368    int fd;
2369    Arg args[1];
2370
2371    DialogData * dialog_data;
2372    FileMgrData * file_mgr_data;
2373    char * msg;
2374    char * tmp_path;
2375    char full_path[MAX_PATH + 1];
2376    char * tmpStr;
2377    char * save_host;
2378    char * save_directory;
2379    char ** save_branch_list;
2380    FileViewData ** save_selection_list;
2381    int save_selected_file_count;
2382
2383
2384    /* Get the file_mgr_rec hanging off the dialog */
2385    XtUnmanageChild((Widget)client_data);
2386    XmUpdateDisplay ((Widget)client_data);
2387    XtSetArg(args[0], XmNuserData, &file_mgr_rec);
2388    XtGetValues((Widget)client_data, args, 1);
2389
2390
2391    /* Re-sensatize the save settings menu pick */
2392    file_mgr_rec->menuStates |= SETTINGS;
2393
2394
2395    /* Get the file_mgr_rec dialog data info */
2396
2397    dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
2398    file_mgr_data = (FileMgrData *) dialog_data->data;
2399
2400
2401    /* Build the path for our env file */
2402
2403    tmp_path = _DtCreateDtDirs(display);
2404    if (tmp_path == NULL)
2405      {
2406        XtDestroyWidget(client_data);
2407        return;
2408      }
2409
2410
2411    /* Look and see what type of restore we are doing */
2412    if (file_mgr_data->restoreKind == TOOL_RESTORE)
2413    {
2414       sprintf(full_path, "%s/%s", tmp_path, TOOL_SETTINGS_FILENAME);
2415       application_args.tool_width = file_mgr_data->width;
2416       application_args.tool_height = file_mgr_data->height;
2417    }
2418    else
2419    {
2420       sprintf(full_path, "%s/%s", tmp_path, HOME_SETTINGS_FILENAME);
2421       application_args.dir_width = file_mgr_data->width;
2422       application_args.dir_height = file_mgr_data->height;
2423    }
2424
2425    XtFree(tmp_path);
2426
2427
2428    /*  Create the Environment session file  */
2429
2430    if ((fd = creat(full_path, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
2431    {
2432       char *title;
2433       tmpStr = GETMESSAGE(18, 17, "Unable to create a file to store the default options.");
2434       title = XtNewString((GETMESSAGE(21,38,"Object Create Error")));
2435       msg = XtNewString(tmpStr);
2436       _DtMessage (toplevel, title, msg, NULL, HelpRequestCB);
2437       XtFree(msg);
2438       XtFree(title);
2439       return;
2440    }
2441
2442
2443    /*  Write out the general information  */
2444
2445    (void) write (fd, "*", strlen ("*"));
2446    (void) write (fd, DTFILE_CLASS_NAME,strlen (DTFILE_CLASS_NAME));
2447    (void) write (fd, "*view_count:      ", strlen ("*view_count:      "));
2448
2449    (void) sprintf (view_number, "%d", 1);
2450    (void) write (fd, view_number, strlen (view_number));
2451    (void) write (fd, "\n#\n", strlen ("\n#\n"));
2452
2453    name_list[1] = view_number;
2454
2455    /* Temporarily remove data that we don't need or want saved */
2456
2457    save_host = file_mgr_data->host;
2458    save_directory = file_mgr_data->current_directory;
2459    save_branch_list = file_mgr_data->branch_list;
2460    save_selection_list = file_mgr_data->selection_list;
2461    save_selected_file_count = file_mgr_data->selected_file_count;
2462    file_mgr_data->host = NULL;
2463    file_mgr_data->current_directory = NULL;
2464    file_mgr_data->branch_list = NULL;
2465    file_mgr_data->selection_list = NULL;
2466    file_mgr_data->selected_file_count = 0;
2467
2468    /*  Call the encapsulation mechanism to write each dialog  */
2469
2470    (void) sprintf (view_number, "%d", 0);
2471    _DtWriteDialogData (dialog_data, fd, name_list);
2472    (void) write (fd, "#\n", strlen ("#\n"));
2473
2474    /* Restore the data that was temporarily removed */
2475
2476    file_mgr_data->host = save_host;
2477    file_mgr_data->current_directory = save_directory;
2478    file_mgr_data->branch_list = save_branch_list;
2479    file_mgr_data->selection_list = save_selection_list;
2480    file_mgr_data->selected_file_count = save_selected_file_count;
2481
2482    (void) close (fd);
2483
2484    XtDestroyWidget(client_data);
2485
2486 }
2487
2488
2489
2490 /************************************************************************
2491  *
2492  *  SaveSessionCallback
2493  *      Get the session name and call the function to save the session.
2494  *
2495  ************************************************************************/
2496
2497 void
2498 SaveSessionCallback(
2499         Widget w,
2500         XtPointer client_data,
2501         XtPointer call_data )
2502 {
2503    char * full_path=NULL;
2504    char * file_name=NULL;
2505    char * strPtr;
2506    int restore=NORMAL_RESTORE;
2507    Boolean status=FALSE;
2508    char * sessionFileName;
2509    char ** argv;
2510
2511    if(view_count == 0 && desktop_data->numIconsUsed == 0)
2512    {
2513       XChangeProperty (display, XtWindow (toplevel), command_atom,
2514                     XA_STRING, 8, PropModeReplace, (unsigned char *)NULL, 0);
2515       XSync(display, False);
2516       FinalizeToolTalkSession( );
2517       exit(0);
2518    }
2519
2520    status = DtSessionSavePath(w, &full_path, &file_name);
2521
2522    if (status)
2523      sessionFileName = file_name;
2524    else
2525    {
2526      XtFree( (char *)full_path);
2527      full_path = (char *) XtMalloc (sizeof (char) * MAX_PATH);
2528      sprintf( full_path, "%s/%s", dt_path, DTFILE_CLASS_NAME );
2529      sessionFileName = full_path;
2530    }
2531    SaveSession( full_path );
2532
2533    /* skip to the /.dt/ portion of the sessionFileName */
2534    strPtr = strstr(full_path, "/.dt/");
2535    (void)strcpy(full_path, strPtr);
2536
2537    /* Save off the settings files for both tool and home views */
2538    do {
2539         strPtr = DtStrrchr(full_path, '/');
2540         if ( !strPtr )
2541            continue;
2542         if ((strncmp(strPtr, "/home", 5) == 0))
2543            restore = HOME_DIR_RESTORE;
2544         else if ((strncmp(strPtr, "/current", 8) == 0))
2545            restore = CURRENT_DIR_RESTORE;
2546
2547         if (strPtr != NULL)
2548           *strPtr = '\0';
2549    } while ((strPtr != NULL) && (restore == NORMAL_RESTORE));
2550
2551    SaveDesktopInfo(restore);
2552
2553    /* Cop the settings files to the proper dir */
2554    MoveDefaultSettings(restore);
2555
2556    /*  Generate the reinvoking command and add it as the property value */
2557    argv = (char **) XtMalloc(3 * sizeof(char *));
2558    argv[0] = XtNewString(application_name);
2559    argv[1] = XtNewString("-session");
2560    argv[2] = XtNewString(sessionFileName);
2561    XSetCommand(XtDisplay(toplevel), XtWindow(toplevel), argv, 3);
2562
2563    XtFree ((char *) argv[0]);
2564    XtFree ((char *) argv[1]);
2565    XtFree ((char *) argv[2]);
2566    XtFree ((char *) argv);
2567
2568    XtFree ((char *) full_path);
2569    XtFree ((char *) file_name);
2570 }
2571
2572 /************************************************************************
2573  *
2574  *  SaveSession
2575  *      Save the current File Manager session as a set of resources
2576  *      within the file denoted by path.
2577  *
2578  ************************************************************************/
2579
2580 static void
2581 SaveSession(
2582         char *path
2583         )
2584 {
2585    static char * name_list[] = { DTFILE_CLASS_NAME, NULL, NULL, NULL,
2586                                  NULL, NULL};
2587    char view_number[5];
2588    char number[5];
2589    char workspaceNumber[5];
2590    int fd;
2591    Atom * ws_presence = NULL;
2592    char * workspace_name=NULL;
2593    unsigned long num_workspaces = 0;
2594
2595    Atom actual_type;
2596    int  actual_format;
2597    unsigned long nitems;
2598    unsigned long leftover;
2599    WM_STATE * wm_state;
2600
2601    DialogData * dialog_data;
2602    FileMgrData * file_mgr_data;
2603    FileMgrRec  * file_mgr_rec;
2604    int i;
2605    int j;
2606    char * msg;
2607    int view_index;
2608    WorkspaceRec * workspaceInfo;
2609    char * tmpStr;
2610    Boolean saveTitle;
2611    char *actualSavedTitle;
2612
2613    /* This needs to be done because name_list is static and the values
2614       can be changed during the routine.  This means that they need to be
2615       NULL'd out each pass */
2616    name_list[1] = NULL;
2617    name_list[2] = NULL;
2618    name_list[3] = NULL;
2619    name_list[4] = NULL;
2620    name_list[5] = NULL;
2621
2622    /*  Disable any message box display during save session  */
2623
2624    message_display_enabled = False;
2625
2626
2627    /*  Create the session file  */
2628
2629    if ((fd = creat (path, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
2630    {
2631       tmpStr = GETMESSAGE(18, 18, "Could not open the session file.");
2632       msg = XtNewString(tmpStr);
2633       _DtSimpleError (application_name, DtError, NULL, msg);
2634       XtFree(msg);
2635       message_display_enabled = True;
2636
2637       return;
2638    }
2639
2640
2641    /*  Write out the general information  */
2642
2643    /* Number of dtfile views */
2644    (void) write (fd, "*", strlen ("*"));
2645    (void) write (fd, DTFILE_CLASS_NAME, strlen (DTFILE_CLASS_NAME));
2646    (void) write (fd, "*view_count:      ", strlen ("*view_count:        "));
2647
2648    if (trashFileMgrData)
2649    {
2650       if (trashFileMgrData->file_mgr_rec)
2651          (void) sprintf (view_number, "%d", view_count + 1);
2652       else
2653          (void) sprintf (view_number, "%d", view_count);
2654    }
2655    else
2656    {
2657       (void) sprintf (view_number, "%d", view_count);
2658    }
2659    (void) write (fd, view_number, strlen (view_number));
2660    (void) write (fd, "\n#\n", strlen ("\n#\n"));
2661
2662    (void) write (fd, "*", strlen ("*"));
2663    (void) write (fd, DTFILE_CLASS_NAME, strlen (DTFILE_CLASS_NAME));
2664    (void) write (fd, "*showFilesystem:  ", strlen ("*showFilesystem:    "));
2665
2666    if(showFilesystem)
2667       (void) write (fd, "True", strlen ("True"));
2668    else
2669       (void) write (fd, "False", strlen ("False"));
2670    (void) write (fd, "\n#\n", strlen ("\n#\n"));
2671
2672    (void) write (fd, "*", strlen ("*"));
2673    (void) write (fd, DTFILE_CLASS_NAME, strlen (DTFILE_CLASS_NAME));
2674    (void) write (fd, "*restrictMode:    ", strlen ("*restrictMode:      "));
2675
2676    if(restrictMode)
2677       (void) write (fd, "True", strlen ("True"));
2678    else
2679       (void) write (fd, "False", strlen ("False"));
2680    (void) write (fd, "\n#\n", strlen ("\n#\n"));
2681
2682    (void) write (fd, "*", strlen ("*"));
2683    (void) write (fd, DTFILE_CLASS_NAME, strlen (DTFILE_CLASS_NAME));
2684    (void) write (fd, "*openFolder:      ", strlen ("*openFolder:        "));
2685
2686    if(openDirType == NEW)
2687       (void) write (fd, "NEW", strlen ("NEW"));
2688    else
2689       (void) write (fd, "CURRENT", strlen ("CURRENT"));
2690    (void) write (fd, "\n#\n", strlen ("\n#\n"));
2691
2692    view_index = 0;
2693    name_list[1] = view_number;
2694    saveTitle = False;
2695
2696
2697    /*  Write out each of the view's resources  */
2698    /*  start with -1 so we can include the trash dialog */
2699    for (i = -1; i < view_count; i++)
2700    {
2701       if(i == -1)
2702       {
2703          if(trashDialogData)
2704             dialog_data = (DialogData *) trashDialogData;
2705          else
2706             continue;
2707       }
2708       else
2709       {
2710          dialog_data = (DialogData *) view_set[i]->dialog_data;
2711       }
2712
2713       file_mgr_data = (FileMgrData *) dialog_data->data;
2714       if(i == -1 && trashDialogData)
2715           file_mgr_data->IsTrashCan = True;
2716       file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
2717       if(file_mgr_rec == NULL)
2718          continue;
2719
2720       /* This is a bug fix ... We don't want to save the title if the
2721          View is the Trash Can of if it is an Application Manager.  This
2722          is because if the user saves a session in one Locale, then logs
2723          in in another, the Title will be in the locale that the session was
2724          saved in rather then the new local.  So let's save the Title,
2725          Null it out, Save the session info, and finally restore the Title.
2726       */
2727       if(i == -1 || file_mgr_data->toolbox)
2728       {
2729          /* the Trash Can or toolbox (i.e. Application Manager) */
2730          actualSavedTitle = file_mgr_data->title;
2731          file_mgr_data->title = NULL;
2732          saveTitle = True;
2733       }
2734
2735       /*  Getting the WM_STATE property to see if iconified or not */
2736       XGetWindowProperty (display, XtWindow (file_mgr_rec->shell),
2737                              wm_state_atom, 0L, (long) BUFSIZ, False,
2738                              wm_state_atom, &actual_type, &actual_format,
2739                              &nitems, &leftover, (unsigned char **) &wm_state);
2740
2741       /* Write out if iconified our not */
2742
2743       write (fd, "*", strlen ("*"));
2744       write (fd, DTFILE_CLASS_NAME, strlen (DTFILE_CLASS_NAME));
2745       sprintf (view_number, "%d", view_index);
2746       write (fd, ".", strlen ("."));
2747       write (fd, view_number, strlen (view_number));
2748
2749       (void) write (fd, ".iconify:      ", strlen (".iconify:   "));
2750
2751       if (wm_state->state == IconicState)
2752         write (fd, "True\n", strlen ("True\n"));
2753       else
2754         write (fd, "False\n", strlen ("False\n"));
2755
2756
2757       /*  Get the workspaces for this dt by accessing the property.  */
2758
2759       if (DtWsmGetWorkspacesOccupied (display, XtWindow (file_mgr_rec->shell),
2760                                   &ws_presence, &num_workspaces) == Success)
2761       {
2762          write (fd, "*", strlen ("*"));
2763          write (fd, DTFILE_CLASS_NAME, strlen (DTFILE_CLASS_NAME));
2764          (void) write (fd, ".", strlen ("."));
2765          (void) write (fd, view_number, strlen (view_number));
2766          (void) write (fd, ".workspace: ", strlen (".workspace: "));
2767
2768
2769          for (j = 0; j < num_workspaces; j++)
2770          {
2771             if (j != 0) (void) write (fd, "*", strlen ("*"));
2772             workspace_name = XGetAtomName (display, ws_presence[j]);
2773             (void) write (fd, workspace_name, strlen (workspace_name));
2774             XtFree ((char *) workspace_name);
2775          }
2776
2777
2778          (void) write (fd, "\n", strlen ("\n"));
2779          XFree((char *)ws_presence);
2780       }
2781
2782
2783       /*  Call the encapsulation mechanism to write each dialog  */
2784
2785       if(i == -1)
2786          _DtWriteDialogData (trashDialogData, fd, name_list);
2787       else
2788          _DtWriteDialogData ((DialogData *)view_set[i]->dialog_data,
2789                              fd, name_list);
2790       (void) write (fd, "#\n", strlen ("#\n"));
2791
2792       view_index++;
2793       if(saveTitle)
2794       {
2795          file_mgr_data->title = actualSavedTitle;
2796          saveTitle = False;
2797       }
2798    }
2799
2800    /*
2801     * Save off help dialog information for each workspace.
2802     * These are the help dialogs used for the desktop objects.
2803     */
2804    name_list[1] = WS_LOAD_RES_HEADER;
2805    name_list[2] = workspaceNumber;
2806    name_list[3] = number;
2807
2808    for (i = 0; i < desktop_data->numWorkspaces; i++)
2809    {
2810       workspaceInfo = desktop_data->workspaceData[i];
2811
2812       /*
2813        * Save number of secondary help dialogs in format:
2814        *     *Dtfile.Workspace.<WS#>.secondaryHelpDialogCount:  <#>
2815        */
2816       write(fd, "*", strlen("*"));
2817       write(fd, DTFILE_CLASS_NAME, strlen(DTFILE_CLASS_NAME));
2818       write(fd, WS_RES_HEADER, strlen(WS_RES_HEADER));
2819       sprintf(workspaceNumber, "%d", i);
2820       write(fd, workspaceNumber, strlen(workspaceNumber));
2821       write(fd, SEC_HELP_RES_HEADER, strlen(SEC_HELP_RES_HEADER));
2822       sprintf(view_number, "%d", workspaceInfo->secondaryHelpDialogCount);
2823       write(fd, view_number, strlen(view_number));
2824       write (fd, "\n#\n", strlen ("\n#\n"));
2825
2826       /* Save each of the secondary help dialogs */
2827       for (j = 0; j < workspaceInfo->secondaryHelpDialogCount; j++)
2828       {
2829          sprintf(number, "%d", j + 1);
2830          _DtWriteDialogData(workspaceInfo->secondaryHelpDialogList[j],
2831                            fd, name_list);
2832       }
2833
2834       /* Save the primary help dialog window */
2835       if (workspaceInfo->primaryHelpDialog)
2836       {
2837          sprintf(number, "%d", 0);
2838          _DtWriteDialogData(workspaceInfo->primaryHelpDialog,
2839                            fd, name_list);
2840       }
2841       write (fd, "#\n", strlen ("#\n"));
2842    }
2843    (void) close (fd);
2844
2845    /*  Re-able message box display flag after save session  */
2846    message_display_enabled = True;
2847
2848
2849 }
2850
2851
2852
2853 /*
2854  * Given a directory name, this function will see if a view of the parent
2855  * directory is open; if so, then it will update the icon representing
2856  * this icon, in the parent view, so that it is drawn as 'open'.  This
2857  * function must only be called if openDirType == NEW.
2858  */
2859
2860 void
2861 ForceMyIconOpen (
2862    char * host_name,
2863    char * directory_name)
2864 {
2865    FileViewData * file_view_data = NULL;
2866    DesktopRec *desktopWindow;
2867    DialogData * dd;
2868    FileMgrData * fmd;
2869    char * parent;
2870    char * fname;
2871    char * ptr;
2872    char * full_path;
2873    int i, j, k;
2874    char *icon_name, *new_file_type_name, *file_type_name;
2875    Arg args[5];
2876
2877    /* if directory_name is passed in a NULL, we want to go through all
2878       existing open directories and check to see if there are any open
2879       directories in each of them. This is used at the end of OpenNewView
2880       and the end of ShowNewDirectory */
2881    if (directory_name == NULL)
2882    {
2883       for (i = 0; i < view_count; i++)
2884       {
2885          dd = (DialogData *) view_set[i]->dialog_data;
2886          fmd = (FileMgrData *) dd->data;
2887
2888          for(j = 0; j < fmd->directory_count; j++)
2889          {
2890             ForceMyIconOpen(view_set[i]->host_name,
2891                             fmd->directory_set[j]->name);
2892          }
2893       }
2894       return;
2895    }
2896
2897    parent = _DtPName(directory_name);
2898    fname =  DName(directory_name);
2899
2900    /* first lets check to see if the directory is open in one of the
2901       open file manager views */
2902    for (i = 0; i < view_count; i++)
2903    {
2904       dd = (DialogData *) view_set[i]->dialog_data;
2905       fmd = (FileMgrData *) dd->data;
2906
2907       /* loop through until we find the file_view_data structure for the
2908          directory to force open */
2909       if (strcmp(host_name, view_set[i]->host_name) == 0)
2910       {
2911          for(j = 0; j < fmd->directory_count; j++)
2912          {
2913             if (strcmp(parent, fmd->directory_set[j]->name) == 0)
2914             {
2915                for (k = 0; k < fmd->directory_set[j]->file_count; k++)
2916                {
2917                   file_view_data = fmd->directory_set[j]->file_view_data[k];
2918                   if (strcmp(file_view_data->file_data->file_name, fname) == 0)
2919                      break;
2920                   file_view_data = NULL;
2921                }
2922                break;
2923             }
2924          }
2925       }
2926
2927       if (file_view_data)
2928       {
2929          fmd = (FileMgrData *)(((DirectorySet *)file_view_data->directory_set)->
2930                            file_mgr_data);
2931
2932          file_type_name = file_view_data->file_data->logical_type;
2933
2934          if(fmd->view != BY_NAME)
2935             BuildAndShowIconName(file_type_name, fmd->view,
2936                                  fmd->show_type, file_view_data->widget);
2937       }
2938    }
2939
2940    /* now we need to check to see if the directory being opened has a
2941       representation on the Desktop */
2942    for(i = 0; i < desktop_data->numIconsUsed; i++)
2943    {
2944       char buf[MAX_PATH];
2945
2946       desktopWindow = desktop_data->desktopWindows[i];
2947       file_view_data = desktopWindow->file_view_data;
2948
2949       sprintf(buf, "%s/%s", desktopWindow->dir_linked_to,
2950                             desktopWindow->file_name);
2951       DtEliminateDots (buf);
2952
2953       if (strcmp(buf, directory_name) == 0 &&
2954                                     strcmp(desktopWindow->host, host_name) == 0)
2955       {
2956          file_type_name = file_view_data->file_data->logical_type;
2957          if(desktopIconType == LARGE)
2958              BuildAndShowIconName(file_type_name, BY_NAME_AND_ICON,
2959                                  SINGLE_DIRECTORY, desktopWindow->iconGadget);
2960          else /* SMALL */
2961              BuildAndShowIconName(file_type_name, BY_NAME_AND_SMALL_ICON,
2962                                  SINGLE_DIRECTORY, desktopWindow->iconGadget);
2963       }
2964    }
2965 }
2966
2967
2968
2969
2970 /************************************************************************
2971  *
2972  *  RestoreSession
2973  *      Open the file as a resource data base, and use the data to
2974  *      create a set of File Manager views.
2975  *
2976  ************************************************************************/
2977
2978 static int
2979 RestoreSession(
2980         char *path,
2981         int type_of_restore,
2982         char *directory)
2983 {
2984    static char * name_list[] = { DTFILE_CLASS_NAME, NULL, NULL, NULL,
2985                                  NULL, NULL };
2986    XrmDatabase db;
2987    XrmName xrm_name[10];
2988    XrmRepresentation rep_type;
2989    XrmValue value;
2990    int num_views = 0;
2991    char * full_path = NULL;
2992    Boolean status=False;
2993    char * temp = NULL;
2994    char wsNum[5];
2995    char dialogNum[5];
2996    int num_sec_help_dialogs;
2997    int i;
2998    int j;
2999    DialogData * dialogData;
3000    struct stat stat_buf;
3001
3002
3003    /* Build the session path if we need to.
3004     * (e.g. When using the -session option)
3005     */
3006     if (type_of_restore == NORMAL_RESTORE)
3007     {
3008       status = DtSessionRestorePath(toplevel, &full_path, path);
3009
3010       if (!status)
3011          return(-1);
3012
3013       if (stat(full_path, &stat_buf) != 0)
3014       {
3015         char *tmpStr, *msg, *title;
3016
3017         tmpStr = GETMESSAGE(18, 18, "Could not open the session file.");
3018         msg = XtNewString(tmpStr);
3019         title = XtNewString((GETMESSAGE(21,39,"File Open Error")));
3020         _DtMessage (toplevel, title, msg, NULL, HelpRequestCB);
3021         XtFree(msg);
3022         XtFree(title);
3023         XtFree(full_path);
3024         full_path = NULL;
3025         return(-1);
3026       }
3027
3028       path = XtNewString(full_path);
3029     }
3030
3031    /* This prevents the encapsulator from placing the dialogs */
3032    disableDialogAutoPlacement = True;
3033
3034    /*  Open the file as a resource database and query it to  */
3035    /*  get the previously saved view count.                  */
3036
3037    db = XrmGetFileDatabase (path);
3038
3039    if (type_of_restore == NORMAL_RESTORE)
3040    {
3041       /* first find out if it should show the file system */
3042       xrm_name [0] = XrmStringToQuark (DTFILE_CLASS_NAME);
3043       xrm_name [1] = XrmStringToQuark ("showFilesystem");
3044       xrm_name [2] = 0;
3045       if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3046       {
3047          if ((temp = (char *) value.addr) != NULL &&
3048                  strcmp (temp, "True") == 0)
3049          {
3050             showFilesystem = True;
3051          }
3052          else
3053             showFilesystem = False;
3054       }
3055       else
3056          showFilesystem = True;
3057
3058       /* find out if it should be in restricted mode */
3059       xrm_name [0] = XrmStringToQuark (DTFILE_CLASS_NAME);
3060       xrm_name [1] = XrmStringToQuark ("restrictMode");
3061       xrm_name [2] = 0;
3062       if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3063       {
3064          if ((temp = (char *) value.addr) != NULL &&
3065                  strcmp (temp, "True") == 0)
3066          {
3067             restrictMode = True;
3068          }
3069          else
3070             restrictMode = False;
3071       }
3072       else
3073          restrictMode = False;
3074
3075       /* find out openFolder mode */
3076       xrm_name [0] = XrmStringToQuark (DTFILE_CLASS_NAME);
3077       xrm_name [1] = XrmStringToQuark ("openFolder");
3078       xrm_name [2] = 0;
3079       if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3080       {
3081          if ((temp = (char *) value.addr) != NULL &&
3082                  strcmp (temp, "NEW") == 0)
3083          {
3084             openDirType = NEW;
3085          }
3086          else
3087             openDirType = CURRENT;
3088       }
3089       else
3090          openDirType = CURRENT;
3091    }
3092
3093    xrm_name [0] = XrmStringToQuark (DTFILE_CLASS_NAME);
3094    xrm_name [1] = XrmStringToQuark ("view_count");
3095    xrm_name [2] = 0;
3096
3097    /* Load standard dtfile views */
3098    if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3099    {
3100       num_views = atoi (value.addr);
3101       if (num_views > 0)
3102          LoadViews(num_views, db, NULL, directory, special_restricted, 0);
3103    }
3104
3105    /* Restore any desktop help dialogs */
3106    if (type_of_restore == NORMAL_RESTORE)
3107    {
3108       for (i = 0; i < desktop_data->numWorkspaces; i++)
3109       {
3110          sprintf(wsNum, "%d", i);
3111          xrm_name [0] = XrmStringToQuark (DTFILE_CLASS_NAME);
3112          xrm_name [1] = XrmStringToQuark (WS_LOAD_RES_HEADER);
3113          xrm_name [2] = XrmStringToQuark (wsNum);
3114          xrm_name [3] = XrmStringToQuark (SEC_LOAD_HELP_RES_HEADER);
3115          xrm_name [4] = 0;
3116
3117          /* Load standard dtfile views */
3118          if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3119          {
3120             num_sec_help_dialogs = atoi (value.addr);
3121             if (num_sec_help_dialogs > 0)
3122             {
3123                desktop_data->workspaceData[i]->secondaryHelpDialogCount =
3124                   num_sec_help_dialogs;
3125                desktop_data->workspaceData[i]->secondaryHelpDialogList =
3126                 (DialogData **) XtMalloc(sizeof(DialogData *) *
3127                    num_sec_help_dialogs);
3128
3129                for (j = 0; j < num_sec_help_dialogs; j++)
3130                {
3131                   name_list[0] = DTFILE_CLASS_NAME;
3132                   name_list[1] = WS_LOAD_RES_HEADER;
3133                   name_list[2] = wsNum;
3134                   name_list[3] = dialogNum;
3135                   name_list[4] = NULL;
3136                   sprintf(dialogNum, "%d", j + 1);
3137                   dialogData =
3138                        _DtGetResourceDialogData(help_dialog, db, name_list);
3139                   desktop_data->workspaceData[i]->secondaryHelpDialogList[j]=
3140                      dialogData;
3141                   ShowDTHelpDialog(NULL, i, HYPER_HELP_DIALOG,
3142                                    dialogData, NULL, NULL, NULL, NULL,
3143                                    DtHELP_TYPE_TOPIC);
3144                }
3145             }
3146          }
3147
3148          /* Load the primary help dialog */
3149          name_list[0] = DTFILE_CLASS_NAME;
3150          name_list[1] = WS_LOAD_RES_HEADER;
3151          name_list[2] = wsNum;
3152          name_list[3] = dialogNum;
3153          name_list[4] = NULL;
3154          sprintf(dialogNum, "%d", 0);
3155          dialogData = _DtGetResourceDialogData(help_dialog, db, name_list);
3156
3157          /* Keep only if currently posted */
3158          if (!(((HelpData *)dialogData->data)->displayed))
3159          {
3160             /* Not currently displayed */
3161             _DtFreeDialogData(dialogData);
3162             dialogData = NULL;
3163          }
3164          desktop_data->workspaceData[i]->primaryHelpDialog = dialogData;
3165          if (dialogData)
3166          {
3167             ShowDTHelpDialog(NULL, i, MAIN_HELP_DIALOG,
3168                              dialogData, NULL, DTFILE_HELP_NAME,
3169                              NULL, NULL, 0);
3170          }
3171       }
3172    }
3173
3174    XtFree(full_path);
3175    full_path = NULL;
3176
3177    /* Free the Xrm Database */
3178    XrmDestroyDatabase(db);
3179    disableDialogAutoPlacement = False;
3180
3181    return(0);
3182 }
3183
3184
3185 static void
3186 ViewAccept(
3187    View *view,
3188    Tt_message msg)
3189 {
3190    extern Tt_message FileCallback();
3191    extern Tt_message SessionCallback();
3192
3193    if ((msg == 0) || tt_is_err( tt_ptr_error( msg ))) {
3194       return;
3195    }
3196    view->msg = msg;
3197    /*
3198     * Register for notifications on the directory viewed.
3199     * This is done so that requesting apps can notify the
3200     * view if the directory name is changed.
3201     */
3202    view->pats = ttdt_file_join( view->directory_name, TT_SESSION, 0,
3203                                 FileCallback, view );
3204    if (tt_is_err( tt_ptr_error( view->pats ))) {
3205       view->pats = 0;
3206    }
3207
3208    /* Returned patterns automatically get destroyed when msg is destroyed */
3209    ttdt_message_accept( msg, SessionCallback,
3210                         _DtGetDialogShell( (DialogData *)view->dialog_data ),
3211                         view, 1, 1 );
3212 }
3213
3214
3215 static void
3216 LoadViews (
3217    int num_views,
3218    XrmDatabase db,
3219    char *host_name,
3220    char *directory_name,
3221    char *type,
3222    Tt_message msg)
3223
3224 {
3225    XrmName xrm_name[5];
3226    XrmRepresentation rep_type;
3227    XrmValue value;
3228    static char * name_list[] = { DTFILE_CLASS_NAME, NULL, NULL };
3229    char view_number[5];
3230    DialogData * dialog_data;
3231    FileMgrData * file_mgr_data;
3232    char * workspaces;
3233    XClassHint classHints;
3234    char * iconify = NULL;
3235    Boolean iconify_window;
3236    int i;
3237    char *title, *tmpTitle;
3238
3239    name_list[1] = view_number;
3240    xrm_name [0] = XrmStringToQuark (DTFILE_CLASS_NAME);
3241
3242
3243    /*  Get and display view_count views.  */
3244
3245    for (i = 0; i < num_views; i++)
3246    {
3247       struct stat stat_buf;
3248
3249       (void) sprintf (view_number, "%d", i);
3250       xrm_name [1] = XrmStringToQuark (view_number);
3251
3252       /* Get the main dialog data and set up the view  */
3253
3254       dialog_data = _DtGetResourceDialogData (file_mgr_dialog, db, name_list);
3255       file_mgr_data = (FileMgrData *) dialog_data->data;
3256
3257       if(file_mgr_data->toolbox && file_mgr_data->title == NULL)
3258          file_mgr_data->title = DtActionLabel("Dtappmgr");
3259
3260       if (stat(file_mgr_data->current_directory, &stat_buf) != 0)
3261       {
3262          _DtFreeDialogData(dialog_data);
3263          continue;
3264       }
3265
3266       if (trashFileMgrData
3267           && (file_mgr_data->IsTrashCan == True)
3268           && strcmp(file_mgr_data->current_directory, trash_dir) == 0)
3269       {
3270          trashFileMgrData->view = file_mgr_data->view;
3271          trashFileMgrData->order = file_mgr_data->order;
3272          trashFileMgrData->direction = file_mgr_data->direction;
3273          trashFileMgrData->positionEnabled = file_mgr_data->positionEnabled;
3274          trashFileMgrData->preferences = file_mgr_data->preferences;
3275          file_mgr_data->preferences = NULL;
3276          _DtFreeDialogData(dialog_data);
3277          continue;
3278       }
3279
3280       /* Increment the view list size if necessary and add directory to list */
3281
3282       if (view_count == view_set_size)
3283       {
3284          view_set_size += 10;
3285          view_set =
3286             (View **) XtRealloc ((char *)view_set,
3287                                      sizeof (View **) * view_set_size);
3288       }
3289       view_set[view_count] = (View *) XtMalloc (sizeof (View));
3290       view_set[view_count]->dialog_data = (XtPointer) dialog_data;
3291       view_set[view_count]->msg = 0;
3292       view_set[view_count]->pats = 0;
3293
3294       if(restoreType == TOOL_RESTORE)
3295          file_mgr_data->toolbox = True;
3296
3297       if(directory_name == NULL)
3298       {
3299          view_set[view_count]->host_name = XtNewString (file_mgr_data->host);
3300          view_set[view_count]->directory_name =
3301             XtNewString (file_mgr_data->current_directory);
3302       }
3303       else
3304       {
3305          XtFree(file_mgr_data->current_directory);
3306          file_mgr_data->current_directory = NULL;
3307          XtFree(file_mgr_data->restricted_directory);
3308          file_mgr_data->restricted_directory = NULL;
3309
3310          view_set[view_count]->directory_name = XtNewString(directory_name);
3311          XtFree((char *)file_mgr_data->selection_list);
3312          file_mgr_data->selection_list = NULL;
3313          if(host_name == NULL)
3314          {
3315             view_set[view_count]->host_name = XtNewString (file_mgr_data->host);
3316             file_mgr_data->current_directory = XtNewString(directory_name);
3317             if(type == NULL)
3318               file_mgr_data->restricted_directory =
3319                                               XtNewString(directory_name);
3320             else
3321               file_mgr_data->restricted_directory =
3322                                               XtNewString(type);
3323          }
3324          else
3325          {
3326             view_set[view_count]->host_name = XtNewString (host_name);
3327             XtFree(file_mgr_data->host);
3328             file_mgr_data->host = XtNewString(host_name);
3329             file_mgr_data->current_directory = XtNewString(directory_name);
3330             if(special_view && special_restricted != NULL)
3331                file_mgr_data->restricted_directory =
3332                                      XtNewString(special_restricted);
3333             else
3334                file_mgr_data->restricted_directory = NULL;
3335          }
3336          FileMgrBuildDirectories (file_mgr_data,
3337                           view_set[view_count]->host_name, directory_name);
3338       }
3339
3340       /*  Get the workspace set the view is contained in  */
3341       /*  and set the property for the view just created  */
3342
3343       xrm_name [2] = XrmStringToQuark ("workspace");
3344       xrm_name [3] = 0;
3345
3346       if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3347       {
3348          /*  Make sure we have some valid workspaces names to work with */
3349
3350          /* value.addr should = NULL if no workspace names */
3351          workspaces = (char *) value.addr;
3352       }
3353       else
3354         /* we have no workspace resource so use default */
3355         workspaces = NULL;
3356
3357       /*  Get and set whether the view is iconic  */
3358
3359       xrm_name [2] = XrmStringToQuark ("iconify");
3360       xrm_name [3] = 0;
3361
3362       if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
3363       {
3364          /*  If there is an iconify resource and its value is True,  */
3365          /*  then mark the window as iconified.                      */
3366
3367          if ((iconify = (char *) value.addr) != NULL &&
3368               strcmp (iconify, "True") == 0)
3369          {
3370            iconify_window = True;
3371
3372          }
3373          else
3374           iconify_window = False;
3375       }
3376       else
3377          iconify_window = False;
3378
3379      if(file_mgr_data->positionEnabled == RANDOM_ON &&
3380                         (file_mgr_data->object_positions == NULL))
3381         LoadPositionInfo(file_mgr_data);
3382
3383       /* Call _DtShowDialog to create and manage the new window */
3384
3385      tmpTitle = file_mgr_data->title;
3386      title = file_mgr_data->title = _DtBuildFMTitle(file_mgr_data);
3387      if (special_title)
3388         XtFree(special_title);
3389      special_title = XtNewString(title);
3390
3391      classHints.res_name = title;
3392      classHints.res_class = DTFILE_CLASS_NAME;
3393
3394      _DtShowDialog (NULL, NULL, NULL, dialog_data, NULL, NULL,
3395                     RemoveTextFields, NULL, workspaces, iconify_window,
3396                     special_view, title, &classHints);
3397
3398      XtFree(title);
3399      file_mgr_data->title = tmpTitle;
3400
3401      if (msg != 0) {
3402         ViewAccept( view_set[view_count], msg );
3403         msg = 0;
3404      }
3405
3406      view_count++;
3407    }
3408
3409    if (openDirType == NEW)
3410       ForceMyIconOpen(file_mgr_data->host, NULL);
3411 }
3412
3413
3414 /************************************************************************
3415  *
3416  *  GetPWD
3417  *
3418  ************************************************************************/
3419 static void
3420 GetPWD(
3421         char current_directory[] )
3422 {
3423    FILE * pwd_file = NULL;
3424    int i = 0;
3425
3426     /*  Open a pwd process and read the current working directory  */
3427     /*  from it.  If the open fails or a read fails, then display  */
3428     /*  the users home directory.                                  */
3429
3430       pwd_file = popen ("pwd", "r");
3431
3432       if (pwd_file)
3433       {
3434          while (1)
3435          {
3436             errno = 0;
3437             if (fread (&current_directory[i], sizeof(char), 1, pwd_file) != 1)
3438             {
3439                if (errno == EINTR)
3440                   continue;
3441                else
3442                   break;
3443             }
3444
3445             if (current_directory[i] == '\n')
3446                break;
3447
3448             i++;
3449          }
3450       }
3451
3452       if (pwd_file)
3453           pclose (pwd_file);
3454
3455       current_directory[i] = '\0';
3456 }
3457
3458 /************************************************************************
3459  *
3460  *  OpenDirectories
3461  *      Given a string that contains a single or set of host:path
3462  *      specifications, parse out each host:path, validate it as
3463  *      a accessible directory, and call a function to create a
3464  *      file manager view of the directory.
3465  *
3466  ************************************************************************/
3467
3468 static void
3469 OpenDirectories(
3470         char *directory_set,
3471         char *type)
3472 {
3473    char * separator;
3474    char * host;
3475    char * path;
3476
3477    /*  Loop the the directory set string until all of  */
3478    /*  the path specifications have be parsed.    */
3479
3480    while (1)
3481    {
3482       separator = DtStrchr (directory_set, ',');
3483       if (separator != NULL)
3484          *separator = '\0';
3485
3486       _DtPathFromInput(directory_set, NULL, &host, &path);
3487
3488       if (path)
3489       {
3490          GetNewView (host, path, type, NULL, 0);
3491       }
3492       else
3493       {
3494          char *tmpStr, *errTitle, *errMsg, *dmsg;
3495
3496          tmpStr = GETMESSAGE(32, 2, "File Manager Open Directory Error");
3497          errTitle = XtNewString(tmpStr);
3498          tmpStr = GETMESSAGE(18, 38, "Invalid folder specification, %s");
3499          errMsg = XtNewString(tmpStr);
3500          dmsg = XtMalloc(strlen(errMsg)+strlen(directory_set)+1);
3501          sprintf(dmsg, errMsg, directory_set);
3502          _DtMessage(toplevel, errTitle, dmsg, NULL, HelpRequestCB);
3503
3504          XtFree(errTitle);
3505          XtFree(errMsg);
3506          XtFree(dmsg);
3507       }
3508
3509       /*  Free up the unique host and directory names  */
3510       /*  that were allocated.                         */
3511
3512       XtFree ((char *) host);
3513       XtFree ((char *) path);
3514
3515       /*  Set the starting position of the next host:path  */
3516
3517       if (separator != NULL)
3518          directory_set = separator + 1;
3519       else
3520          break;
3521    }
3522 }
3523
3524
3525
3526
3527 /************************************************************************
3528  *
3529  *  GetNewView
3530  *      Given a directory name, generate a new view for the directory.
3531  *
3532  ************************************************************************/
3533 DialogData *
3534 GetNewView(
3535         char *host_name,
3536         char *directory_name,
3537         char *type,
3538         WindowPosition *position,
3539         Tt_message msg)
3540 {
3541    DialogData * dialog_data;
3542    DialogInstanceData * instance_data;
3543    FileMgrData * file_mgr_data;
3544    FileMgrData * fmd;
3545    FileMgrRec * file_mgr_rec;
3546    char * real_directory_name;
3547    int i;
3548    XClassHint classHints;
3549    char *title, *tmpTitle;
3550    struct stat stat_buf;
3551    char *tmpStr;
3552    char *errMsg = NULL;
3553
3554    DtEliminateDots( directory_name );
3555
3556    if (stat(directory_name, &stat_buf) == 0)
3557    {
3558       if ((stat_buf.st_mode & S_IFMT) != S_IFDIR)
3559       {
3560          tmpStr = GETMESSAGE(18, 19,
3561                   "The folder specification,\n%s\nis not a folder.");
3562          errMsg = XtNewString(tmpStr);
3563       }
3564    }
3565    else
3566    {
3567       tmpStr = GETMESSAGE(18, 20,
3568                "The folder specification,\n%s\ndoes not exist.");
3569       errMsg = XtNewString(tmpStr);
3570    }
3571
3572    if (errMsg)
3573    {
3574       char *title, *dmsg;
3575
3576       tmpStr = GETMESSAGE(32, 2, "File Manager Open Directory Error");
3577       title = XtNewString(tmpStr);
3578       dmsg = XtMalloc(strlen(errMsg) +
3579                       strlen(directory_name) + 1);
3580       sprintf(dmsg, errMsg, directory_name);
3581       _DtMessage(toplevel, title, dmsg, NULL, HelpRequestCB);
3582
3583       XtFree(errMsg);
3584       XtFree(title);
3585       XtFree(dmsg);
3586       return(NULL);
3587    }
3588
3589    /*
3590     * Special case: When opening any of the special desktop directory
3591     * icons (Home, Remote Systems, etc), we want to display the correct
3592     * path (i.e. $HOME instead of $HOME/.dt/Desktop/Home).  So ... we'll
3593     * do the remap here.
3594     */
3595    real_directory_name = directory_name;
3596
3597    if(openDirType == NEW || (strcmp(real_directory_name, desktop_dir) == 0))
3598    {
3599       for(i = 0; i < view_count; i++)
3600       {
3601          if((strcmp(real_directory_name, view_set[i]->directory_name) == 0 &&
3602             (strcmp(host_name, view_set[i]->host_name) == 0))
3603                                   )
3604          {
3605              Window   rootWindow;
3606              Atom     pCurrent;
3607              Screen   *currentScreen;
3608              int      screen;
3609
3610              dialog_data = (DialogData *) view_set[i]->dialog_data;
3611              file_mgr_data = (FileMgrData *) dialog_data->data;
3612              file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
3613
3614              screen = XDefaultScreen(display);
3615              currentScreen = XScreenOfDisplay(display, screen);
3616              rootWindow = RootWindowOfScreen(currentScreen);
3617
3618              /* Get the current Workspace */
3619              if (DtWsmGetCurrentWorkspace(display, rootWindow, &pCurrent)
3620                                                                    == Success)
3621              {
3622                 Atom * ws_presence = NULL;
3623                 unsigned long num_workspaces = 0;
3624                 int k;
3625
3626                 if (DtWsmGetWorkspacesOccupied(display,
3627                      XtWindow(file_mgr_rec->shell), &ws_presence,
3628                      &num_workspaces) == Success)
3629                 {
3630                    /* Already in this workspace? */
3631                    for (k = 0; k < num_workspaces; k++)
3632                    {
3633                       if (ws_presence[k] == pCurrent)
3634                          break;
3635                    }
3636
3637                    if (k >= num_workspaces)
3638                    {
3639                       /* Add to the workspace */
3640                       ws_presence = (Atom *) XtRealloc((char *)ws_presence,
3641                            sizeof (Atom) * (num_workspaces + 1));
3642
3643                       ws_presence[num_workspaces] = pCurrent;
3644                       DtWsmSetWorkspacesOccupied(display,
3645                                           XtWindow(file_mgr_rec->shell),
3646                                           ws_presence, num_workspaces + 1);
3647                    }
3648                    XFree((char *)ws_presence);
3649                 }
3650                 else
3651                 {
3652                    /* Change the hints to reflect the current workspace */
3653                    DtWsmSetWorkspacesOccupied(display,
3654                                            XtWindow(file_mgr_rec->shell),
3655                                            &pCurrent, 1);
3656                 }
3657              }
3658
3659              /* must map the window to catch iconified windows */
3660              /* a XtPopup will not catch it */
3661              XtMapWidget(file_mgr_rec->shell);
3662              XRaiseWindow(display, XtWindow(file_mgr_rec->shell));
3663
3664              /* announce activity */
3665              {
3666                 Tt_message msg;
3667                 msg = tt_pnotice_create(TT_SESSION, "DtActivity_Began");
3668                 tt_message_send(msg);
3669                 tttk_message_destroy(msg);
3670              }
3671
3672              return(NULL);
3673          }
3674       }
3675    }
3676
3677    /* If in novice mode, force the icon for this dir to the 'Open' state */
3678    if (openDirType == NEW)
3679       ForceMyIconOpen(host_name, directory_name);
3680
3681    /*  Increment the list size if necessary.  */
3682
3683    if (view_count == view_set_size)
3684    {
3685       view_set_size += 10;
3686       view_set =
3687          (View **) XtRealloc ((char *)view_set,
3688                                     sizeof (View **) * view_set_size);
3689    }
3690
3691    view_set[view_count] = (View *) XtMalloc (sizeof (View));
3692    view_set[view_count]->msg = 0;
3693    view_set[view_count]->pats = 0;
3694
3695    if (initiating_view != NULL)
3696       dialog_data = _DtGetDefaultDialogData (file_mgr_dialog);
3697    else
3698    {
3699       char * tmp_path;
3700       char full_path[MAX_PATH + 1];
3701       XrmDatabase db;
3702
3703       tmp_path = _DtCreateDtDirs(display);
3704       if(type != NULL)
3705          sprintf(full_path, "%s/%s", tmp_path, TOOL_SETTINGS_FILENAME);
3706       else
3707          sprintf(full_path, "%s/%s", tmp_path, HOME_SETTINGS_FILENAME);
3708       XtFree(tmp_path);
3709       db = XrmGetFileDatabase (full_path);
3710       if(db != NULL)
3711       {
3712          if(type != NULL)
3713          {
3714             restoreType = TOOL_RESTORE;
3715             LoadViews(1, db, NULL, directory_name, type, msg);
3716          }
3717          else
3718          {
3719             restoreType = HOME_RESTORE;
3720             LoadViews(1, db, host_name, directory_name, NULL, msg);
3721          }
3722
3723          /*
3724           * Free the Xrm Database
3725           */
3726          XrmDestroyDatabase(db);
3727          dialog_data = (DialogData *)view_set[view_count - 1]->dialog_data;
3728          file_mgr_data = (FileMgrData *) dialog_data->data;
3729          if(type != NULL)
3730          {
3731             application_args.tool_width = file_mgr_data->width;
3732             application_args.tool_height = file_mgr_data->height;
3733          }
3734          else
3735          {
3736             application_args.dir_width = file_mgr_data->width;
3737             application_args.dir_height = file_mgr_data->height;
3738          }
3739          if(file_mgr_data->find != NULL &&
3740                                 file_mgr_data->current_directory != NULL)
3741          {
3742             DialogData * dialog_data;
3743             FindData * find_data;
3744
3745             dialog_data = (DialogData *)file_mgr_data->find;
3746             find_data = (FindData *)dialog_data->data;
3747
3748             XtFree(find_data->directories);
3749             if(file_mgr_data->restricted_directory == NULL)
3750             {
3751                if(restrictMode)
3752                   find_data->directories = XtNewString(users_home_dir);
3753                else
3754                   find_data->directories =
3755                             XtNewString(file_mgr_data->current_directory);
3756             }
3757             else
3758             {
3759                if(strcmp(file_mgr_data->current_directory,
3760                          file_mgr_data->restricted_directory) == 0)
3761                   find_data->directories = XtNewString("/");
3762                else
3763                   find_data->directories =
3764                         XtNewString(file_mgr_data->current_directory +
3765                         strlen(file_mgr_data->restricted_directory));
3766             }
3767          }
3768
3769          /* If in novice mode, force the icon for all the dir's to the
3770             'Open' state */
3771          if (openDirType == NEW)
3772             ForceMyIconOpen(host_name, NULL);
3773
3774          return((DialogData *)view_set[view_count - 1]->dialog_data);
3775       }
3776       else
3777          dialog_data = _DtGetDefaultDialogData (file_mgr_dialog);
3778    }
3779    view_set[view_count]->dialog_data = (XtPointer) dialog_data;
3780    file_mgr_data = (FileMgrData *) dialog_data->data;
3781
3782    /*  Adjust the view settings if this new view was created  */
3783    /*  because of an action on a previous view.               */
3784
3785    if (initiating_view != NULL)
3786    {
3787       FileMgrPropagateSettings ((FileMgrData *)initiating_view, file_mgr_data);
3788       /* force new window to come up in flat mode */
3789       file_mgr_data->show_type =
3790         ((PreferencesData *)file_mgr_data->preferences->data)->show_type =
3791                                                               SINGLE_DIRECTORY;
3792       file_mgr_data->view = file_mgr_data->view_single;
3793    }
3794
3795       /*  Call the FileMgr dialog to build up its directory set for  */
3796       /*  the directory name.                                        */
3797    FileMgrBuildDirectories (file_mgr_data, host_name, real_directory_name);
3798
3799    if(type != NULL)
3800    {
3801       PreferencesData *preferences_data;
3802
3803       file_mgr_data->toolbox = True;
3804       file_mgr_data->width = application_args.tool_width;
3805       file_mgr_data->height = application_args.tool_height;
3806
3807       /* we want to default for the toolboxes (i.e. Application Manager) to
3808        * look different from a normal File Manager view.  Let's turn off
3809        * the iconic_path, current_directory, and status_line.
3810        */
3811       file_mgr_data->show_iconic_path = False;
3812       file_mgr_data->show_current_dir = False;
3813 /*
3814       file_mgr_data->show_status_line = True;
3815 */
3816
3817       preferences_data = (PreferencesData *)file_mgr_data->preferences->data;
3818       preferences_data->show_iconic_path = file_mgr_data->show_iconic_path;
3819       preferences_data->show_current_dir = file_mgr_data->show_current_dir;
3820       preferences_data->show_status_line = file_mgr_data->show_status_line;
3821    }
3822    else
3823    {
3824       file_mgr_data->toolbox = False;
3825       file_mgr_data->width = application_args.dir_width;
3826       file_mgr_data->height = application_args.dir_height;
3827    }
3828
3829
3830    if(file_mgr_data->find != NULL && file_mgr_data->current_directory != NULL)
3831    {
3832       DialogData * dialog_data;
3833       FindData * find_data;
3834
3835       dialog_data = (DialogData *)file_mgr_data->find;
3836       find_data = (FindData *)dialog_data->data;
3837
3838       XtFree(find_data->directories);
3839       if(file_mgr_data->restricted_directory == NULL)
3840       {
3841          if(restrictMode)
3842             find_data->directories = XtNewString(users_home_dir);
3843          else
3844             find_data->directories =
3845                             XtNewString(file_mgr_data->current_directory);
3846       }
3847       else
3848       {
3849          if(strcmp(file_mgr_data->current_directory,
3850                    file_mgr_data->restricted_directory) == 0)
3851             find_data->directories = XtNewString("/");
3852          else
3853             find_data->directories =
3854                    XtNewString(file_mgr_data->current_directory +
3855                    strlen(file_mgr_data->restricted_directory));
3856       }
3857    }
3858
3859    view_set[view_count]->host_name = XtNewString (file_mgr_data->host);
3860    view_set[view_count]->directory_name =
3861          XtNewString (file_mgr_data->current_directory);
3862
3863    /* Load default position info, or inherit, if appropriate */
3864    if ((fmd = (FileMgrData *)initiating_view) &&
3865        (strcmp(fmd->host, host_name) == 0) &&
3866        (strcmp(fmd->current_directory, real_directory_name) == 0))
3867    {
3868       InheritPositionInfo(fmd, file_mgr_data);
3869    }
3870    else
3871       LoadPositionInfo(file_mgr_data);
3872
3873
3874    /*  Get the dialog displayed.  */
3875    if (position)
3876    {
3877       instance_data = (DialogInstanceData *) dialog_data->data;
3878       instance_data->x = position->x;
3879       instance_data->y = position->y;
3880       instance_data->displayed = True;  /* @@@ Hack! without this,
3881                                           _DtShowDialog will ignore
3882                                            our position info */
3883    }
3884
3885    tmpTitle = file_mgr_data->title;
3886    title = file_mgr_data->title = _DtBuildFMTitle(file_mgr_data);
3887    if (special_title)
3888       XtFree(special_title);
3889    special_title = XtNewString(title);
3890
3891    classHints.res_name = title;
3892    classHints.res_class = DTFILE_CLASS_NAME;
3893    initiating_view = NULL;
3894
3895    _DtShowDialog (NULL, NULL, NULL, dialog_data, NULL, NULL, RemoveTextFields,
3896                NULL, NULL, False, special_view, title, &classHints);
3897
3898    XtFree(title);
3899    file_mgr_data->title = tmpTitle;
3900
3901    if (msg != 0) {
3902       ViewAccept( view_set[view_count], msg );
3903       msg = 0;
3904    }
3905
3906    view_count++;
3907
3908    /* If in novice mode, force the icon for all the dir's to the 'Open' state */
3909    if (openDirType == NEW)
3910       ForceMyIconOpen(host_name, NULL);
3911
3912    return(dialog_data);
3913 }
3914
3915
3916
3917
3918 /************************************************************************
3919  *
3920  *  CloseView
3921  *      Update the view set array when a view is closed.
3922  *
3923  ************************************************************************/
3924
3925 void
3926 CloseView(
3927         DialogData *dialog_data )
3928 {
3929    register int i;
3930    register int j;
3931    FileMgrData * file_mgr_data;
3932    DialogData * tmpDialog_data;
3933    FileMgrRec * file_mgr_rec;
3934    XmManagerWidget file_window;
3935    char *directory_name = NULL;
3936    char *host_name = NULL;
3937
3938    if(dialog_data == trashDialogData)
3939    {
3940       CloseTrash(NULL, NULL, NULL);
3941       return;
3942    }
3943
3944    for (i = 0; i < view_count; i++)
3945    {
3946       if (dialog_data == (DialogData *) (view_set[i]->dialog_data))
3947       {
3948          tmpDialog_data = (DialogData *) (view_set[i]->dialog_data);
3949          file_mgr_data = (FileMgrData *)tmpDialog_data->data;
3950
3951          directory_name = (char *)XtMalloc( strlen(view_set[i]->directory_name) + 1);
3952          strcpy(directory_name, view_set[i]->directory_name);
3953          host_name = (char *)XtMalloc( strlen(view_set[i]->host_name) + 1);
3954          strcpy(host_name, view_set[i]->host_name);
3955
3956          if (view_set[i]->msg != 0) {
3957             if (view_set[i]->pats != 0) {
3958                ttdt_file_quit( view_set[i]->pats, 0 );
3959                view_set[i]->pats = 0;
3960             }
3961             tt_message_reply( view_set[i]->msg );
3962             tttk_message_destroy( view_set[i]->msg );
3963             view_set[i]->msg = 0;
3964          }
3965
3966          XtFree ((char *) view_set[i]->directory_name);
3967          XtFree ((char *) view_set[i]->host_name);
3968          XtFree ((char *) view_set[i]);
3969          view_set[i] = NULL;
3970
3971          for (j = i; j < view_count - 1; j++)
3972             view_set[j] = view_set[j + 1];
3973
3974          view_count--;
3975
3976          _DtHideDialog (dialog_data, True);
3977
3978          file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
3979          file_window = (XmManagerWidget)file_mgr_rec->file_window;
3980          /* For next time, unmanage all the icons */
3981          XtUnmanageChildren(file_window->composite.children,
3982                             file_window->composite.num_children);
3983
3984          if(PositionFlagSet(file_mgr_data))
3985             SavePositionInfo(file_mgr_data);
3986
3987          /* If it is an Application Manager view, then no point in
3988           caching this dialog, so free it */
3989
3990          if(file_mgr_data->toolbox)
3991             _DtFreeDialog(dialog_data);
3992
3993          _DtFreeDialogData (dialog_data);
3994
3995          break;
3996       }
3997    }
3998
3999
4000    /*  Update the directory cache list to remove unneeded directories.  */
4001
4002    UpdateCachedDirectories (view_set, view_count);
4003
4004    if (openDirType == NEW)
4005       ForceMyIconClosed(host_name, directory_name);
4006
4007    XtFree(directory_name);
4008    XtFree(host_name);
4009 }
4010
4011
4012
4013
4014 /************************************************************************
4015  *
4016  *  DirectoryChanged
4017  *      This function is called when a view may be changing its
4018  *      current directory.  It updates the view_set list to the
4019  *      new host and directory.
4020  *
4021  ************************************************************************/
4022
4023 void
4024 DirectoryChanged(
4025         XtPointer file_mgr_data,
4026         char *old_host_name,
4027         char *new_host_name,
4028         char *old_directory_name,
4029         char *new_directory_name )
4030 {
4031    int i;
4032
4033
4034    /*  See if the directory is one being viewed  */
4035
4036    for (i = 0; i < view_count; i++)
4037    {
4038       if (((DialogData *) (view_set[i]->dialog_data))->data == file_mgr_data)
4039       {
4040          if (strcmp (old_host_name, view_set[i]->host_name) == 0              &&
4041              strcmp (old_directory_name, view_set[i]->directory_name) == 0)
4042          {
4043             XtFree ((char *) view_set[i]->host_name);
4044             view_set[i]->host_name = XtNewString (new_host_name);
4045
4046             XtFree ((char *) view_set[i]->directory_name);
4047             view_set[i]->directory_name = XtNewString (new_directory_name);
4048          }
4049       }
4050    }
4051
4052
4053    /*  Update the directory cache list to remove unneeded directories.  */
4054
4055    UpdateCachedDirectories (view_set, view_count);
4056 }
4057
4058
4059
4060 /************************************************************************
4061  *
4062  *  ObserveTtNotice
4063  *      Dispatch ToolTalk events to internal handlers.
4064  *
4065  ************************************************************************/
4066
4067 static Tt_callback_action
4068 ObserveTtNotice(
4069         Tt_message msg,
4070         Tt_pattern pat
4071 )
4072 {
4073    char *op;
4074    Tt_status status;
4075
4076    op = tt_message_op( msg );
4077    status = tt_ptr_error( op );
4078    if ((status != TT_OK) || (op == 0)) {
4079       /* Let tttk_Xt_input_handler() Do The Right Thing */
4080       return TT_CALLBACK_CONTINUE;
4081    }
4082    if (strcmp( op, "DtTypes_Reloaded" ) == 0) {
4083       ReloadDatabases();
4084    } else if (strcmp( op, "XSession_Ending" ) == 0) {
4085       if( emptyTrashOnExit )
4086          TrashEmpty();
4087    } else {
4088       tt_free( op );
4089       return TT_CALLBACK_CONTINUE;
4090    }
4091    tt_free( op );
4092    tttk_message_destroy( msg );
4093    return TT_CALLBACK_PROCESSED;
4094 }
4095
4096 /************************************************************************
4097  *
4098  *  HandleTtRequest
4099  *      Dispatch ToolTalk requests to internal handlers.
4100  *
4101  ************************************************************************/
4102
4103 Tt_callback_action
4104 HandleTtRequest(
4105         Tt_message msg,
4106         Tt_pattern pat
4107 )
4108 {
4109         char *op;
4110         Tt_status status;
4111
4112         op = tt_message_op( msg );
4113         status = tt_ptr_error( op );
4114         if ((status != TT_OK) || (op == 0)) {
4115                 /* Let tttk_Xt_input_handler() Do The Right Thing */
4116                 return TT_CALLBACK_CONTINUE;
4117         }
4118         if (strcmp( op, "DtFileSession_Run" ) == 0) {
4119                 ViewSessionHandler( msg );
4120         } else if (strcmp( op, "DtFolder_Show" ) == 0) {
4121                 ViewDirectoryHandler( msg );
4122         } else if (strcmp( op, "DtHome_Show" ) == 0) {
4123                 ViewHomeDirectoryHandler( msg );
4124         } else if (strcmp( op, "DtTools_Show" ) == 0) {
4125                 ViewToolsDirectoryHandler( msg );
4126         } else if (strcmp( op, "DtTrash_Show" ) == 0) {
4127                 TrashDisplayHandler( msg );
4128         } else if (strcmp( op, "DtTrash_Remove" ) == 0) {
4129                 TrashRemoveHandler( msg );
4130         } else if (strcmp( op, "DtTrash_Empty" ) == 0) {
4131                 TrashEmptyHandler( msg );
4132         } else if (strcmp( op, "DtTrash_File" ) == 0) {
4133                 TrashRemoveNoConfirmHandler( msg );
4134     } else if (strcmp( op, "DtTrash_Restore" ) == 0) {
4135          TrashRestoreHandler( msg );
4136     } else if (strcmp( op, "DtFile_PutOnWorkspace" ) == 0) {
4137          PutOnWorkspaceHandler( msg );
4138     } else if (strcmp( op, "DtFile_Move" ) == 0) {
4139          MoveCopyLinkHandler( msg, MOVE_FILE );
4140     } else if (strcmp( op, "DtFile_Copy" ) == 0) {
4141          MoveCopyLinkHandler( msg, COPY_FILE );
4142     } else if (strcmp( op, "DtFile_Link" ) == 0) {
4143          MoveCopyLinkHandler( msg, LINK_FILE );
4144     } else {
4145          tt_free( op );
4146          return TT_CALLBACK_CONTINUE;
4147     }
4148     tt_free( op );
4149     return TT_CALLBACK_PROCESSED;
4150 }
4151
4152
4153
4154
4155 /************************************************************************
4156  *
4157  *  ViewSessionHandler
4158  *      This function is called upon the dt session  message
4159  *      being received.  The name of the session file is extracted
4160  *      out of the message and a function is called to create
4161  *      a view or set of views described by the file.
4162  *
4163  ************************************************************************/
4164
4165 static void
4166 ViewSessionHandler(
4167    Tt_message msg)
4168 {
4169    char *file = tt_message_file( msg );
4170    tt_message_reply( msg );
4171    tttk_message_destroy( msg );
4172
4173    if (! tt_is_err( tt_ptr_error( file )))
4174    {
4175       if (view_count == 0 && desktop_data->numIconsUsed == 0)
4176       {
4177            int session_flag = 0;
4178            char *session_name;
4179
4180            session_name = strrchr(file, '/');
4181            session_name++;
4182            LoadDesktopInfo(session_name);
4183            session_flag = RestoreSession (session_name, NORMAL_RESTORE, NULL);
4184            if ((session_flag != 0) && (view_count == 0))
4185            {
4186               char current_directory[MAX_PATH];
4187
4188               GetPWD(current_directory);
4189               if (current_directory[0] != '\0')
4190               {
4191                  if (!GetNewView
4192                       (home_host_name, current_directory, NULL, NULL, 0))
4193                     ViewHomeDirectoryHandler (0);
4194               }
4195               else
4196               {
4197                  ViewHomeDirectoryHandler (0);
4198               }
4199            }
4200       }
4201       else
4202       {
4203            char *tmpStr, *msg, *title;
4204
4205            tmpStr = GETMESSAGE(18, 39, "Cannot start a second File Manager session because a File Manager\nsession is already open on the desktop.  If you want to start a new File\nManager session, you must first close all current File Manager windows\nand remove all File Manager objects from the workspaces.");
4206            msg = XtNewString(tmpStr);
4207            title = XtNewString((GETMESSAGE(18,40,"Session Error")));
4208            _DtMessage (toplevel, title, msg, NULL, HelpRequestCB);
4209            XtFree(msg);
4210            XtFree(title);
4211       }
4212    }
4213    tt_free( file );
4214 }
4215
4216
4217
4218
4219 /************************************************************************
4220  *
4221  *  ViewDirectoryHandler
4222  *      This function is called upon the dt directory message
4223  *      being received.  The name of the directory is extracted
4224  *      out of the message and a function is called to create
4225  *      a view of the directory.
4226  *
4227  ************************************************************************/
4228
4229 static void
4230 ViewDirectoryHandler(
4231    Tt_message msg)
4232 {
4233    int i, j, k;
4234    char *msgFile;
4235    int numArgs;
4236
4237    initiating_view = NULL;
4238    msgFile = tt_message_file( msg );
4239    if (tt_is_err( tt_ptr_error( msgFile ))) msgFile = 0;
4240
4241    if(restrictMode)
4242    {
4243       if(msgFile && strncmp(msgFile, "~", 1) != 0 )
4244       {
4245          if((strcmp(users_home_dir, "/") != 0) &&
4246             (strncmp(msgFile, users_home_dir, strlen(users_home_dir)-1) != 0))
4247          {
4248             char *tmpStr, *errTitle, *errMsg, *dmsg;
4249
4250             tmpStr = GETMESSAGE(32, 2, "File Manager Open Directory Error");
4251             errTitle = XtNewString(tmpStr);
4252             tmpStr = GETMESSAGE(2,20,"You cannot switch to folder:\n\n%s\n\nYou are not allowed to view this folder\nbecause it is a restricted folder.");
4253             errMsg = XtNewString(tmpStr);
4254             dmsg = XtMalloc(strlen(errMsg)+strlen(msgFile)+1);
4255             sprintf(dmsg, errMsg, msgFile);
4256             _DtMessage(toplevel, errTitle, dmsg, NULL, HelpRequestCB);
4257
4258             XtFree(errTitle);
4259             XtFree(errMsg);
4260             XtFree(dmsg);
4261
4262             tt_free( msgFile );
4263             tt_message_reply( msg );
4264             tttk_message_destroy( msg );
4265             return;
4266          }
4267       }
4268    }
4269
4270    numArgs = tt_message_args_count( msg );
4271    if (tt_is_err( tt_int_error( numArgs ))) numArgs = 0;
4272    if (numArgs > 0)
4273    {
4274       special_view = True;
4275       special_treeType = UNSET_VALUE;
4276       special_treeFiles = UNSET_VALUE;
4277       special_viewType = UNSET_VALUE;
4278       special_orderType = UNSET_VALUE;
4279       special_directionType = UNSET_VALUE;
4280       special_randomType = UNSET_VALUE;
4281       special_restricted = NULL;
4282       special_title = NULL;
4283       special_helpVol = XtNewString(DTFILE_HELP_NAME);
4284       for(i = 0; i < numArgs; i++)
4285       {
4286          char *vtype;
4287          char *val;
4288          vtype = tt_message_arg_type( msg, i );
4289          if ((vtype == 0) || (tt_is_err( tt_ptr_error( vtype )))) {
4290             continue;
4291          }
4292          val = tt_message_arg_val( msg, i );
4293          if(strcmp(vtype, "-title") == 0)
4294          {
4295             special_title = XtNewString(val);
4296          }
4297          else if(strcmp(vtype, "-help_volume") == 0)
4298          {
4299             special_helpVol = XtNewString(val);
4300          }
4301          if(strcmp(vtype, "-tree") == 0)
4302          {
4303             DtfileStringToTree(val, &special_treeType);
4304          }
4305          else if(strcmp(vtype, "-tree_files") == 0)
4306          {
4307             DtfileStringToTreeFiles(val, &special_treeFiles);
4308          }
4309          else if(strcmp(vtype, VIEW_HEADER) == 0)
4310          {
4311             DtfileStringToView(val, &special_viewType);
4312          }
4313          else if(strcmp(vtype, "-order") == 0)
4314          {
4315             DtfileStringToOrder(val, &special_orderType);
4316          }
4317          else if(strcmp(vtype, "-direction") == 0)
4318          {
4319             DtfileStringToDirection(val, &special_directionType);
4320          }
4321          else if(strcmp(vtype, "-grid") == 0)
4322          {
4323             DtfileStringToGrid(val, &special_randomType);
4324          }
4325          else if(strcmp(vtype, RESTRICTED_HEADER) == 0)
4326          {
4327             special_restricted = XtNewString(msgFile);
4328          }
4329          tt_free( val );
4330          tt_free( vtype );
4331
4332          if ((restrictMode) && (!special_restricted))
4333          {
4334             char *ptr;
4335
4336             ptr = strrchr(users_home_dir, '/');
4337             *ptr = '\0';
4338             special_restricted = XtNewString(users_home_dir);
4339             *ptr = '/';
4340          }
4341       }
4342    }
4343    else if (restrictMode)
4344    {
4345      char *ptr;
4346
4347      special_view = True;
4348      special_treeType = treeType;
4349      special_treeFiles = treeFiles;
4350      special_viewType = viewType;
4351      special_orderType = orderType;
4352      special_directionType = directionType;
4353      special_randomType = randomType;
4354
4355      ptr = strrchr(users_home_dir, '/');
4356      *ptr = '\0';
4357      special_restricted = XtNewString(users_home_dir);
4358      *ptr = '/';
4359
4360      special_title = NULL;
4361      special_helpVol = XtNewString(DTFILE_HELP_NAME);
4362
4363    }
4364    else
4365       special_view = False;
4366
4367    OpenDirectories (msgFile, NULL);
4368
4369    tt_free( msgFile );
4370    tt_message_reply( msg );
4371    tttk_message_destroy( msg );
4372 }
4373
4374
4375
4376
4377 /************************************************************************
4378  *
4379  *  ViewDirectoryProc
4380  *      This function is called upon the dt directory message
4381  *      being received.  The name of the directory is extracted
4382  *      out of the message and a function is called to create
4383  *      a view of the directory.  This function is passed directly
4384  *      to DtActionInvoke to be used as a callback.
4385  *
4386  ************************************************************************/
4387
4388 DialogData *
4389 ViewDirectoryProc(
4390    char* root_dir,
4391    int restricted,
4392    Tt_message msg
4393 )
4394 {
4395    DialogData *return_data;
4396
4397    if(restrictMode)
4398    {
4399       if(root_dir && strncmp(root_dir, "~", 1) != 0 )
4400       {
4401          if((strcmp(users_home_dir, "/") != 0) &&
4402             (strncmp(root_dir, users_home_dir, strlen(users_home_dir)-1) != 0))
4403          {
4404             char *tmpStr, *errTitle, *errMsg, *dmsg;
4405
4406             tmpStr = GETMESSAGE(32, 2, "File Manager Open Directory Error");
4407             errTitle = XtNewString(tmpStr);
4408             tmpStr = GETMESSAGE(2,20,"You cannot switch to folder:\n\n%s\n\nYou are not allowed to view this folder\nbecause it is a restricted folder.");
4409             errMsg = XtNewString(tmpStr);
4410             dmsg = XtMalloc(strlen(errMsg)+strlen(root_dir)+1);
4411             sprintf(dmsg, errMsg, root_dir);
4412             _DtMessage(toplevel, errTitle, dmsg, NULL, HelpRequestCB);
4413
4414             XtFree(errTitle);
4415             XtFree(errMsg);
4416             XtFree(dmsg);
4417             return NULL;
4418          }
4419       }
4420    }
4421
4422    initiating_view = NULL;
4423    special_view = True;
4424    special_treeType = treeType;
4425    special_treeFiles = treeFiles;
4426    special_viewType = viewType;
4427    special_orderType = orderType;
4428    special_directionType = directionType;
4429    special_randomType = randomType;
4430
4431    if (restricted) {
4432      special_restricted = XtNewString(root_dir);
4433    }
4434    else {
4435      special_restricted = NULL;
4436    }
4437
4438    if ((restrictMode) && (!special_restricted))
4439    {
4440       char *ptr;
4441
4442       ptr = strrchr(users_home_dir, '/');
4443       *ptr = '\0';
4444       special_restricted = XtNewString(users_home_dir);
4445       *ptr = '/';
4446    }
4447
4448    special_title = NULL;
4449    special_helpVol = XtNewString(DTFILE_HELP_NAME);
4450
4451    return_data = GetNewView (home_host_name, root_dir, NULL, NULL, msg);
4452
4453    if ((!return_data) && msg)
4454    {
4455       tt_message_reply(msg);
4456       tttk_message_destroy( msg );
4457    }
4458
4459    return(return_data);
4460 }
4461
4462
4463
4464 /************************************************************************
4465  *
4466  *  ViewHomeDirectoryHandler
4467  *      This function is called upon the dt home directory message
4468  *      being received.  The home directory is extracted from the
4469  *      users uid and used to open the directory.
4470  *
4471  ************************************************************************/
4472
4473
4474 static void
4475 ViewHomeDirectoryHandler(
4476    Tt_message msg)
4477 {
4478    register int i, j, k;
4479    struct passwd * pwInfo;
4480    char * homeDir;
4481    char * tmp_path;
4482    char full_path[MAX_PATH + 1];
4483    struct stat stat_buf;
4484    int numArgs;
4485
4486    /* We have a new view so set initiating_view to null */
4487    initiating_view = NULL;
4488
4489    if ((homeDir = getenv("HOME")) == NULL || strlen (homeDir) == 0)
4490    {
4491       pwInfo = getpwuid (getuid());
4492       homeDir = pwInfo->pw_dir;
4493    }
4494
4495    /* Look and see if we have a default environment file present */
4496    tmp_path = _DtCreateDtDirs(display);
4497
4498    numArgs = 0;
4499    if (msg) numArgs = tt_message_args_count(msg);
4500    if (tt_is_err(tt_int_error(numArgs))) numArgs = 0;
4501    if (numArgs > 0)
4502    {
4503       special_view = True;
4504       special_treeType = UNSET_VALUE;
4505       special_treeFiles = UNSET_VALUE;
4506       special_viewType = UNSET_VALUE;
4507       special_orderType = UNSET_VALUE;
4508       special_directionType = UNSET_VALUE;
4509       special_randomType = UNSET_VALUE;
4510       special_restricted = NULL;
4511       special_title = NULL;
4512       special_helpVol = XtNewString(DTFILE_HELP_NAME);
4513       for(i = 0; i < numArgs; i++)
4514       {
4515          char *vtype;
4516          char *val;
4517          vtype = tt_message_arg_type( msg, i );
4518          if ((vtype == 0) || (tt_is_err( tt_ptr_error( vtype )))) {
4519             continue;
4520          }
4521          val = tt_message_arg_val(msg, i);
4522          if(strcmp(vtype, "-title") == 0)
4523          {
4524             special_title = XtNewString(val);
4525          }
4526          else if(strcmp(vtype, "-help_volume") == 0)
4527          {
4528             special_helpVol = XtNewString(val);
4529          }
4530          if(strcmp(vtype, "-tree") == 0)
4531          {
4532             DtfileStringToTree(val, &special_treeType);
4533          }
4534          else if(strcmp(vtype, "-tree_files") == 0)
4535          {
4536             DtfileStringToTreeFiles(val, &special_treeFiles);
4537          }
4538          else if(strcmp(vtype, VIEW_HEADER) == 0)
4539          {
4540             DtfileStringToView(val, &special_viewType);
4541          }
4542          else if(strcmp(vtype, "-order") == 0)
4543          {
4544             DtfileStringToOrder(val, &special_orderType);
4545          }
4546          else if(strcmp(vtype, "-direction") == 0)
4547          {
4548             DtfileStringToDirection(val, &special_directionType);
4549          }
4550          else if(strcmp(vtype, "-grid") == 0)
4551          {
4552             DtfileStringToGrid(val, &special_randomType);
4553          }
4554          else if(strcmp(vtype, RESTRICTED_HEADER) == 0)
4555          {
4556             special_restricted = XtNewString(val);
4557          }
4558          tt_free( val );
4559          tt_free( vtype );
4560       }
4561    }
4562    else if (restrictMode)
4563    {
4564      char *ptr;
4565
4566      special_view = True;
4567      special_treeType = treeType;
4568      special_treeFiles = treeFiles;
4569      special_viewType = viewType;
4570      special_orderType = orderType;
4571      special_directionType = directionType;
4572      special_randomType = randomType;
4573
4574      ptr = strrchr(users_home_dir, '/');
4575      *ptr = '\0';
4576      special_restricted = XtNewString(users_home_dir);
4577      *ptr = '/';
4578
4579      special_title = NULL;
4580      special_helpVol = XtNewString(DTFILE_HELP_NAME);
4581    }
4582    else
4583       special_view = False;
4584
4585    if (tmp_path == NULL)
4586       OpenDirectories (homeDir, NULL);
4587    else
4588    {
4589      sprintf(full_path, "%s/%s", tmp_path, HOME_SETTINGS_FILENAME);
4590      XtFree(tmp_path);
4591
4592      /* Stat the file and make sure its there */
4593      if(numArgs > 0)
4594      {
4595         if (stat (full_path, &stat_buf) == 0 && numArgs < 1)
4596         {
4597            restoreType = HOME_RESTORE;
4598            RestoreSession(full_path, HOME_RESTORE, NULL);
4599            restoreType = NORMAL_RESTORE;
4600         }
4601         else
4602         {
4603            char *ptr;
4604
4605            ptr = strrchr(users_home_dir, '/');
4606            *ptr = '\0';
4607            strcpy(full_path, users_home_dir);
4608            *ptr = '/';
4609            OpenDirectories (full_path, NULL);
4610         }
4611      }
4612      else if (numArgs < 1 && stat (full_path, &stat_buf) == 0)
4613      {
4614         restoreType = HOME_RESTORE;
4615         RestoreSession(full_path, HOME_RESTORE, NULL);
4616         restoreType = NORMAL_RESTORE;
4617      }
4618      else
4619      {
4620        char *ptr;
4621
4622        ptr = strrchr(users_home_dir, '/');
4623
4624        if( ptr != users_home_dir )
4625          *ptr = '\0';
4626
4627        strcpy(full_path, users_home_dir);
4628        *ptr = '/';
4629
4630        OpenDirectories (full_path, NULL);
4631      }
4632    }
4633
4634    if(msg)
4635    {
4636      tt_message_reply(msg);
4637      tttk_message_destroy(msg);
4638    }
4639 }
4640
4641 /************************************************************************
4642  *
4643  *  ViewToolsDirectroyHandler
4644  *      This function is called upon the dt tools message
4645  *      being received.  The names of the tools directories are
4646  *      retrieved from libXue, a view is created and the change
4647  *      directory dialog for the view is displayed with the
4648  *      set of directories contained in the list.
4649  *
4650  ************************************************************************/
4651
4652 static void
4653 ViewToolsDirectoryHandler(
4654    Tt_message msg)
4655 {
4656    register int i;
4657    char * tmp_path = NULL;
4658    char * tool_dir = NULL;
4659    char * msgFile = NULL;
4660    int numArgs = 0;
4661
4662    /* We have a new view so set initiating_view to null */
4663    initiating_view = NULL;
4664
4665    /* Look and see if we have a default environment file present */
4666    tmp_path = _DtCreateDtDirs(display);
4667
4668    if (msg) msgFile = tt_message_file(msg);
4669    if (tt_is_err(tt_ptr_error(msgFile))) msgFile = 0;
4670
4671    if (msg) numArgs = tt_message_args_count(msg);
4672    if (tt_is_err(tt_int_error( numArgs ))) numArgs = 0;
4673
4674    if(msgFile != NULL)
4675    {
4676       if(numArgs > 0)
4677       {
4678          char *link_point = NULL;
4679          char *root_toolbox = NULL;
4680          char *user_install_point = NULL;
4681
4682          special_view = True;
4683          special_treeType = treeType;
4684          special_treeFiles = treeFiles;
4685          special_viewType = viewType;
4686          special_orderType = orderType;
4687          special_directionType = directionType;
4688          special_randomType = randomType;
4689          special_restricted = XtNewString(msgFile);
4690          special_title = NULL;
4691          special_helpVol = XtNewString(DTFILE_HELP_NAME);
4692          for(i = 0; i < numArgs; i++)
4693          {
4694             char *vtype;
4695             char *val;
4696             vtype = tt_message_arg_type( msg, i );
4697             if ((vtype == 0) || (tt_is_err( tt_ptr_error( vtype )))) {
4698                continue;
4699             }
4700             val = tt_message_arg_val( msg, i );
4701             if(strcmp(vtype, "-title") == 0)
4702             {
4703                special_title = XtNewString(val);
4704             }
4705             else if(strcmp(vtype, "-help_volume") == 0)
4706             {
4707                special_helpVol = XtNewString(val);
4708             }
4709             else if(strcmp(vtype, "-root") == 0)
4710             {
4711                root_toolbox = XtNewString(val);
4712             }
4713             else if(strcmp(vtype, "-common_link_point") == 0)
4714             {
4715                link_point = XtNewString(val);
4716             }
4717             else if(strcmp(vtype, "-user_install_point") == 0)
4718             {
4719                user_install_point = XtNewString(val);
4720             }
4721             if(strcmp(vtype, "-tree") == 0)
4722             {
4723                DtfileStringToTree(val, &special_treeType);
4724             }
4725             else if(strcmp(vtype, "-tree_files") == 0)
4726             {
4727                DtfileStringToTreeFiles(val, &special_treeFiles);
4728             }
4729             else if(strcmp(vtype, VIEW_HEADER) == 0)
4730             {
4731                DtfileStringToView(val, &special_viewType);
4732             }
4733             else if(strcmp(vtype, "-order") == 0)
4734             {
4735                DtfileStringToOrder(val, &special_orderType);
4736             }
4737             else if(strcmp(vtype, "-direction") == 0)
4738             {
4739                DtfileStringToDirection(val, &special_directionType);
4740             }
4741             else if(strcmp(vtype, "-grid") == 0)
4742             {
4743                DtfileStringToGrid(val, &special_randomType);
4744             }
4745             else if(strcmp(vtype, RESTRICTED_HEADER) == 0)
4746             {
4747                ;
4748             }
4749             tt_free( val );
4750             tt_free( vtype );
4751          }
4752          /* Due to the use of tooltalk messaging, app manager objects
4753             that are dragged either to the desktop or to the front
4754             panel are identified by their fully resolved names (ie.
4755             /usr/dt/appconfig/appmanager/$LANG/.... as opposed to
4756             /var/dt/appconfig/appmanager/$DTUSERSESSION/....).  In order
4757             for the File Manager to treat these objects as links existing
4758             in the /var/.... directory, we use the following ugly code:
4759
4760               1. Search the incoming path for $LANG (if you can't find
4761                  $LANG, try C since this is the default).
4762               2. Concatenate the path following $LANG to the path for the
4763                  root toolbox (this comes in with the tooltalk message
4764                  so that we don't have to hardcode it).
4765               3. Call OpenDirectories with the new path that you have
4766                  created and with the root toolbox path as the restricted
4767                  directory.
4768
4769             This problem is further complicated by:
4770               1. Users traversing into APPGROUPs.
4771               2. Users opening the parent folders for workspace APPGROUPs.
4772
4773             For situation 1, File Manager kicks the user into the App Manager
4774             if he/she traverses into an APPGROUP.  BUT we don't want to
4775             make modifications to the path as we do above.
4776             So, if there is nothing following $LANG or if we can't find
4777             $LANG in the path,
4778             (ie. /var/dt/appconfig/appmanager/$DTUSERSESSION), call
4779             OpenDirectories with no parameter changes.
4780
4781             For situation 2, File Manager is unable to distinguish between
4782             workspace objects dragged from /usr/.... or /var/...., so
4783             the parent folder for all workspace APPGROUPS is considered to
4784             be in the /var path.  In addition to the OpenAppGroup action,
4785             there is an OpenParentAppGroup action which also triggers
4786             ViewToolsDirectoryHandler but sends in an additional
4787             parameter (user_install_point).
4788             If we know that this msg was generated by the OpenParentAppGroup
4789             action
4790             AND nothing follows $LANG.
4791               Modify the parameters as above.
4792             OR we can't find $LANG but we can find the user_install_point
4793               (user's personal appgroup path).
4794               Concatenate the path following .dt/appmanager to the path for the
4795               root toolbox. Call OpenDirectories with the new path and the
4796               root toolbox as the restricted directory.
4797          */
4798          if( root_toolbox )
4799          {
4800             if( link_point )
4801             {
4802                char *ptr;
4803
4804                if ((user_install_point) &&
4805                    (ptr = strstr(msgFile, user_install_point)))
4806                {
4807                   ptr += strlen(user_install_point);
4808                   tool_dir = XtMalloc(strlen(root_toolbox) + strlen(ptr) + 1);
4809                   sprintf(tool_dir, "%s%s", root_toolbox, ptr);
4810                   XtFree(special_restricted);
4811                   special_restricted = XtNewString(root_toolbox);
4812                }
4813                else
4814                {
4815                   ptr = strstr(msgFile, link_point);
4816
4817                   if (!ptr)
4818                   {
4819                      XtFree(link_point);
4820                      link_point = XtNewString("C");
4821                      ptr = strstr(msgFile, link_point);
4822                   }
4823
4824                   if (ptr)
4825                   {
4826                      ptr += strlen(link_point);
4827                      if (strcmp(ptr, "") != 0)
4828                      {
4829                         tool_dir = XtMalloc(strlen(root_toolbox) +
4830                                             strlen(ptr) + 1);
4831                         sprintf(tool_dir, "%s%s", root_toolbox, ptr);
4832                         XtFree(special_restricted);
4833                         special_restricted = XtNewString(root_toolbox);
4834                      }
4835                      else if (user_install_point)
4836                      {
4837                         tool_dir = XtNewString(root_toolbox);
4838                         XtFree(special_restricted);
4839                         special_restricted = XtNewString(root_toolbox);
4840                      }
4841                   }
4842                }
4843             }
4844          }
4845          XtFree(link_point);
4846          XtFree(root_toolbox);
4847          XtFree(user_install_point);
4848       }
4849       else if (restrictMode)
4850       {
4851          char *ptr;
4852
4853          special_view = True;
4854          ptr = strrchr(users_home_dir, '/');
4855          *ptr = '\0';
4856          special_restricted = XtNewString(users_home_dir);
4857          *ptr = '/';
4858       }
4859       else
4860          special_view = False;
4861    }
4862
4863    if (tmp_path == NULL)
4864    {
4865       if (tool_dir)
4866          OpenDirectories (tool_dir, special_restricted);
4867       else if (msgFile != NULL)
4868          OpenDirectories (msgFile, special_restricted);
4869    }
4870    else
4871    {
4872       char full_path[MAX_PATH + 1];
4873       struct stat stat_buf;
4874
4875       sprintf(full_path, "%s/%s", tmp_path, TOOL_SETTINGS_FILENAME);
4876       XtFree(tmp_path);
4877
4878       /* Stat the file and make sure its there */
4879       if (stat (full_path, &stat_buf) == 0 && numArgs > 0)
4880       {
4881          DialogData * dialog_data;
4882          FileMgrData * file_mgr_data;
4883
4884          restoreType = TOOL_RESTORE;
4885          if (tool_dir)
4886             RestoreSession(full_path, TOOL_RESTORE, tool_dir);
4887          else
4888             RestoreSession(full_path, TOOL_RESTORE, msgFile);
4889          dialog_data = (DialogData *)view_set[view_count - 1]->dialog_data;
4890          file_mgr_data = (FileMgrData *) dialog_data->data;
4891          application_args.tool_width = file_mgr_data->width;
4892          application_args.tool_height = file_mgr_data->height;
4893          restoreType = NORMAL_RESTORE;
4894       }
4895       else
4896       {
4897          if (tool_dir)
4898             OpenDirectories (tool_dir, special_restricted);
4899          else if (msgFile != NULL)
4900             OpenDirectories (msgFile, special_restricted);
4901       }
4902    }
4903
4904    if( msgFile )
4905      tt_free( msgFile );
4906
4907    if( msg )
4908    {
4909      tt_message_reply( msg );
4910      tttk_message_destroy( msg );
4911    }
4912
4913    if (tool_dir)
4914       XtFree(tool_dir);
4915 }
4916
4917
4918 /************************************************************************
4919  *
4920  *  ExitHandler
4921  *      This function is called upon the DtSTOP message.
4922  *
4923  ************************************************************************/
4924
4925 static void
4926 ExitHandler(
4927    Tt_message msg,
4928    XtPointer clientData,
4929    String * messageFields,
4930    int numFields)
4931 {
4932    tt_message_reply( msg );
4933    tttk_message_destroy( msg );
4934    FinalizeToolTalkSession( );
4935    exit(0);
4936 }
4937
4938
4939 /*
4940  * This is the message handling function responsible for reloading
4941  * the filetype and action databases, and then updating our collection
4942  * of action menu items, and updating all open views.
4943  */
4944
4945 static void
4946 ReloadDatabases(void)
4947 {
4948    int i;
4949    DialogData * dialog_data;
4950    FileMgrData * file_mgr_data;
4951    FileMgrRec  * file_mgr_rec;
4952    FileViewData *file_view_data;
4953    DesktopRec *desktopWindow;
4954
4955    DtDbLoad();
4956
4957    XmeFlushIconFileCache ( NULL );
4958
4959    /* Update each directory_set view, both mapped and not */
4960    UpdateDirectorySet();
4961
4962    /* Force action menus to update the next time they're posted */
4963    XtFree(fileMgrPopup.action_pane_file_type);
4964    fileMgrPopup.action_pane_file_type = NULL;
4965    XtFree(desktop_data->popupMenu->action_pane_file_type);
4966    desktop_data->popupMenu->action_pane_file_type = NULL;
4967
4968    /* Update each view */
4969    for (i = 0; i < view_count; i++)
4970    {
4971       dialog_data = (DialogData *)view_set[i]->dialog_data;
4972       file_mgr_data = (FileMgrData *) dialog_data->data;
4973       file_mgr_rec = (FileMgrRec *) file_mgr_data->file_mgr_rec;
4974       XtFree(file_mgr_rec->action_pane_file_type);
4975       file_mgr_rec->action_pane_file_type = NULL;
4976       UpdateFilterAfterDBReread(file_mgr_data->filter_active);
4977       UpdateFilterAfterDBReread(file_mgr_data->filter_edit);
4978       FileMgrRedisplayFiles(file_mgr_rec, file_mgr_data, False);
4979    }
4980
4981    /* go through the desktop objects to make sure the icons change
4982     * Do this by setting the logical_type to -l, CheckDesktop will
4983     * then update the logical type and the icon
4984     */
4985    for(i = 0; i < desktop_data->numIconsUsed; i++)
4986    {
4987       desktopWindow = desktop_data->desktopWindows[i];
4988       file_view_data = desktopWindow->file_view_data;
4989
4990       file_view_data->file_data->logical_type = NULL;
4991    }
4992    CheckDesktop();
4993 }
4994
4995
4996 /*
4997  * Whenever a directory view or drawer view is closed, we need to remove
4998  * any of its text field children, so that they will not magically reappear
4999  * should this view be reused from the cache to view the same directory later.
5000  */
5001
5002 static void
5003 RemoveTextFields (
5004    XtPointer client_data,
5005    DialogData * old_dialog_data,
5006    DialogData * new_dialog_data)
5007 {
5008    FileMgrRec * file_mgr_rec;
5009    XmManagerWidget file_window;
5010    int i;
5011    int num_children;
5012
5013    file_mgr_rec = (FileMgrRec *) _DtGetDialogInstance(old_dialog_data);
5014    file_window = (XmManagerWidget) file_mgr_rec->file_window;
5015    num_children = file_window->composite.num_children;
5016
5017    for (i = 0; i < num_children; i++)
5018    {
5019       if (XmIsTextField(file_window->composite.children[i]))
5020          XtDestroyWidget(file_window->composite.children[i]);
5021    }
5022
5023    _DtFreeDialogData (new_dialog_data);
5024 }
5025
5026
5027 /*
5028  * This function searches the view list, and returns the file_mgr_data
5029  * associated with the passed-in widget.
5030  */
5031
5032 FileMgrData *
5033 ReturnDesktopPtr (
5034    Widget w)
5035 {
5036    int i;
5037    DialogData * dialog_data;
5038    FileMgrData * file_mgr_data;
5039
5040    for (i = 0; i < view_count; i++)
5041    {
5042       dialog_data = (DialogData *) view_set[i]->dialog_data;
5043       file_mgr_data = (FileMgrData *) dialog_data->data;
5044
5045       if (w == ((FileMgrRec *)file_mgr_data->file_mgr_rec)->file_window ||
5046           w == ((FileMgrRec *)file_mgr_data->file_mgr_rec)->shell)
5047          return(file_mgr_data);
5048    }
5049
5050    return(NULL);
5051 }
5052
5053
5054 PixmapData *
5055 CheckForOpenDirectory(
5056      FileViewData *order_list,
5057      DirectorySet *directory_set,
5058      FileMgrData *file_mgr_data,
5059      char * logical_type)
5060 {
5061    int i;
5062    char *ptr;
5063    char *file_type_name, *new_file_type_name;
5064    char directory_name[MAX_PATH];
5065    char * real_dir_name;
5066    FileMgrRec *file_mgr_rec;
5067    int icon_size;
5068    PixmapData *pixmapData = NULL;
5069
5070    if (file_mgr_data->view == BY_NAME_AND_ICON)
5071      icon_size = LARGE;
5072    else
5073      icon_size = SMALL;
5074
5075    file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
5076
5077    if (strcmp (directory_set->name, "/") != 0)
5078      sprintf( directory_name, "%s/%s", directory_set->name, order_list->file_data->file_name);
5079    else
5080      sprintf( directory_name, "%s%s", directory_set->name, order_list->file_data->file_name );
5081
5082    (void) DtEliminateDots (directory_name);
5083
5084    real_dir_name = XtNewString(directory_name);
5085
5086    for(i = 0; i < view_count; i++)
5087    {
5088       if(strcmp(real_dir_name, view_set[i]->directory_name) == 0)
5089       {
5090          file_type_name = order_list->file_data->logical_type;
5091          new_file_type_name = (char *)XtMalloc(strlen(file_type_name)
5092                                                + strlen(ICON_OPEN_PREFIX) + 1);
5093          sprintf(new_file_type_name, "%s%s", ICON_OPEN_PREFIX, file_type_name);
5094          pixmapData = _DtRetrievePixmapData(new_file_type_name,
5095                                             NULL,
5096                                             NULL,
5097                                             file_mgr_rec->file_window,
5098                                             icon_size);
5099          XtFree(new_file_type_name);
5100          break;
5101       }
5102    }
5103    XtFree(real_dir_name);
5104
5105    if(pixmapData == NULL || pixmapData->iconFileName == NULL)
5106    {
5107      if( pixmapData != NULL )
5108      {
5109        DtDtsFreeAttributeValue(pixmapData->hostPrefix);
5110        DtDtsFreeAttributeValue(pixmapData->instanceIconName);
5111        DtDtsFreeAttributeValue(pixmapData->iconName);
5112        XtFree((char *)pixmapData);
5113      }
5114
5115        pixmapData = _DtRetrievePixmapData(logical_type,
5116                                           NULL,
5117                                           NULL,
5118                                           file_mgr_rec->file_window,
5119                                           icon_size);
5120    }
5121
5122    return(pixmapData);
5123 }
5124
5125
5126 /*
5127  * The is the menu callback function for cleaning up a view.
5128  */
5129
5130 void
5131 CleanUp (
5132    Widget w,
5133    XtPointer client_data,
5134    XtPointer call_data)
5135 {
5136    Widget mbar;
5137    Arg args[2];
5138    FileMgrRec * file_mgr_rec;
5139    DialogData * dialog_data;
5140    FileMgrData * file_mgr_data;
5141    int i, j;
5142    XmManagerWidget file_window;
5143    char * name;
5144    FileViewData * file_view_data;
5145    XRectangle textExtent;
5146    Position x, y;
5147
5148    if ((int)(XtArgVal) client_data == FM_POPUP)
5149      mbar = XtParent(w);
5150    else
5151      mbar = XmGetPostedFromWidget(XtParent(w));
5152
5153    XmUpdateDisplay(w);
5154    XtSetArg(args[0], XmNuserData, &file_mgr_rec);
5155    XtGetValues(mbar, args, 1);
5156
5157    /* Ignore accelerators when we're insensitive */
5158    if ((file_mgr_rec->menuStates & CLEAN_UP) == 0)
5159       return;
5160
5161    /* Ignore accelerators received after we're unposted */
5162    if ((dialog_data = _DtGetInstanceData((XtPointer)file_mgr_rec)) == NULL)
5163       return;
5164
5165    file_mgr_data = (FileMgrData *)dialog_data->data;
5166
5167    /* Reset the grid size, so it will be recalculated later. */
5168    file_mgr_data->grid_height = 0;
5169    file_mgr_data->grid_width = 0;
5170
5171    if(file_mgr_data->object_positions)
5172       FreePositionInfo(file_mgr_data);
5173
5174    /* CLEAN_UP_OP is not really a menu state.
5175       It's a flag to let GetFileData in FileMgr.c (call when the directory
5176       is being reread) not to reload icon positions from the .!dt<userid> file.
5177    */
5178    file_mgr_rec->menuStates |= CLEAN_UP_OP;
5179
5180    /* Re-layout the view */
5181    FileMgrRedisplayFiles(file_mgr_rec, file_mgr_data, False);
5182
5183    if ((file_mgr_data->show_type == SINGLE_DIRECTORY) &&
5184         (file_mgr_data->view != BY_ATTRIBUTES) &&
5185         (file_mgr_data->positionEnabled == RANDOM_ON))
5186    {
5187       ((PreferencesData *)(file_mgr_data->preferences->data))->positionEnabled =
5188           RANDOM_ON;
5189    }
5190    else
5191    {
5192       /* Update the preferences dialog */
5193       ((PreferencesData *)(file_mgr_data->preferences->data))->positionEnabled =
5194           RANDOM_OFF;
5195    }
5196
5197    /* Move any text widget, to keep them in sync with their icons */
5198    file_window = (XmManagerWidget)file_mgr_rec->file_window;
5199
5200    for (j = 0; j < file_window->composite.num_children; j++)
5201    {
5202       if (XmIsTextField(file_window->composite.children[j]) &&
5203           !file_window->composite.children[j]->core.being_destroyed)
5204       {
5205          XtSetArg(args[0], XmNuserData, &name);
5206          XtGetValues(file_window->composite.children[j], args, 1);
5207
5208          /* Find the associated icon data */
5209          /* @@@ this won't work for tree mode! */
5210          for (i = 0; i < file_mgr_data->directory_set[0]->file_count; i++)
5211          {
5212             file_view_data = file_mgr_data->directory_set[0]->file_view_data[i];
5213             if (strcmp(name, file_view_data->file_data->file_name) == 0)
5214             {
5215                _DtIconGetTextExtent_r(file_view_data->widget, &textExtent);
5216                x = textExtent.x;
5217                y = textExtent.y -
5218                    (Dimension)(file_window->composite.children[j]->core.height -
5219                     textExtent.height)/(Dimension)2;
5220                XtSetArg (args[0], XmNx, x);
5221                XtSetArg (args[1], XmNy, y);
5222                XtSetValues (file_window->composite.children[j], args, 2);
5223                break;
5224             }
5225          }
5226       }
5227    }
5228
5229    if ((file_mgr_rec->menuStates & CLEAN_UP_OP))
5230      file_mgr_rec->menuStates  &= ~CLEAN_UP_OP;
5231 }
5232
5233 /*************************************<->*************************************
5234  *
5235  *  DtfileCvtStringToObjPlace (args, numArgs, fromVal, toVal)
5236  *
5237  *
5238  *  Description:
5239  *  -----------
5240  *  This function converts a string to an desktop placement scheme description.
5241  *
5242  *
5243  *  Inputs:
5244  *  ------
5245  *  args = NULL (don't care)
5246  *
5247  *  numArgs = 0 (don't care)
5248  *
5249  *  fromVal = resource value to convert
5250  *
5251  *
5252  *  Outputs:
5253  *  -------
5254  *  toVal = descriptor to use to return converted value
5255  *
5256  *************************************<->***********************************/
5257
5258 static void
5259 DtfileCvtStringToObjPlace (
5260           XrmValue *args,
5261           Cardinal numArgs,
5262           XrmValue *fromVal,
5263           XrmValue *toVal)
5264 {
5265     unsigned char       *pch = (unsigned char *) (fromVal->addr);
5266     unsigned char       *pchNext;
5267     int         len;
5268     static long cval;
5269     char tmp[2];
5270     Boolean     fPrimarySet = False;
5271     Boolean     fSecondarySet = False;
5272
5273 /*
5274  * Icon placement layout values:
5275  */
5276
5277 #define OBJ_PLACE_BOTTOM_STR           (unsigned char *)"bottom"
5278 #define OBJ_PLACE_LEFT_STR             (unsigned char *)"left"
5279 #define OBJ_PLACE_RIGHT_STR            (unsigned char *)"right"
5280 #define OBJ_PLACE_TOP_STR              (unsigned char *)"top"
5281
5282
5283     /*
5284      * Convert the icon placement resource value:
5285      */
5286
5287     cval = 0;
5288
5289     while (*pch && _DtNextToken (pch, &len, &pchNext))
5290     {
5291         tmp[0] = pch[len];
5292         pch[len] = '\0';
5293         switch( *pch )
5294         {
5295             case 'B':
5296             case 'b':
5297                 if (_DtStringsAreEquivalent((char *)pch, (char *)OBJ_PLACE_BOTTOM_STR))
5298                 {
5299                   if (!fPrimarySet)
5300                   {
5301                     cval |= OBJ_PLACE_BOTTOM_PRIMARY;
5302                     fPrimarySet = True;
5303                   }
5304                   else if (!fSecondarySet)
5305                   {
5306                     if (!(cval &
5307                           (OBJ_PLACE_BOTTOM_PRIMARY | OBJ_PLACE_TOP_PRIMARY)))
5308                     {
5309                       cval |= OBJ_PLACE_BOTTOM_SECONDARY;
5310                       fSecondarySet = True;
5311                     }
5312                   }
5313                 }
5314                 break;
5315
5316
5317             case 'L':
5318             case 'l':
5319                 if (_DtStringsAreEquivalent ((char *)pch, (char *)OBJ_PLACE_LEFT_STR))
5320                 {
5321                   if (!fPrimarySet)
5322                   {
5323                     cval |= OBJ_PLACE_LEFT_PRIMARY;
5324                     fPrimarySet = True;
5325                   }
5326                   else if (!fSecondarySet)
5327                   {
5328                     if (!(cval &
5329                           (OBJ_PLACE_LEFT_PRIMARY | OBJ_PLACE_RIGHT_PRIMARY)))
5330                     {
5331                       cval |= OBJ_PLACE_LEFT_SECONDARY;
5332                       fSecondarySet = True;
5333                     }
5334                   }
5335                 }
5336                 break;
5337
5338             case 'R':
5339             case 'r':
5340                 if (_DtStringsAreEquivalent ((char *)pch, (char *)OBJ_PLACE_RIGHT_STR))
5341                 {
5342                   if (!fPrimarySet)
5343                   {
5344                     cval |= OBJ_PLACE_RIGHT_PRIMARY;
5345                     fPrimarySet = True;
5346                   }
5347                   else if (!fSecondarySet)
5348                   {
5349                     if (!(cval &
5350                           (OBJ_PLACE_RIGHT_PRIMARY | OBJ_PLACE_LEFT_PRIMARY)))
5351                     {
5352                       cval |= OBJ_PLACE_RIGHT_SECONDARY;
5353                       fSecondarySet = True;
5354                     }
5355                   }
5356                 }
5357                 break;
5358
5359             case 'T':
5360             case 't':
5361                 if (_DtStringsAreEquivalent ((char *)pch, (char *)OBJ_PLACE_TOP_STR))
5362                 {
5363                   if (!fPrimarySet)
5364                   {
5365                     cval |= OBJ_PLACE_TOP_PRIMARY;
5366                     fPrimarySet = True;
5367                   }
5368                   else if (!fSecondarySet)
5369                   {
5370                     if (!(cval &
5371                           (OBJ_PLACE_TOP_PRIMARY | OBJ_PLACE_BOTTOM_PRIMARY)))
5372                     {
5373                       cval |= OBJ_PLACE_TOP_SECONDARY;
5374                       fSecondarySet = True;
5375                     }
5376                   }
5377                 }
5378
5379                 break;
5380         }
5381         pch[len] = tmp[0];
5382         pch = pchNext;
5383     }
5384
5385     if (!fPrimarySet)
5386     {
5387         cval =  OBJ_PLACE_TOP_PRIMARY;
5388     }
5389     if (!fSecondarySet)
5390     {
5391         if (cval & (OBJ_PLACE_LEFT_PRIMARY | OBJ_PLACE_RIGHT_PRIMARY))
5392         {
5393             cval |= OBJ_PLACE_TOP_SECONDARY;
5394         }
5395         else        {
5396             cval |= OBJ_PLACE_RIGHT_SECONDARY;
5397         }
5398     }
5399
5400
5401     (*toVal).size = sizeof (long);
5402     (*toVal).addr = (XtPointer) &cval;
5403
5404 } /* END OF FUNCTION DtfileCvtStringToObjPlace */
5405
5406 /*************************************<->*************************************
5407  *
5408  *  _DtNextToken (pchIn, pLen, ppchNext)
5409  *
5410  *
5411  *  Description:
5412  *  -----------
5413  *  XXDescription ...
5414  *
5415  *
5416  *  Inputs:
5417  *  ------
5418  *  pchIn = pointer to start of next token
5419  *
5420  *
5421  *  Outputs:
5422  *  -------
5423  *  pLen  =    pointer to integer containing number of characters in next token
5424  *  ppchNext = address of pointer to following token
5425  *
5426  *  Return =   next token or NULL
5427  *
5428  *
5429  *  Comments:
5430  *  --------
5431  *  None.
5432  *
5433  *************************************<->***********************************/
5434
5435 static unsigned char
5436 *_DtNextToken (
5437         unsigned char *pchIn,
5438         int *pLen,
5439         unsigned char **ppchNext)
5440 {
5441     unsigned char *pchR = pchIn;
5442     register int   i;
5443 #ifdef MULTIBYTE
5444     register int   chlen;
5445
5446     for (i = 0; ((chlen = mblen ((char *)pchIn, MB_CUR_MAX)) > 0); i++)
5447     /* find end of word: requires singlebyte whitespace terminator */
5448     {
5449         if ((chlen == 1) && isspace (*pchIn))
5450         {
5451             break;
5452         }
5453         pchIn += chlen;
5454     }
5455
5456 #else
5457     for (i = 0; *pchIn && !isspace (*pchIn); i++, pchIn++)
5458     /* find end of word */
5459     {
5460     }
5461 #endif
5462
5463     /* skip to next word */
5464 #ifdef MULTIBYTE
5465     while (pchIn && (mblen ((char *)pchIn, MB_CUR_MAX) == 1) && isspace (*pchIn))
5466 #else
5467     while (pchIn && isspace (*pchIn))
5468 #endif
5469     {
5470         *pchIn++;
5471     }
5472
5473     *ppchNext = pchIn;
5474     *pLen = i;
5475     if (i)
5476     {
5477         return(pchR);
5478     }
5479     else
5480     {
5481        return(NULL);
5482     }
5483
5484 } /* END OF FUNCTION _DtNextToken */
5485
5486 /*************************************<->*************************************
5487  *
5488  *  DtfileCvtStringToOpenDir (args, numArgs, fromVal, toVal)
5489  *
5490  *
5491  *  Description:
5492  *  -----------
5493  *  This function converts a string to an desktop placement scheme description.
5494  *
5495  *
5496  *  Inputs:
5497  *  ------
5498  *  args = NULL (don't care)
5499  *
5500  *  numArgs = 0 (don't care)
5501  *
5502  *  fromVal = resource value to convert
5503  *
5504  *
5505  *  Outputs:
5506  *  -------
5507  *  toVal = descriptor to use to return converted value
5508  *
5509  *************************************<->***********************************/
5510
5511 static void
5512 DtfileCvtStringToOpenDir (
5513           XrmValue *args,
5514           Cardinal numArgs,
5515           XrmValue *fromVal,
5516           XrmValue *toVal)
5517 {
5518    char * in_str = (char *) (fromVal->addr);
5519    static int i;
5520
5521    toVal->size = sizeof (int);
5522    toVal->addr = (XtPointer) &i;
5523
5524    if (_DtStringsAreEquivalent (in_str, "current"))
5525       i = CURRENT;
5526    else if (_DtStringsAreEquivalent (in_str, "new"))
5527       i = NEW;
5528    else
5529       i = CURRENT;
5530 /*
5531    else
5532    {
5533       toVal->size = 0;
5534       toVal->addr = NULL;
5535       XtStringConversionWarning ((char *)fromVal->addr, "OpenDir");
5536    }
5537 */
5538 }
5539
5540 /*************************************<->*************************************
5541  *
5542  *  DtfileCvtStringToDTIcon (args, numArgs, fromVal, toVal)
5543  *
5544  *
5545  *  Description:
5546  *  -----------
5547  *  This function converts a string to an desktop placement scheme description.
5548  *
5549  *
5550  *  Inputs:
5551  *  ------
5552  *  args = NULL (don't care)
5553  *
5554  *  numArgs = 0 (don't care)
5555  *
5556  *  fromVal = resource value to convert
5557  *
5558  *
5559  *  Outputs:
5560  *  -------
5561  *  toVal = descriptor to use to return converted value
5562  *
5563  *************************************<->***********************************/
5564
5565 static void
5566 DtfileCvtStringToDTIcon (
5567           XrmValue *args,
5568           Cardinal numArgs,
5569           XrmValue *fromVal,
5570           XrmValue *toVal)
5571 {
5572    char * in_str = (char *) (fromVal->addr);
5573    static int i;
5574
5575    toVal->size = sizeof (int);
5576    toVal->addr = (XtPointer) &i;
5577
5578    if (_DtStringsAreEquivalent (in_str, "large"))
5579       i = LARGE;
5580    else if (_DtStringsAreEquivalent (in_str, "small"))
5581       i = SMALL;
5582    else if (_DtStringsAreEquivalent (in_str, "default"))
5583       i = LARGE;  /* for now, eventually want to look at screen width/height*/
5584    else
5585       i = LARGE;
5586 /*
5587    else
5588    {
5589       toVal->size = 0;
5590       toVal->addr = NULL;
5591       XtStringConversionWarning ((char *)fromVal->addr, "DesktopIcon");
5592    }
5593 */
5594 }
5595
5596 static void
5597 DtfileCvtStringToTree (
5598           XrmValue *args,
5599           Cardinal numArgs,
5600           XrmValue *fromVal,
5601           XrmValue *toVal)
5602 {
5603    char * in_str = (char *) (fromVal->addr);
5604    static int i;
5605
5606    toVal->size = sizeof (int);
5607    toVal->addr = (XtPointer) &i;
5608
5609    DtfileStringToTree(in_str, &i);
5610 }
5611
5612 static void
5613 DtfileCvtStringToTreeFiles (
5614           XrmValue *args,
5615           Cardinal numArgs,
5616           XrmValue *fromVal,
5617           XrmValue *toVal)
5618 {
5619    char * in_str = (char *) (fromVal->addr);
5620    static int i;
5621
5622    toVal->size = sizeof (int);
5623    toVal->addr = (XtPointer) &i;
5624
5625    DtfileStringToTreeFiles(in_str, &i);
5626 }
5627
5628 static void
5629 DtfileCvtStringToView (
5630           XrmValue *args,
5631           Cardinal numArgs,
5632           XrmValue *fromVal,
5633           XrmValue *toVal)
5634 {
5635    char * in_str = (char *) (fromVal->addr);
5636    static int i;
5637
5638    toVal->size = sizeof (int);
5639    toVal->addr = (XtPointer) &i;
5640
5641    DtfileStringToView(in_str, &i);
5642 }
5643
5644 static void
5645 DtfileCvtStringToOrder (
5646           XrmValue *args,
5647           Cardinal numArgs,
5648           XrmValue *fromVal,
5649           XrmValue *toVal)
5650 {
5651    char * in_str = (char *) (fromVal->addr);
5652    static int i;
5653
5654    toVal->size = sizeof (int);
5655    toVal->addr = (XtPointer) &i;
5656
5657    DtfileStringToOrder(in_str, &i);
5658 }
5659
5660 static void
5661 DtfileCvtStringToDirection (
5662           XrmValue *args,
5663           Cardinal numArgs,
5664           XrmValue *fromVal,
5665           XrmValue *toVal)
5666 {
5667    char * in_str = (char *) (fromVal->addr);
5668    static int i;
5669
5670    toVal->size = sizeof (int);
5671    toVal->addr = (XtPointer) &i;
5672
5673    DtfileStringToDirection(in_str, &i);
5674 }
5675
5676 static void
5677 DtfileCvtStringToGrid (
5678           XrmValue *args,
5679           Cardinal numArgs,
5680           XrmValue *fromVal,
5681           XrmValue *toVal)
5682 {
5683    char * in_str = (char *) (fromVal->addr);
5684    static int i;
5685
5686    toVal->size = sizeof (int);
5687    toVal->addr = (XtPointer) &i;
5688
5689    DtfileStringToGrid(in_str, &i);
5690 }
5691
5692 FileMgrData *
5693 CheckOpenDir (
5694           char * directory,
5695           char * host)
5696 {
5697    int i;
5698    FileMgrData *file_mgr_data;
5699    DialogData *dialog_data;
5700
5701    for(i = 0; i < view_count; i++)
5702    {
5703       if(strcmp(directory, view_set[i]->directory_name) == 0 &&
5704                             strcmp(host, view_set[i]->host_name) == 0)
5705       {
5706          dialog_data = (DialogData *) view_set[i]->dialog_data;
5707          file_mgr_data = (FileMgrData *) dialog_data->data;
5708          return(file_mgr_data);
5709       }
5710    }
5711    return(NULL);
5712 }
5713
5714 char *
5715 GetRestrictedDirectory (
5716           Widget widget)
5717 {
5718    int i;
5719    FileMgrData *file_mgr_data;
5720    FileMgrRec *file_mgr_rec;
5721    DialogData *dialog_data;
5722
5723    for(i = 0; i < view_count; i++)
5724    {
5725       dialog_data = (DialogData *) view_set[i]->dialog_data;
5726       file_mgr_data = (FileMgrData *) dialog_data->data;
5727       file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
5728       if(file_mgr_rec->current_directory_text == widget &&
5729                                           file_mgr_data->fast_cd_enabled)
5730       {
5731          return(file_mgr_data->restricted_directory);
5732       }
5733    }
5734    return((char *)NULL);
5735 }
5736
5737 static void
5738 DtfileStringToTree(
5739    char *str,
5740    int *type)
5741 {
5742    if (_DtStringsAreEquivalent (str, "on"))
5743       *type = MULTIPLE_DIRECTORY;
5744    else if (_DtStringsAreEquivalent (str, "off"))
5745       *type = SINGLE_DIRECTORY;
5746    else
5747       *type = UNSET_VALUE;
5748 }
5749
5750 static void
5751 DtfileStringToTreeFiles(
5752    char *str,
5753    int *type)
5754 {
5755    if (_DtStringsAreEquivalent (str, "never"))
5756       *type = TREE_FILES_NEVER;
5757    else if (_DtStringsAreEquivalent (str, "choose"))
5758       *type = TREE_FILES_CHOOSE;
5759    else if (_DtStringsAreEquivalent (str, "always"))
5760       *type = TREE_FILES_ALWAYS;
5761    else
5762       *type = UNSET_VALUE;
5763 }
5764
5765 static void
5766 DtfileStringToView(
5767    char *str,
5768    int *type)
5769 {
5770    if (_DtStringsAreEquivalent (str, "no_icon") ||
5771                             _DtStringsAreEquivalent (str, "no_icons"))
5772       *type = BY_NAME;
5773    else if (_DtStringsAreEquivalent (str, "large_icon") ||
5774                             _DtStringsAreEquivalent (str, "large_icons"))
5775       *type = BY_NAME_AND_ICON;
5776    else if (_DtStringsAreEquivalent (str, "small_icon") ||
5777                             _DtStringsAreEquivalent (str, "small_icons"))
5778       *type = BY_NAME_AND_SMALL_ICON;
5779    else if (_DtStringsAreEquivalent (str, "attributes"))
5780       *type = BY_ATTRIBUTES;
5781    else
5782       *type = UNSET_VALUE;
5783 }
5784
5785 static void
5786 DtfileStringToOrder(
5787    char *str,
5788    int *type)
5789 {
5790    if (_DtStringsAreEquivalent (str, "file_type"))
5791       *type = ORDER_BY_FILE_TYPE;
5792    else if (_DtStringsAreEquivalent (str, "alphabetical"))
5793       *type = ORDER_BY_ALPHABETICAL;
5794    else if (_DtStringsAreEquivalent (str, "date"))
5795       *type = ORDER_BY_DATE;
5796    else if (_DtStringsAreEquivalent (str, "size"))
5797       *type = ORDER_BY_SIZE;
5798    else
5799       *type = UNSET_VALUE;
5800 }
5801
5802
5803 static void
5804 DtfileStringToDirection(
5805    char *str,
5806    int *type)
5807 {
5808    if (_DtStringsAreEquivalent (str, "ascending"))
5809       *type = DIRECTION_ASCENDING;
5810    else if (_DtStringsAreEquivalent (str, "descending"))
5811       *type = DIRECTION_DESCENDING;
5812    else
5813       *type = UNSET_VALUE;
5814 }
5815
5816 static void
5817 DtfileStringToGrid(
5818    char *str,
5819    int *type)
5820 {
5821    if (_DtStringsAreEquivalent (str, "on"))
5822       *type = RANDOM_OFF;
5823    else if (_DtStringsAreEquivalent (str, "off"))
5824       *type = RANDOM_ON;
5825    else
5826       *type = UNSET_VALUE;
5827 }
5828
5829 static void
5830 SetupSendRequestArgs(
5831    ApplicationArgs application_args,
5832    Tt_message msg)
5833 {
5834    char *vtype;
5835    if(application_args.title != NULL)
5836    {
5837       tt_message_arg_add( msg, TT_IN, "-title", application_args.title );
5838    }
5839    if(application_args.restricted != NULL)
5840    {
5841       tt_message_arg_add( msg, TT_IN, RESTRICTED_HEADER, 0 );
5842    }
5843    vtype = VIEW_HEADER;
5844    switch( application_args.view )
5845    {
5846        case BY_NAME:
5847            tt_message_arg_add( msg, TT_IN, vtype, "no_icon" );
5848            break;
5849        case BY_NAME_AND_ICON:
5850            tt_message_arg_add( msg, TT_IN, vtype, "large_icon" );
5851            break;
5852        case BY_NAME_AND_SMALL_ICON:
5853            tt_message_arg_add( msg, TT_IN, vtype, "small_icon" );
5854            break;
5855        case BY_ATTRIBUTES:
5856            tt_message_arg_add( msg, TT_IN, vtype, "attributes" );
5857            break;
5858        default:
5859            tt_message_arg_add( msg, TT_IN, vtype, "none" );
5860            break;
5861    }
5862
5863    vtype = "-order";
5864    switch( application_args.order )
5865    {
5866        case ORDER_BY_FILE_TYPE:
5867            tt_message_arg_add( msg, TT_IN, vtype, "file_type" );
5868            break;
5869        case ORDER_BY_ALPHABETICAL:
5870            tt_message_arg_add( msg, TT_IN, vtype, "alphabetical" );
5871            break;
5872        case ORDER_BY_DATE:
5873            tt_message_arg_add( msg, TT_IN, vtype, "date" );
5874            break;
5875        case ORDER_BY_SIZE:
5876            tt_message_arg_add( msg, TT_IN, vtype, "size" );
5877            break;
5878        default:
5879            tt_message_arg_add( msg, TT_IN, vtype, "none" );
5880            break;
5881    }
5882
5883    vtype = "-direction";
5884    switch( application_args.direction )
5885    {
5886        case DIRECTION_ASCENDING:
5887            tt_message_arg_add( msg, TT_IN, vtype, "ascending" );
5888            break;
5889        case DIRECTION_DESCENDING:
5890            tt_message_arg_add( msg, TT_IN, vtype, "descending" );
5891            break;
5892        default:
5893            tt_message_arg_add( msg, TT_IN, vtype, "none" );
5894            break;
5895    }
5896
5897    vtype = "-grid";
5898    switch( application_args.grid )
5899    {
5900        case RANDOM_OFF:
5901            tt_message_arg_add( msg, TT_IN, vtype, "on" );
5902            break;
5903        case RANDOM_ON:
5904            tt_message_arg_add( msg, TT_IN, vtype, "off" );
5905            break;
5906        default:
5907            tt_message_arg_add( msg, TT_IN, vtype, "none" );
5908            break;
5909    }
5910    vtype = "-tree";
5911    switch( application_args.tree_view )
5912    {
5913        case MULTIPLE_DIRECTORY:
5914            tt_message_arg_add( msg, TT_IN, vtype, "on" );
5915            break;
5916        case SINGLE_DIRECTORY:
5917            tt_message_arg_add( msg, TT_IN, vtype, "off" );
5918            break;
5919        default:
5920            tt_message_arg_add( msg, TT_IN, vtype, "none" );
5921            break;
5922    }
5923
5924    vtype = "-tree_files";
5925    switch( application_args.tree_files )
5926    {
5927        case TREE_FILES_NEVER:
5928            tt_message_arg_add( msg, TT_IN, vtype, "never" );
5929            break;
5930        case TREE_FILES_CHOOSE:
5931            tt_message_arg_add( msg, TT_IN, vtype, "choose" );
5932            break;
5933        case TREE_FILES_ALWAYS:
5934            tt_message_arg_add( msg, TT_IN, vtype, "always" );
5935            break;
5936        default:
5937            tt_message_arg_add( msg, TT_IN, vtype, "none" );
5938            break;
5939    }
5940
5941    if(application_args.help_volume != NULL)
5942    {
5943       tt_message_arg_add( msg, TT_IN, "-help_volume",
5944                           application_args.help_volume );
5945    }
5946 }
5947
5948 /*
5949  * This routine is used by ForceMyIconOpen to get the "Open" filetype and
5950  * find out what the new icon is.  It then places that icon in the
5951  * correct icon gadget.
5952  */
5953 static void
5954 BuildAndShowIconName(
5955    char *file_type_name,
5956    unsigned char view,
5957    unsigned char show_type,
5958    Widget widget)
5959 {
5960    char *new_file_type_name;
5961    char *ptr;
5962    Arg args[1];
5963    PixmapData *pixmapData;
5964
5965    new_file_type_name = (char *)XtMalloc(strlen(file_type_name) +
5966                                          strlen(ICON_OPEN_PREFIX) + 1);
5967    sprintf(new_file_type_name, "%s%s", ICON_OPEN_PREFIX, file_type_name);
5968
5969    if (view == BY_NAME_AND_ICON && show_type != MULTIPLE_DIRECTORY)
5970      pixmapData = _DtRetrievePixmapData(new_file_type_name,
5971                                         NULL,
5972                                         NULL,
5973                                         widget,
5974                                         LARGE);
5975    else
5976      pixmapData = _DtRetrievePixmapData(new_file_type_name,
5977                                         NULL,
5978                                         NULL,
5979                                         widget,
5980                                         SMALL);
5981
5982    if(pixmapData && pixmapData->iconFileName)
5983    {
5984      XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
5985      XtSetValues(widget, args, 1);
5986    }
5987 /*
5988    else
5989    {
5990      XtSetArg (args[0], XmNimageName, NULL);
5991      XtSetValues(widget, args, 1);
5992    }
5993 */
5994
5995    _DtCheckAndFreePixmapData(new_file_type_name,
5996                              widget,
5997                              (DtIconGadget) widget,
5998                              pixmapData);
5999
6000    XtFree(new_file_type_name);
6001 }
6002
6003
6004 /*
6005  * Given a directory name, this function will see if a view of the parent
6006  * directory is open; if so, then it will update the icon representing
6007  * this icon, in the parent view, so that it is drawn as 'closed'.  This
6008  * function must only be called if openDirType == NEW.
6009  */
6010
6011 void
6012 ForceMyIconClosed (
6013    char * host_name,
6014    char * directory_name)
6015 {
6016    register int i;
6017    register int j;
6018    register int k;
6019    Arg args[1];
6020    FileViewData * file_view_data = NULL;
6021    DialogData *dialog_data;
6022    FileMgrData *file_mgr_data;
6023    DesktopRec *desktopWindow;
6024    char * parent;
6025    char * fname;
6026    PixmapData *pixmapData;
6027
6028    /* find the parent directory of the one just removed */
6029    parent = _DtPName(directory_name);
6030    fname =  DName(directory_name);
6031
6032    /* first check to see if any File Manager views have this directory */
6033    for (i = 0; i < view_count; i++)
6034    {
6035       dialog_data = (DialogData *) view_set[i]->dialog_data;
6036       file_mgr_data = (FileMgrData *) dialog_data->data;
6037
6038       /* loop through until we find the file_view_data structure for
6039        * the directory to force open */
6040
6041       for(j = 0; j < file_mgr_data->directory_count; j++)
6042       {
6043          if (strcmp(parent, file_mgr_data->directory_set[j]->name) == 0)
6044          {
6045             for (k = 0; k < file_mgr_data->directory_set[j]->file_count; k++)
6046             {
6047                file_view_data =
6048                        file_mgr_data->directory_set[j]->file_view_data[k];
6049                if (strcmp(file_view_data->file_data->file_name, fname) == 0)
6050                   goto search_done;
6051             }
6052             break;
6053          }
6054       }
6055    }
6056
6057    search_done:
6058
6059    if( (file_view_data) && (file_mgr_data->view != BY_NAME) )
6060    {
6061       if (file_mgr_data->view == BY_NAME_AND_ICON  &&
6062                        file_mgr_data->show_type != MULTIPLE_DIRECTORY)
6063          pixmapData = _DtRetrievePixmapData(
6064                                  file_view_data->file_data->logical_type,
6065                                  fname,
6066                                  parent,
6067                                  file_view_data->widget,
6068                                  LARGE);
6069       else
6070          pixmapData = _DtRetrievePixmapData(
6071                                  file_view_data->file_data->logical_type,
6072                                  fname,
6073                                  parent,
6074                                  file_view_data->widget,
6075                                  SMALL);
6076
6077       if (pixmapData)
6078         XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
6079       else
6080         XtSetArg (args[0], XmNimageName, NULL);
6081       XtSetValues (file_view_data->widget, args, 1);
6082
6083       _DtCheckAndFreePixmapData(file_view_data->file_data->logical_type,
6084                                 file_view_data->widget,
6085                                 (DtIconGadget) file_view_data->widget,
6086                                 pixmapData);
6087    }
6088
6089    /* now check to see if any desktop objects are this directory */
6090    for(j = 0; j < desktop_data->numIconsUsed; j++)
6091    {
6092       char buf[MAX_PATH];
6093
6094       desktopWindow = desktop_data->desktopWindows[j];
6095       file_view_data = desktopWindow->file_view_data;
6096
6097       sprintf(buf, "%s/%s", desktopWindow->dir_linked_to,
6098                             desktopWindow->file_name);
6099       DtEliminateDots (buf);
6100
6101       if( (strcmp(buf, directory_name) == 0) &&
6102           (strcmp(desktopWindow->host, host_name) == 0) )
6103       {
6104          pixmapData = _DtRetrievePixmapData(
6105               file_view_data->file_data->logical_type,
6106               fname,
6107               NULL,
6108               desktopWindow->shell,
6109               desktopIconType);
6110
6111          if(pixmapData)
6112            XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
6113          else
6114            XtSetArg (args[0], XmNimageName, NULL);
6115          XtSetValues (desktopWindow->iconGadget, args, 1);
6116
6117          _DtCheckAndFreePixmapData(
6118                  desktopWindow->file_view_data->file_data->logical_type,
6119                  desktopWindow->shell,
6120                  (DtIconGadget) desktopWindow->iconGadget,
6121                  pixmapData);
6122       }
6123    }
6124 }
6125
6126
6127 /*************************************************************************
6128  *
6129  * MarqueeSelect - this is the callback which gets called when there is
6130  *    a marquee event happening on the root window.
6131  *
6132  ************************************************************************/
6133 static void
6134 MarqueeSelect (
6135       Widget w,
6136       int type,
6137       Position x,
6138       Position y,
6139       Dimension width,
6140       Dimension height,
6141       XtPointer client_data)
6142 {
6143    int i;
6144    Window   rootWindow;
6145    Atom     pCurrent;
6146    Screen   *currentScreen;
6147    int      screen;
6148    char     *workspace_name=NULL;
6149    Display *display;
6150
6151
6152    switch (type)
6153    {
6154        case DT_WSM_MARQUEE_SELECTION_TYPE_BEGIN:
6155             display = XtDisplay(desktop_data->desktopWindows[0]->shell);
6156             screen = XDefaultScreen(display);
6157             currentScreen = XScreenOfDisplay(display, screen);
6158             rootWindow = RootWindowOfScreen(currentScreen);
6159
6160             if(DtWsmGetCurrentWorkspace(display, rootWindow, &pCurrent)
6161                                                             == Success)
6162             {
6163                workspace_name = XGetAtomName (display, pCurrent);
6164                CleanUpWSName(workspace_name);
6165             }
6166             else
6167                workspace_name =
6168                   XtNewString(desktop_data->workspaceData[0]->name);
6169
6170             for(i = 0; i < desktop_data->numWorkspaces; i++)
6171             {
6172                if(strcmp(workspace_name,
6173                            desktop_data->workspaceData[i]->name) == 0)
6174                {
6175                   DeselectAllDTFiles(desktop_data->workspaceData[i]);
6176                   break;
6177                }
6178             }
6179             XtFree(workspace_name);
6180             break;
6181
6182        case DT_WSM_MARQUEE_SELECTION_TYPE_END:
6183             CheckDesktopMarquee(x, y, width, height);
6184             break;
6185
6186        case DT_WSM_MARQUEE_SELECTION_TYPE_CANCEL:
6187             break;
6188
6189        case DT_WSM_MARQUEE_SELECTION_TYPE_CONTINUE:
6190             CheckDesktopMarquee(x, y, width, height);
6191             break;
6192
6193        default:
6194             break;
6195    }
6196 }
6197
6198
6199 /*
6200  * We must wait for the message response, before exiting
6201  */
6202
6203 static void
6204 WaitForResponseAndExit( void )
6205
6206 {
6207    XtMainLoop();
6208 }
6209
6210 static void
6211 ExitApp(
6212         XtPointer clientData,
6213         DtString words[],
6214         int num_fields )
6215
6216 {
6217   FinalizeToolTalkSession( );
6218   exit(0);
6219 }
6220
6221
6222 /*
6223  * Puts up an Error dialog with Cancel and Help unmapped in the
6224  * center of the screen. The last argument is the OK callback
6225  */
6226
6227 static Widget
6228 post_dialog(Widget parent, char *title, char *msg, void (*DtErrExitCB)())
6229 {
6230    Widget dialog, dialogShell;
6231    XmString message_text, ok;
6232    Arg args[10];
6233    Dimension dialogWd, dialogHt;
6234    int n = 0;
6235
6236    ok = XmStringCreateLocalized ((char*)_DtOkString);
6237    message_text = XmStringCreateLocalized (msg);
6238
6239    XtSetArg(args[n], XmNautoUnmanage, False); n++;
6240    XtSetArg(args[n], XmNokLabelString, ok); n++;
6241    XtSetArg(args[n], XmNtitle, title); n++;
6242    XtSetArg(args[n], XmNmessageString, message_text); n++;
6243    XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
6244    XtSetArg (args[n], XmNdefaultPosition, False); n++;
6245    XtSetArg(args[n], XmNuseAsyncGeometry, True); n++;
6246
6247    dialog = XmCreateErrorDialog (parent, title, args, n);
6248    XtAddCallback (dialog, XmNokCallback, DtErrExitCB, NULL);
6249    XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
6250    XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
6251
6252    /* Disable the frame menu from dialog since we don't want the user
6253       to be able to close dialogs with the frame menu */
6254
6255    dialogShell = XtParent(dialog);
6256    XtSetArg(args[0], XmNmappedWhenManaged, False);
6257    XtSetArg(args[1], XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MENU);
6258    XtSetValues(dialogShell, args, 2);
6259    XtManageChild (dialog);
6260    XtRealizeWidget (dialogShell);
6261
6262    /* Center the dialog */
6263
6264    XtSetArg(args[0], XmNwidth, &dialogWd);
6265    XtSetArg(args[1], XmNheight, &dialogHt);
6266    XtGetValues(dialog, args, 2);
6267    XtSetArg (args[0], XmNx,
6268                 (WidthOfScreen(XtScreen(dialog)) - dialogWd) / 2);
6269    XtSetArg (args[1], XmNy,
6270                 (HeightOfScreen(XtScreen(dialog)) - dialogHt) / 2);
6271    XtSetArg (args[2], XmNmappedWhenManaged, True); 
6272    XtSetValues (dialog, args, 3);
6273
6274    XtSetArg(args[0], XmNmappedWhenManaged, True);
6275    XtSetValues(dialogShell, args, 1);
6276
6277    XtManageChild (dialog);
6278    XmStringFree(message_text);
6279
6280    return (dialog);
6281 }
6282
6283 /*  
6284  * This is the Callback when an error occurs while trying to create 
6285  * the .dt folder or sub-folders. Application exits.
6286  */
6287
6288 static void 
6289 DtErrExitCB (Widget dialog, XtPointer client_data, XtPointer call_data)
6290 {
6291 XtPopdown (XtParent (dialog));
6292 FinalizeToolTalkSession();
6293 exit (1);
6294 }
6295
6296 #if defined(__osf__) || defined(CSRG_BASED)
6297 extern void
6298 sigchld_handler(int signo)      /* Do not use the arg signo at the moment */
6299 {
6300     pid_t   pid;
6301     int     stat_loc;
6302
6303     /*
6304       On DUX, the process remains in the ZOMBIE
6305       state untill parent invokes wait or waitpid.
6306     */
6307
6308     pid = waitpid(-1, &stat_loc, WNOHANG);
6309     /* Child exit handling code follows, if any */
6310 }
6311 #endif /* __osf__ */