Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtfile / IconicPath.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: IconicPath.c /main/9 1996/10/15 10:08:03 mustafa $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  *
27  *   FILE:           IconicPath.c
28  *
29  *   COMPONENT_NAME: Desktop File Manager (dtfile)
30  *
31  *   Description:    Contains routines to handle the Iconic Path.
32  *
33  *   FUNCTIONS: ButtonCallback
34  *              ChangeManaged
35  *              ClassInitialize
36  *              ClassPartInitialize
37  *              DESIRED_HEIGHT
38  *              DESIRED_WIDTH
39  *              Destroy
40  *              DtUpdateIconicPath
41  *              GeometryManager
42  *              ICON_HT
43  *              IconicPathRedraw
44  *              Initialize
45  *              MHT
46  *              MIN_WD
47  *              MWD
48  *              QueryGeometry
49  *              Redisplay
50  *              Resize
51  *              SPC
52  *              SetValues
53  *              Update
54  *              WidgetNavigable
55  *              _DtCreateIconicPath
56  *              externaldef
57  *
58  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
59  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
60  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
61  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
62  *
63  ****************************************************************************
64  ************************************<+>*************************************/
65
66 /* Copied from Xm/XmI.h */
67 #define GMode(g)            ((g)->request_mode)
68 #define IsWidth(g)          (GMode (g) & CWWidth)
69 #define IsHeight(g)         (GMode (g) & CWHeight)
70 #define IsBorder(g)         (GMode (g) & CWBorderWidth)
71 #define IsQueryOnly(g)      (GMode (g) & XtCWQueryOnly)
72
73 #include <Xm/TransltnsP.h>
74 #include <Xm/LabelG.h>
75 #include <Xm/PushBG.h>
76 #include <Xm/DragDrop.h>
77 #include <Dt/Icon.h>
78 #include <Dt/IconP.h>
79 #include <Dt/DtNlUtils.h>
80 #include <Dt/Connect.h>
81 #include <Dt/FileM.h>
82 #include <Dt/Dts.h>
83 #include "Encaps.h"
84 #include "SharedProcs.h"
85
86 #include "Desktop.h"
87 #include "FileMgr.h"
88 #include "Main.h"
89 #include "ChangeDir.h"
90 #include "Prefs.h"
91 #include "IconicPathP.h"
92
93
94 #define defaultTranslations     _XmManager_defaultTranslations
95 #define traversalTranslations   _XmManager_managerTraversalTranslations
96
97
98 /********    Static Function Declarations    ********/
99
100 static void ClassInitialize( void ) ;
101 static void ClassPartInitialize( 
102                         WidgetClass w_class) ;
103 static void Initialize(
104                         Widget rw,
105                         Widget nw,
106                         ArgList args,
107                         Cardinal *num_args) ;
108 static void Destroy(
109                         Widget w) ;
110 static void Redisplay( 
111                         Widget wid,
112                         XEvent *event,
113                         Region region) ;
114 static void Resize( 
115                         Widget wid) ;
116 static XtGeometryResult GeometryManager( 
117                         Widget w,
118                         XtWidgetGeometry *request,
119                         XtWidgetGeometry *reply) ;
120 static void ChangeManaged( 
121                         Widget wid) ;
122 static Boolean SetValues( 
123                         Widget cw,
124                         Widget rw,
125                         Widget nw,
126                         ArgList args,
127                         Cardinal *num_args) ;
128 static XtGeometryResult QueryGeometry( 
129                         Widget wid,
130                         XtWidgetGeometry *intended,
131                         XtWidgetGeometry *desired) ;
132 static XmNavigability WidgetNavigable( 
133                         Widget wid) ;
134
135 /********    End Static Function Declarations    ********/
136
137
138 /*--------------------------------------------------------------------
139  * Convenience macros
140  *------------------------------------------------------------------*/
141
142 #define MWD(ip)        ((ip)->iconic_path.margin_width)
143 #define MHT(ip)        ((ip)->iconic_path.margin_height)
144 #define SPC(ip)        ((ip)->iconic_path.spacing)
145 #define MIN_WD(ip)     ((ip)->iconic_path.large_icons? \
146                             (ip)->iconic_path.large_min_width: \
147                             (ip)->iconic_path.small_min_width)
148 #define ICON_HT(ip)    ((ip)->iconic_path.large_icons? 32: 16)
149
150 #define DESIRED_WIDTH(ip) \
151    (MWD(ip) + (ip)->iconic_path.dotdot_button->core.width + MWD(ip) \
152     + ((ip)->iconic_path.dropzone? \
153          ((ip)->iconic_path.dropzone_icon->core.width + MWD(ip)): 0) \
154     + ((ip)->iconic_path.status_msg? \
155          ((ip)->iconic_path.status_label->core.width + MWD(ip)): 0))
156
157 #define DESIRED_HEIGHT(ip) \
158    (MHT(ip) + ICON_HT(ip) + SPC(ip) + \
159     (ip)->iconic_path.dotdot_button->core.height + MHT(ip))
160
161
162 /*--------------------------------------------------------------------
163  * Resource definitions for IconicPath
164  *------------------------------------------------------------------*/
165
166 static XmSyntheticResource syn_resources[] =
167 {
168         {       XmNmarginWidth,
169                 sizeof (Dimension),
170                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_width),
171                 XmeFromHorizontalPixels,
172                 XmeToHorizontalPixels
173         },
174
175         {       XmNmarginHeight,
176                 sizeof (Dimension),
177                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_height),
178                 XmeFromVerticalPixels,
179                 XmeToVerticalPixels
180         },
181 };
182
183
184 static XtResource resources[] =
185 {
186         {       XmNmarginWidth,
187                 XmCMarginWidth, XmRHorizontalDimension, sizeof (Dimension),
188                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_width),
189                 XmRImmediate, (XtPointer) 5
190         },
191
192         {       XmNmarginHeight,
193                 XmCMarginHeight, XmRVerticalDimension, sizeof (Dimension),
194                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_height),
195                 XmRImmediate, (XtPointer) 2
196         },
197
198         {       XmNspacing,
199                 XmCSpacing, XmRVerticalDimension, sizeof (Dimension),
200                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.spacing),
201                 XmRImmediate, (XtPointer) 4
202         },
203
204         {       DtNsmallMinWidth,
205                 XmCMinWidth, XmRHorizontalDimension, sizeof (Dimension),
206                 XtOffsetOf( struct _DtIconicPathRec,
207                             iconic_path.small_min_width),
208                 XmRImmediate, (XtPointer) 25
209         },
210
211         {       DtNlargeMinWidth,
212                 XmCMinWidth, XmRHorizontalDimension, sizeof (Dimension),
213                 XtOffsetOf( struct _DtIconicPathRec,
214                             iconic_path.large_min_width),
215                 XmRImmediate, (XtPointer) 45
216         },
217
218         {       DtNforceSmallIcons,
219                 DtCForceSmallIcons, XmRBoolean, sizeof (Boolean),
220                 XtOffsetOf( struct _DtIconicPathRec,
221                 iconic_path.force_small_icons),
222                 XmRImmediate, (XtPointer) False
223         },
224
225         {       DtNforceLargeIcons,
226                 DtCForceLargeIcons, XmRBoolean, sizeof (Boolean),
227                 XtOffsetOf( struct _DtIconicPathRec,
228                             iconic_path.force_large_icons),
229                 XmRImmediate, (XtPointer) False
230         },
231
232         {       "buttons",
233                 "Buttons", XmRBoolean, sizeof (Boolean),
234                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.buttons),
235                 XmRImmediate, (XtPointer) False
236         },
237
238         {       "dropZone",
239                 "DropZone", XmRBoolean, sizeof (Boolean),
240                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.dropzone),
241                 XmRImmediate, (XtPointer) False
242         },
243
244         {       "statusMsg",
245                 "StatusMsg", XmRBoolean, sizeof (Boolean),
246                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.status_msg),
247                 XmRImmediate, (XtPointer) True
248         },
249
250         {       DtNfileMgrRec,
251                 DtCfileMgrRec, XmRString, sizeof (char *),
252                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.file_mgr_rec),
253                 XmRImmediate, (XtPointer) NULL
254         },
255
256         {       DtNcurrentDirectory,
257                 DtCCurrentDirectory, XmRString, sizeof (char *),
258                 XtOffsetOf( struct _DtIconicPathRec,
259                             iconic_path.current_directory),
260                 XmRImmediate, (XtPointer) NULL
261         },
262
263         {       DtNlargeIcons,
264                 DtCLargeIcons, XmRBoolean, sizeof (Boolean),
265                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.large_icons),
266                 XmRImmediate, (XtPointer) True
267         },
268
269         {       DtNiconsChanged,
270                 DtCIconsChanged, XmRBoolean, sizeof (Boolean),
271                 XtOffsetOf( struct _DtIconicPathRec, iconic_path.icons_changed),
272                 XmRImmediate, (XtPointer) True
273         },
274
275 };
276
277
278
279 /*--------------------------------------------------------------------
280  *
281  * Full class record constant
282  *
283  *------------------------------------------------------------------*/
284
285 static XmBaseClassExtRec baseClassExtRec = {
286     NULL,
287     NULLQUARK,
288     XmBaseClassExtVersion,
289     sizeof(XmBaseClassExtRec),
290     NULL,                               /* InitializePrehook    */
291     NULL,                               /* SetValuesPrehook     */
292     NULL,                               /* InitializePosthook   */
293     NULL,                               /* SetValuesPosthook    */
294     NULL,                               /* secondaryObjectClass */
295     NULL,                               /* secondaryCreate      */
296     NULL,                               /* getSecRes data       */
297     { 0 },                              /* fastSubclass flags   */
298     NULL,                               /* getValuesPrehook     */
299     NULL,                               /* getValuesPosthook    */
300     NULL,                               /* classPartInitPrehook */
301     NULL,                               /* classPartInitPosthook*/
302     NULL,                               /* ext_resources        */
303     NULL,                               /* compiled_ext_resources*/
304     0,                                  /* num_ext_resources    */
305     FALSE,                              /* use_sub_resources    */
306     WidgetNavigable,                    /* widgetNavigable      */
307     NULL                                /* focusChange          */
308 };
309
310 externaldef( dticonicpathclassrec) DtIconicPathClassRec dtIconicPathClassRec =
311 {
312    {                    /* core_class fields      */
313       (WidgetClass) &xmManagerClassRec,         /* superclass         */
314       "DtIconicPath",                           /* class_name         */
315       sizeof(DtIconicPathRec),                  /* widget_size        */
316       ClassInitialize,                          /* class_initialize   */
317       ClassPartInitialize,                      /* class_part_init    */
318       FALSE,                                    /* class_inited       */
319       Initialize,                               /* initialize         */
320       NULL,                                     /* initialize_hook    */
321       XtInheritRealize,                         /* realize            */
322       NULL,                                     /* actions            */
323       0,                                        /* num_actions        */
324       resources,                                /* resources          */
325       XtNumber(resources),                      /* num_resources      */
326       NULLQUARK,                                /* xrm_class          */
327       TRUE,                                     /* compress_motion    */
328       FALSE,                                    /* compress_exposure  */
329       TRUE,                                     /* compress_enterlv   */
330       FALSE,                                    /* visible_interest   */
331       Destroy,                                  /* destroy            */
332       Resize,                                   /* resize             */
333       Redisplay,                                /* expose             */
334       SetValues,                                /* set_values         */
335       NULL,                                     /* set_values_hook    */
336       XtInheritSetValuesAlmost,                 /* set_values_almost  */
337       NULL,                                     /* get_values_hook    */
338       NULL,                                     /* accept_focus       */
339       XtVersion,                                /* version            */
340       NULL,                                     /* callback_private   */
341       defaultTranslations,                      /* tm_table           */
342       QueryGeometry,                            /* query_geometry     */
343       NULL,                                     /* display_accelerator*/
344       (XtPointer)&baseClassExtRec,              /* extension          */
345    },
346    {            /* composite_class fields */
347       GeometryManager,                          /* geometry_manager   */
348       ChangeManaged,                            /* change_managed     */
349       XtInheritInsertChild,                     /* insert_child       */
350       XtInheritDeleteChild,                     /* delete_child       */
351       NULL,                                     /* extension          */
352    },
353
354    {            /* constraint_class fields */
355       NULL,                                     /* resource list        */   
356       0,                                        /* num resources        */   
357       0,                                        /* constraint size      */   
358       NULL,                                     /* init proc            */   
359       NULL,                                     /* destroy proc         */   
360       NULL,                                     /* set values proc      */   
361       NULL,                                     /* extension            */
362    },
363
364    {            /* manager_class fields */
365       traversalTranslations,                    /* translations           */
366       syn_resources,                            /* syn_resources          */
367       XtNumber (syn_resources),                 /* num_get_resources      */
368       NULL,                                     /* syn_cont_resources     */
369       0,                                        /* num_get_cont_resources */
370       XmInheritParentProcess,                   /* parent_process         */
371       NULL,                                     /* extension           */    
372    },
373
374    {            /* drawingArea class - none */     
375       0                                         /* mumble */
376    }    
377 };
378
379 externaldef( dticonicpathwidgetclass) WidgetClass dtIconicPathWidgetClass
380                                        = (WidgetClass) &dtIconicPathClassRec ;
381
382
383 /*--------------------------------------------------------------------
384  * Activate Callback for iconic path buttons and double click on icons
385  *------------------------------------------------------------------*/
386
387 static void
388 ButtonCallback(
389         Widget w,
390         XtPointer client_data,
391         XtPointer call_data )
392 {
393    DtIconicPathWidget ip = (DtIconicPathWidget)client_data;
394    FileMgrRec *file_mgr_rec = (FileMgrRec *) ip->iconic_path.file_mgr_rec;
395    DialogData  *dialog_data;
396    FileMgrData *file_mgr_data;
397    char host_name[MAX_PATH];
398    int i;
399
400    if (XtClass(w) == dtIconGadgetClass)
401    {
402       if (((XmAnyCallbackStruct *)call_data)->reason != XmCR_DEFAULT_ACTION)
403          return;
404    }
405
406    if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
407       return;
408    file_mgr_data = (FileMgrData *) dialog_data->data;
409    strcpy(host_name, file_mgr_data->host);
410
411    if (w == ip->iconic_path.dotdot_button)
412       i = ip->iconic_path.left_component - 1;
413    else
414    {
415       for (i = 0; i < ip->iconic_path.num_components; i++)
416          if (w == ip->iconic_path.components[i].button ||
417              w == ip->iconic_path.components[i].icon)
418          {
419             break;
420          }
421    }
422
423    if (i == ip->iconic_path.num_components - 1)
424       FileMgrReread (file_mgr_rec);
425
426    else if (i < ip->iconic_path.num_components)
427       ShowNewDirectory (file_mgr_data, host_name,
428                         ip->iconic_path.components[i].path);
429 }
430
431
432 /*--------------------------------------------------------------------
433  * Iconic path update function
434  *------------------------------------------------------------------*/
435
436 static int
437 Update(
438         DtIconicPathWidget ip,
439         FileMgrRec *file_mgr_rec,
440         FileMgrData *file_mgr_data)
441 {
442    static Pixmap change_view_pixmap = XmUNSPECIFIED_PIXMAP;
443    char *fileLabel;
444    Widget *manage;
445    int nmanage;
446    Dimension iwidth, iheight;
447    int twidth;
448    Pixel foreground, background;
449    Arg args[35];
450    char *ptr, *path, *name;
451    XmString xm_string;
452    int restricted_len;
453    int path_len;
454    Boolean forbidden;
455    int i, j, n;
456    int x, y;
457    int n_changes = 0;
458    PixmapData *pixmapData;
459    char msg_buf[21+MAX_PATH];
460
461    /* macro that updates the change count */
462 # define INC_N_CHANGES() \
463    if (n_changes++ == 0) \
464    {  /* first change: unmanage all children and clear the window */ \
465       XtUnmanageChildren(ip->composite.children, ip->composite.num_children); \
466       if (XtIsRealized((Widget)ip)) \
467          XClearWindow(XtDisplay(ip), XtWindow(ip)); \
468    } else
469
470    /* macro that moves a child and updates the change count */
471 # define MOVE_OBJECT(w,_x,_y) \
472    if ((w)->core.x != (_x) || (w)->core.y != (_y)) \
473    { \
474       INC_N_CHANGES(); \
475       XmeConfigureObject(w, _x, _y, (w)->core.width, (w)->core.height, (w)->core.border_width); \
476    } else
477
478
479    DPRINTF2((
480      "IconicPath.Update: cur_dir '%s', dir_shown '%s', icons_changed %d\n",
481      ip->iconic_path.current_directory,
482      ip->iconic_path.directory_shown? ip->iconic_path.directory_shown: "(nil)",
483      ip->iconic_path.icons_changed));
484
485    /* enforce the forceSmallIconsor forceLargeIcons resources */
486    if (ip->iconic_path.force_small_icons)
487       ip->iconic_path.large_icons = False;
488    else if (ip->iconic_path.force_large_icons)
489       ip->iconic_path.large_icons = True;
490
491    /* create "..." button, if necessary */
492    if (ip->iconic_path.dotdot_button == NULL)
493    {
494       xm_string = XmStringCreateLocalized("...");
495       n = 0;
496       XtSetArg (args[n], XmNlabelString, xm_string);            n++;
497       XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING);  n++;
498       XtSetArg (args[n], XmNmarginHeight, 0);                   n++;
499       XtSetArg (args[n], XmNhighlightThickness, 0);             n++;
500       if (ip->iconic_path.buttons)
501       {
502          XtSetArg (args[n], XmNshadowThickness, 1);                n++;
503          XtSetArg (args[n], XmNtraversalOn, False);                n++;
504          ip->iconic_path.dotdot_button =
505             XmCreatePushButtonGadget((Widget)ip, "iconic_path_button", args, n);
506          XtAddCallback(ip->iconic_path.dotdot_button,
507                        XmNactivateCallback, ButtonCallback, ip);
508       }
509       else
510       {
511          ip->iconic_path.dotdot_button =
512             XmCreateLabelGadget((Widget)ip, "iconic_path_label", args, n);
513       }
514       XmStringFree(xm_string);
515       if (ip->iconic_path.dotdot_button->core.width < (Dimension)((Dimension)MIN_WD(ip)/(Dimension)2))
516       {
517          XmeConfigureObject(ip->iconic_path.dotdot_button,
518                             ip->iconic_path.dotdot_button->core.x,
519                             ip->iconic_path.dotdot_button->core.y,
520                             (Dimension)MIN_WD(ip)/(Dimension)2,
521                             ip->iconic_path.dotdot_button->core.height, 0);
522       }
523    }
524    else if (ip->iconic_path.large_shown != ip->iconic_path.large_icons)
525    {
526       xm_string = XmStringCreateLocalized("...");
527       XtSetArg (args[0], XmNlabelString, xm_string);
528       XtSetValues(ip->iconic_path.dotdot_button, args, 1);
529       XmStringFree(xm_string);
530       if (ip->iconic_path.dotdot_button->core.width < (Dimension)((Dimension)MIN_WD(ip)/(Dimension)2))
531       {
532          XmeConfigureObject(ip->iconic_path.dotdot_button,
533                             ip->iconic_path.dotdot_button->core.x,
534                             ip->iconic_path.dotdot_button->core.y,
535                             (Dimension)MIN_WD(ip)/(Dimension)2,
536                             ip->iconic_path.dotdot_button->core.height, 0);
537       }
538    }
539
540    /* create StatuMsg, if necessary */
541    if (ip->iconic_path.status_msg && ip->iconic_path.status_label == NULL)
542    {
543       /* create StatuMsg */
544       n = 0;
545       XtSetArg (args[n], XmNmarginHeight, 0);                   n++;
546       XtSetArg (args[n], XmNhighlightThickness, 0);             n++;
547       ip->iconic_path.status_label =
548             XmCreateLabelGadget((Widget)ip, "status_label", args, n);
549    }
550
551    foreground = ip->manager.foreground;
552    background = ip->core.background_pixel;
553
554    /* create DropZone, if necessary */
555    if (ip->iconic_path.dropzone && ip->iconic_path.dropzone_icon == NULL)
556    {
557       /* create DropZone */
558       if (change_view_pixmap == XmUNSPECIFIED_PIXMAP)
559       {
560          foreground = ip->manager.foreground;
561          background = ip->core.background_pixel;
562          change_view_pixmap = _DtGetPixmap(XtScreen(ip), CHANGE_VIEW_ICON_M,
563                                            foreground, background);
564       }
565       n = 0;
566       XtSetArg (args[n], XmNstring, NULL);                      n++;
567       XtSetArg (args[n], XmNshadowThickness, 2);                n++;
568       XtSetArg (args[n], XmNfillOnArm, False);                  n++;
569       XtSetArg (args[n], XmNhighlightThickness, 0);             n++;
570       XtSetArg (args[n], XmNpixmap, change_view_pixmap);        n++;
571       XtSetArg (args[n], XmNtraversalOn, False);                n++;
572       XtSetArg (args[n], XmNdropSiteOperations,
573                    XmDROP_MOVE | XmDROP_COPY | XmDROP_LINK);    n++;
574       ip->iconic_path.dropzone_icon =
575          _DtCreateIcon ((Widget)ip, "change_view", args, n);
576
577       XtAddCallback (ip->iconic_path.dropzone_icon, XmNdropCallback,
578                      DropOnChangeView, (XtPointer) file_mgr_rec);
579       XtAddCallback (ip->iconic_path.dropzone_icon, XmNcallback,
580                      CurrentDirDropCallback, file_mgr_rec);
581    }
582
583    /* if the current directory changed, update component list */
584    if (file_mgr_data != NULL && ip->iconic_path.current_directory != NULL &&
585        ip->iconic_path.current_directory[0] == '/' &&
586        (ip->iconic_path.directory_shown == NULL ||
587         strcmp(ip->iconic_path.directory_shown,
588                ip->iconic_path.current_directory) != 0 ||
589         ip->iconic_path.large_shown != ip->iconic_path.large_icons ||
590         ip->iconic_path.icons_changed))
591    {
592       /* store the new directory */
593       XtFree(ip->iconic_path.directory_shown);
594       ip->iconic_path.directory_shown =
595          XtNewString(ip->iconic_path.current_directory);
596
597       /* for restricted directory: compute length of unshown path */
598       if (file_mgr_data->restricted_directory)
599       {
600          ptr = strrchr(file_mgr_data->restricted_directory, '/');
601          if( ptr == file_mgr_data->restricted_directory )
602            restricted_len = 1;
603          else
604            restricted_len = ptr? ptr - file_mgr_data->restricted_directory: 0;
605       }
606       else
607          restricted_len = 0;
608
609
610       /* get all path components */
611       i = 0;
612       ptr = ip->iconic_path.directory_shown;
613       for (;;)
614       {
615          /* extract the next path component */
616          if (ptr != NULL)
617             *ptr = '\0';
618          if (ip->iconic_path.directory_shown[0] == '\0')
619             path = name = "/";
620          else
621          {
622             path = ip->iconic_path.directory_shown;
623             name = strrchr(path, '/') + 1;
624          }
625
626          /* don't show path components above a restricted directory */
627          path_len = strlen(path);
628          if (restricted_len && path_len <= restricted_len)
629             goto next_component;
630
631          /* in restricted mode: check if this component is above $HOME */
632          forbidden = restrictMode
633              && strncmp(path, users_home_dir, path_len) == 0
634              && (path_len == 1 ||
635                  users_home_dir[path_len] == '/' &&
636                  users_home_dir[path_len + 1] != '\0');
637
638          /* check if we need to add or update the path component */
639          if (i >= ip->iconic_path.num_components)
640          {
641             /* create new component */
642             INC_N_CHANGES();
643
644             ip->iconic_path.components = (struct _IconicPathComponent *)
645                XtRealloc((char *)ip->iconic_path.components,
646                          (i + 1)*sizeof(struct _IconicPathComponent));
647
648             ip->iconic_path.components[i].path = XtNewString(path);
649             pixmapData = GetPixmapData(file_mgr_rec, 
650                                        file_mgr_data,
651                                        path,
652                                        ip->iconic_path.large_icons);
653
654             n = 0;
655             XtSetArg (args[n], XmNstring, NULL);                      n++;
656             if (pixmapData)
657             {
658               XtSetArg (args[n], XmNimageName, pixmapData->iconFileName);
659               ip->iconic_path.components[i].icon_name =
660                                         XtNewString(pixmapData->iconFileName);
661             }
662             else
663             {
664               XtSetArg (args[n], XmNimageName, NULL); 
665               ip->iconic_path.components[i].icon_name = NULL;
666             }
667             n++;
668
669
670             if ( background == white_pixel )
671             {
672               XtSetArg (args[n], XmNbackground, white_pixel);         n++;
673               XtSetArg (args[n], XmNpixmapBackground, white_pixel);   n++;
674               XtSetArg (args[n], XmNpixmapForeground, black_pixel);   n++;
675             }
676             else if ( background == black_pixel )
677             {
678               XtSetArg (args[n], XmNbackground, black_pixel);         n++;
679               XtSetArg (args[n], XmNpixmapBackground, white_pixel);   n++;
680               XtSetArg (args[n], XmNpixmapForeground, black_pixel);   n++;
681             }
682             else
683             {
684               XtSetArg (args[n], XmNbackground, background);          n++;
685             }
686
687
688             XtSetArg (args[n], XmNhighlightThickness, 0);             n++;
689             XtSetArg (args[n], XmNmarginHeight, 0);                   n++;
690             XtSetArg (args[n], XmNmarginWidth, 0);                    n++;
691             XtSetArg (args[n], XmNtraversalOn, False);                n++;
692             ip->iconic_path.components[i].icon =
693                _DtCreateIcon ((Widget)ip, "iconic_path_icon", args, n);
694
695             _DtCheckAndFreePixmapData(
696                            GetDirectoryLogicalType(file_mgr_data, path),
697                            file_mgr_rec->shell,
698                            (DtIconGadget) ip->iconic_path.components[i].icon,
699                            pixmapData);
700
701             XtAddCallback (ip->iconic_path.components[i].icon, XmNcallback,
702                            ButtonCallback, ip);
703
704             if (fileLabel = DtDtsDataTypeToAttributeValue(
705                             GetDirectoryLogicalType(file_mgr_data, path),
706                             DtDTS_DA_LABEL,
707                             NULL))
708             {
709                xm_string = XmStringCreateLocalized(fileLabel);
710                DtDtsFreeAttributeValue(fileLabel);
711             }
712             else
713             {
714                xm_string = XmStringCreateLocalized(name);
715             }
716
717             n = 0;
718             XtSetArg (args[n], XmNlabelString, xm_string);            n++;
719             XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING);  n++;
720             XtSetArg (args[n], XmNmarginHeight, 0);                   n++;
721             XtSetArg (args[n], XmNhighlightThickness, 0);             n++;
722             if (ip->iconic_path.buttons)
723             {
724                XtSetArg (args[n], XmNshadowThickness, 1);             n++;
725                XtSetArg (args[n], XmNtraversalOn, False);             n++;
726                XtSetArg (args[n], XmNsensitive, !forbidden);          n++;
727                ip->iconic_path.components[i].button =
728                   XmCreatePushButtonGadget ((Widget)ip, "iconic_path_button",
729                                             args, n);
730                XtAddCallback(ip->iconic_path.components[i].button,
731                              XmNactivateCallback, ButtonCallback, ip);
732             }
733             else
734             {
735                ip->iconic_path.components[i].button =
736                   XmCreateLabelGadget((Widget)ip, "iconic_path_label", args, n);
737             }
738             XmStringFree(xm_string);
739
740          }
741          else
742          {
743             /* check if the existing component needs to be updated */
744
745             /* check if the path has changed */
746             if (strcmp(ip->iconic_path.components[i].path, path) != 0 ||
747                 ip->iconic_path.large_shown != ip->iconic_path.large_icons)
748             {
749                INC_N_CHANGES();
750
751                XtFree(ip->iconic_path.components[i].path);
752                ip->iconic_path.components[i].path = XtNewString(path);
753             }
754
755             if (fileLabel = DtDtsDataTypeToAttributeValue(
756                             GetDirectoryLogicalType(file_mgr_data, path),
757                             DtDTS_DA_LABEL,
758                             NULL))
759             {
760                xm_string = XmStringCreateLocalized(fileLabel);
761                DtDtsFreeAttributeValue(fileLabel);
762             }
763             else
764             {
765                xm_string = XmStringCreateLocalized(name);
766             }
767             XtSetArg (args[0], XmNlabelString, xm_string);
768             XtSetArg (args[1], XmNsensitive, !forbidden);
769             XtSetValues(ip->iconic_path.components[i].button, args, 2);
770             XmStringFree(xm_string);
771
772             /* check if the icon has changed */
773             pixmapData = GetPixmapData(file_mgr_rec,
774                                        file_mgr_data,
775                                        path,
776                                        ip->iconic_path.large_icons);
777
778             if (pixmapData)
779             {
780                if ((pixmapData->iconFileName == NULL) !=
781                           (ip->iconic_path.components[i].icon_name == NULL) ||
782                    pixmapData->iconFileName != NULL &&
783                    strcmp(pixmapData->iconFileName,
784                           ip->iconic_path.components[i].icon_name) != 0)
785                {
786                   INC_N_CHANGES();
787
788                   XtFree(ip->iconic_path.components[i].icon_name);
789                   ip->iconic_path.components[i].icon_name =
790                                   XtNewString(pixmapData->iconFileName);
791
792                   XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
793                   XtSetValues(ip->iconic_path.components[i].icon, args, 1);
794                    
795                   _DtCheckAndFreePixmapData(
796                           GetDirectoryLogicalType(file_mgr_data, path),
797                           file_mgr_rec->shell,
798                           (DtIconGadget) ip->iconic_path.components[i].icon,
799                           pixmapData);
800                }
801             }
802             else
803             {
804                XtFree(ip->iconic_path.components[i].icon_name);
805                ip->iconic_path.components[i].icon_name = NULL;
806                XtSetArg (args[0], XmNimageName, NULL);
807                XtSetValues(ip->iconic_path.components[i].icon, args, 1);
808             }
809          }
810
811          /* update component count */
812          i++;
813
814 next_component:
815          /* go to the next path component */
816          if (ptr == NULL)
817            break;
818
819          /* restore '/' */
820          *ptr = '/';
821
822          /* find next component */
823          if (strcmp(ptr, "/") == 0)
824             break;
825          ptr = DtStrchr(ptr + 1, '/');
826       }
827
828       /* free any leftover components */
829       for (j = i; j < ip->iconic_path.num_components; j++)
830       {
831          INC_N_CHANGES();
832
833          XtFree(ip->iconic_path.components[j].path);
834          ip->iconic_path.components[j].path = NULL;
835          XtFree(ip->iconic_path.components[j].icon_name);
836          ip->iconic_path.components[j].icon_name = NULL;
837          XtDestroyWidget(ip->iconic_path.components[j].icon);
838          XtDestroyWidget(ip->iconic_path.components[j].button);
839       }
840
841       ip->iconic_path.num_components = i;
842       ip->iconic_path.large_shown = ip->iconic_path.large_icons;
843    }
844
845    /* update component widths */
846    for (i = 0; i < ip->iconic_path.num_components; i++)
847    {
848       /* determine width for this component */
849       twidth = MIN_WD(ip);
850       if (ip->iconic_path.components[i].icon->core.width > (Dimension)twidth)
851          twidth = ip->iconic_path.components[i].icon->core.width;
852       if (ip->iconic_path.components[i].button->core.width > (Dimension)twidth)
853          twidth = ip->iconic_path.components[i].button->core.width;
854
855       if (ip->iconic_path.components[i].button->core.width < (Dimension)twidth)
856       {
857          /* increment the change count */
858          INC_N_CHANGES();
859
860          /* resize */
861          XmeConfigureObject(ip->iconic_path.components[i].button,
862                             ip->iconic_path.components[i].button->core.x,
863                             ip->iconic_path.components[i].button->core.y,
864                             twidth,
865                             ip->iconic_path.components[i].button->core.height,
866                             0);
867       }
868
869       ip->iconic_path.components[i].width = twidth;
870    }
871
872    /* update the status message */
873    if (file_mgr_data && ip->iconic_path.status_msg)
874       GetStatusMsg(file_mgr_data, msg_buf);
875    else
876       strcpy(msg_buf, "");
877
878    if (ip->iconic_path.msg_text == NULL ||
879        strcmp(msg_buf, ip->iconic_path.msg_text) != 0)
880    {
881       /* remember the new status message text */
882       XtFree(ip->iconic_path.msg_text);
883       ip->iconic_path.msg_text = XtNewString(msg_buf);
884
885       if (ip->iconic_path.status_label)
886       {
887          /* clear the area under the old status message text */
888          if (XtIsRealized((Widget)ip) &&
889              ip->iconic_path.status_label->core.x > 0)
890             XClearArea(XtDisplay(ip), XtWindow(ip),
891                        ip->iconic_path.status_label->core.x,
892                        ip->iconic_path.status_label->core.y,
893                        ip->iconic_path.status_label->core.width,
894                        ip->iconic_path.status_label->core.height, False);
895
896          /* set a new status message text */
897          xm_string = XmStringCreateLocalized(msg_buf);
898          XtSetArg (args[0], XmNlabelString, xm_string);
899          XtSetValues(ip->iconic_path.status_label, args, 1);
900          XmStringFree(xm_string);
901       }
902    }
903
904    /* set widget size, if necessary */
905    if (ip->core.width == 0)
906       ip->core.width = DESIRED_WIDTH(ip);
907    if (ip->core.height == 0)
908       ip->core.height = DESIRED_HEIGHT(ip);
909
910    /* for the layout: check how much of the path will fit */
911    twidth = MWD(ip) + ip->iconic_path.dotdot_button->core.width + MWD(ip);
912    if (ip->iconic_path.status_msg && ip->iconic_path.dropzone)
913    {
914       if (ip->iconic_path.status_label->core.width
915            >= ip->iconic_path.dropzone_icon->core.width)
916          twidth += ip->iconic_path.status_label->core.width + MWD(ip);
917       else
918          twidth += ip->iconic_path.dropzone_icon->core.width + MWD(ip);
919    }
920    else if (ip->iconic_path.status_msg)
921       twidth += ip->iconic_path.status_label->core.width + MWD(ip);
922    else if (ip->iconic_path.dropzone)
923       twidth += ip->iconic_path.dropzone_icon->core.width + MWD(ip);
924
925
926    for (i = ip->iconic_path.num_components; i > 0; i--)
927    {
928       twidth += SPC(ip) + ip->iconic_path.components[i - 1].width;
929       if ((Dimension)twidth > ip->core.width)
930          break;
931    }
932
933    if (i == 1 && (Dimension)(twidth - ip->iconic_path.dotdot_button->core.width - SPC(ip))
934                     <= ip->core.width)
935    {
936       i--;
937    }
938
939    if (i != ip->iconic_path.left_component)
940    {
941       INC_N_CHANGES();
942       ip->iconic_path.left_component = i;
943    }
944
945    /* allocate list of to-be-managed children */
946    manage = (Widget *)
947       XtMalloc((2*(ip->iconic_path.num_components - i) + 2)*sizeof(Widget));
948    nmanage = 0;
949
950    /* position & manage the path components */
951    x = MWD(ip);
952    y = ip->core.height - MHT(ip) - ip->iconic_path.dotdot_button->core.height
953         - SPC(ip);
954
955    if (i > 0)
956    {
957       MOVE_OBJECT(ip->iconic_path.dotdot_button, x, y + SPC(ip));
958       manage[nmanage++] = ip->iconic_path.dotdot_button;
959       x += ip->iconic_path.dotdot_button->core.width + SPC(ip);
960    }
961
962    for (j = i; j < ip->iconic_path.num_components; j++)
963    {
964       MOVE_OBJECT(ip->iconic_path.components[j].icon,
965                   x + SPC(ip),
966                   y - ip->iconic_path.components[j].icon->core.height);
967       MOVE_OBJECT(ip->iconic_path.components[j].button, x, y + SPC(ip));
968
969       x += ip->iconic_path.components[j].width + SPC(ip);
970
971       manage[nmanage++] = ip->iconic_path.components[j].icon;
972       manage[nmanage++] = ip->iconic_path.components[j].button;
973    }
974
975    /* position & manage the status message label */
976    if (ip->iconic_path.status_msg)
977    {
978       x = ip->core.width - MWD(ip) -
979           (int)ip->iconic_path.status_label->core.width;
980       if (x < 0)
981          x = 0;
982       y = ip->core.height - MHT(ip) -
983           (int)ip->iconic_path.status_label->core.height;
984       if (y < 0)
985          y = 0;
986
987       if (ip->iconic_path.status_label->core.x != x ||
988           ip->iconic_path.status_label->core.y != y)
989       {
990           XmeConfigureObject(ip->iconic_path.status_label, x, y,
991                              ip->iconic_path.status_label->core.width,
992                              ip->iconic_path.status_label->core.height,
993                              ip->iconic_path.status_label->core.border_width);
994       }
995
996       manage[nmanage++] = ip->iconic_path.status_label;
997
998       y -= SPC(ip);
999    }
1000    else
1001       y = ip->core.height;
1002
1003    /* position & manage the drop zone icon */
1004    if (ip->iconic_path.dropzone)
1005    {
1006       x = ip->core.width - MWD(ip) -
1007           (int)ip->iconic_path.dropzone_icon->core.width;
1008       if (x < 0)
1009          x = 0;
1010       y = (y - (int)ip->iconic_path.dropzone_icon->core.height + 1)/2;
1011       if (y < 0)
1012          y = 0;
1013
1014       MOVE_OBJECT(ip->iconic_path.dropzone_icon, x, y);
1015
1016       manage[nmanage++] = ip->iconic_path.dropzone_icon;
1017    }
1018
1019
1020    /* if all icons are there, manage the children */
1021    for (i = 0; i < ip->iconic_path.num_components; i++)
1022       if (ip->iconic_path.components[i].icon_name == NULL)
1023          break;
1024    if (file_mgr_data != NULL && i == ip->iconic_path.num_components)
1025    {
1026       DPRINTF2(("IconicPath.Update: manage %d children\n", nmanage));
1027       XtManageChildren(manage, nmanage);
1028    }
1029    XtFree((char *)manage);
1030
1031    /* reset icons_changed flag */
1032    ip->iconic_path.icons_changed = False;
1033
1034    return n_changes;
1035 }
1036
1037
1038 /*--------------------------------------------------------------------
1039  * Iconic path redraw function
1040  *------------------------------------------------------------------*/
1041
1042 static void
1043 IconicPathRedraw(
1044         DtIconicPathWidget ip)
1045 {
1046    FileMgrRec *file_mgr_rec = (FileMgrRec *)ip->iconic_path.file_mgr_rec;
1047    DialogData  * dialog_data;
1048    FileMgrData *file_mgr_data;
1049    int i;
1050    int x, y, l;
1051
1052    if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
1053       return;
1054    file_mgr_data = (FileMgrData *) dialog_data->data;
1055
1056    if (ip->iconic_path.gc == None)
1057    {
1058       XGCValues gc_values;
1059
1060       gc_values.foreground = ip->manager.foreground;
1061       gc_values.line_width = 2;
1062
1063       ip->iconic_path.gc = XCreateGC(XtDisplay(ip), XtWindow(ip),
1064                                      GCForeground | GCLineWidth, &gc_values);
1065    }
1066
1067    x = MWD(ip);
1068    y = ip->core.height - MHT(ip) - ip->iconic_path.dotdot_button->core.height
1069         - SPC(ip) - ICON_HT(ip)/2;
1070
1071    if (ip->iconic_path.left_component > 0)
1072    {
1073       XSetLineAttributes(XtDisplay(ip), ip->iconic_path.gc,
1074                          2, LineOnOffDash, CapNotLast, JoinMiter);
1075       XSetDashes(XtDisplay(ip), ip->iconic_path.gc, 0, "\04", 1);
1076
1077       l = ip->iconic_path.dotdot_button->core.width + SPC(ip) - 3;
1078       l = (l/4) * 4;
1079       XDrawLine(XtDisplay(ip), XtWindow(ip), ip->iconic_path.gc,
1080                 x + 2 + l, y, x + 2, y);
1081       x += ip->iconic_path.dotdot_button->core.width + SPC(ip);
1082       XSetLineAttributes(XtDisplay(ip), ip->iconic_path.gc,
1083                          2, LineSolid, CapNotLast, JoinMiter);
1084    }
1085
1086    for (i = ip->iconic_path.left_component;
1087         i < ip->iconic_path.num_components - 1;
1088         i++)
1089    {
1090       if (ip->iconic_path.components[i].icon_name != NULL &&
1091           ip->iconic_path.components[i+1].icon_name != NULL)
1092       {
1093          XDrawLine(XtDisplay(ip), XtWindow(ip), ip->iconic_path.gc,
1094                    x + SPC(ip) +
1095                        ip->iconic_path.components[i].icon->core.width + 1,
1096                    y,
1097                    x + SPC(ip) +
1098                        ip->iconic_path.components[i].width + SPC(ip) - 1,
1099                    y);
1100       }
1101       x += ip->iconic_path.components[i].width + SPC(ip);
1102    }
1103 }
1104
1105
1106
1107 /*--------------------------------------------------------------------
1108  * Class initialize
1109  *------------------------------------------------------------------*/
1110
1111 static void
1112 ClassInitialize( void )
1113 {   
1114   baseClassExtRec.record_type = XmQmotif ;
1115 }
1116
1117
1118 static void
1119 ClassPartInitialize(
1120         WidgetClass w_class )
1121 {   
1122     _XmFastSubclassInit( w_class, XmDRAWING_AREA_BIT) ;
1123     return ;
1124 }
1125
1126
1127 /*--------------------------------------------------------------------
1128  * Instance initialize
1129  *------------------------------------------------------------------*/
1130
1131 static void
1132 Initialize(
1133         Widget rw,
1134         Widget nw,
1135         ArgList args,
1136         Cardinal *num_args )
1137 {
1138     DtIconicPathWidget new_w = (DtIconicPathWidget) nw ;
1139     FileMgrRec *file_mgr_rec = (FileMgrRec *)new_w->iconic_path.file_mgr_rec;
1140
1141     new_w->iconic_path.msg_text = NULL;
1142     new_w->iconic_path.current_directory = NULL;
1143     new_w->iconic_path.directory_shown = NULL;
1144     new_w->iconic_path.large_shown = False;
1145     new_w->iconic_path.status_label = NULL;
1146     new_w->iconic_path.dotdot_button = NULL;
1147     new_w->iconic_path.dropzone_icon = NULL;
1148     new_w->iconic_path.num_components = 0;
1149     new_w->iconic_path.components = NULL;
1150     new_w->iconic_path.left_component = 0;
1151     new_w->iconic_path.gc = None;
1152
1153     Update(new_w, file_mgr_rec, NULL);
1154
1155     return;
1156 }
1157
1158
1159 /*--------------------------------------------------------------------
1160  * Instance destroy
1161  *------------------------------------------------------------------*/
1162
1163 static void
1164 Destroy(
1165         Widget w )
1166 {
1167     DtIconicPathWidget ip = (DtIconicPathWidget) w;
1168     int i;
1169
1170     /*
1171     XtFree(ip->iconic_path.current_directory);
1172     */
1173     ip->iconic_path.current_directory = NULL;
1174     XtFree(ip->iconic_path.msg_text);
1175     ip->iconic_path.msg_text = NULL;
1176     XtFree(ip->iconic_path.directory_shown);
1177     ip->iconic_path.directory_shown = NULL;
1178
1179     for (i = 0; i < ip->iconic_path.num_components; i++)
1180     {
1181        XtFree(ip->iconic_path.components[i].path);
1182        ip->iconic_path.components[i].path = NULL;
1183     }
1184
1185     XtFree((char *)ip->iconic_path.components);
1186     ip->iconic_path.components = NULL;
1187
1188     return;
1189 }
1190
1191
1192 /*--------------------------------------------------------------------
1193  * General redisplay function called on exposure events
1194  *------------------------------------------------------------------*/
1195
1196 static void
1197 Redisplay(
1198         Widget wid,
1199         XEvent *event,
1200         Region region )
1201 {
1202     DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
1203
1204     IconicPathRedraw (ip);
1205
1206     XmeRedisplayGadgets( (Widget) ip, event, region);
1207     return ;
1208 }
1209
1210
1211 /*--------------------------------------------------------------------
1212  * Resize
1213  *------------------------------------------------------------------*/
1214
1215 static void
1216 Resize(
1217         Widget wid )
1218 {
1219     DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
1220     FileMgrRec *file_mgr_rec = (FileMgrRec *)ip->iconic_path.file_mgr_rec;
1221     DialogData  *dialog_data;
1222     FileMgrData *file_mgr_data;
1223
1224     if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
1225        return;
1226     file_mgr_data = (FileMgrData *) dialog_data->data;
1227
1228     Update(ip, file_mgr_rec, file_mgr_data);
1229     return ;
1230 }
1231
1232
1233
1234 /*--------------------------------------------------------------------
1235  * GeometryManager
1236  *------------------------------------------------------------------*/
1237
1238 static XtGeometryResult
1239 GeometryManager(
1240         Widget w,
1241         XtWidgetGeometry *request,
1242         XtWidgetGeometry *reply )
1243 {
1244     DtIconicPathWidget ip;
1245
1246     ip = (DtIconicPathWidget) w->core.parent;
1247
1248     if (IsQueryOnly(request)) return XtGeometryYes;
1249
1250     if (IsWidth(request)) w->core.width = request->width;
1251     if (IsHeight(request)) w->core.height = request->height;
1252     if (IsBorder(request)) w->core.border_width = request->border_width;
1253
1254     /* @@@ adjust layout ? */
1255
1256     return XtGeometryYes;
1257 }
1258
1259
1260 /*--------------------------------------------------------------------
1261  * Re-layout children
1262  *------------------------------------------------------------------*/
1263
1264 static void
1265 ChangeManaged(
1266         Widget wid )
1267 {
1268     DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
1269     XtWidgetProc manager ;
1270
1271     XmeNavigChangeManaged((Widget) ip) ;
1272
1273     return;
1274 }
1275
1276
1277 /*--------------------------------------------------------------------
1278  * SetValues
1279  *------------------------------------------------------------------*/
1280
1281 static Boolean
1282 SetValues(
1283         Widget cw,
1284         Widget rw,
1285         Widget nw,
1286         ArgList args,
1287         Cardinal *num_args )
1288 {
1289     DtIconicPathWidget current = (DtIconicPathWidget) cw ;
1290     DtIconicPathWidget ip = (DtIconicPathWidget) nw ;
1291     FileMgrRec *file_mgr_rec = (FileMgrRec *)ip->iconic_path.file_mgr_rec;
1292     DialogData *dialog_data;
1293     FileMgrData *file_mgr_data;
1294     Boolean redisplay;
1295
1296     dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1297     file_mgr_data = dialog_data? (FileMgrData *) dialog_data->data: NULL;
1298
1299     redisplay = (Update(ip, file_mgr_rec, file_mgr_data) > 0);
1300
1301     if (XtHeight(ip) != DESIRED_HEIGHT(ip)
1302         || (Dimension)XtWidth(ip) < (Dimension)DESIRED_WIDTH(ip))
1303     {
1304        XtWidgetGeometry request;
1305        XtWidgetGeometry reply;
1306
1307        request.request_mode = 0;
1308        if (XtHeight(ip) != DESIRED_HEIGHT(ip))
1309        {
1310           request.request_mode |= CWHeight;
1311           request.height = DESIRED_HEIGHT(ip);
1312        }
1313        if ((Dimension)XtWidth(ip) < (Dimension)DESIRED_WIDTH(ip))
1314        {
1315           request.request_mode |= CWWidth;
1316           request.width = DESIRED_WIDTH(ip);
1317        }
1318
1319        if (XtMakeGeometryRequest(nw, &request, &reply) != XtGeometryNo)
1320           Update(ip, file_mgr_rec, file_mgr_data);
1321
1322        redisplay = True;
1323     }
1324
1325     return redisplay;
1326 }
1327
1328
1329 /*--------------------------------------------------------------------
1330  * QueryGeometry
1331  *------------------------------------------------------------------*/
1332
1333 static XtGeometryResult
1334 QueryGeometry(
1335         Widget wid,
1336         XtWidgetGeometry *intended,
1337         XtWidgetGeometry *desired )
1338 {
1339     DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
1340
1341     desired->width = DESIRED_WIDTH(ip);
1342     desired->height = DESIRED_HEIGHT(ip);
1343
1344     /* deal with user initial size setting */
1345     if (!XtIsRealized(wid))
1346     {
1347         if (XtWidth(wid) != 0) desired->width = XtWidth(wid) ;
1348         if (XtHeight(wid) != 0) desired->height = XtHeight(wid) ;
1349     }   
1350
1351     return XmeReplyToQueryGeometry(wid, intended, desired) ;
1352 }
1353
1354 static XmNavigability
1355 WidgetNavigable(
1356         Widget wid)
1357 {
1358   if(    wid->core.sensitive
1359      &&  wid->core.ancestor_sensitive
1360      &&  ((XmManagerWidget) wid)->manager.traversal_on    )
1361     {
1362       XmNavigationType nav_type
1363                            = ((XmManagerWidget) wid)->manager.navigation_type ;
1364
1365       if(    (nav_type == XmSTICKY_TAB_GROUP)
1366          ||  (nav_type == XmEXCLUSIVE_TAB_GROUP)
1367          ||  (    (nav_type == XmTAB_GROUP)
1368               &&  !_XmShellIsExclusive( wid))    )
1369         {
1370           return XmDESCENDANTS_TAB_NAVIGABLE ;
1371         }
1372     }
1373   return XmNOT_NAVIGABLE ;
1374 }
1375
1376
1377 /*--------------------------------------------------------------------
1378  * _DtCreateIconicPath: creates and returns a IconicPath widget.
1379  *------------------------------------------------------------------*/
1380
1381 Widget
1382 _DtCreateIconicPath(
1383         Widget p,
1384         String name,
1385         ArgList args,
1386         Cardinal n )
1387 {
1388     return( XtCreateWidget( name, dtIconicPathWidgetClass, p, args, n)) ;
1389 }
1390
1391
1392 /*--------------------------------------------------------------------
1393  * UpdateIconicPath: update IconicPath widget.
1394  *------------------------------------------------------------------*/
1395
1396 void
1397 DtUpdateIconicPath(
1398         FileMgrRec *file_mgr_rec,
1399         FileMgrData *file_mgr_data,
1400         Boolean icons_changed)
1401 {
1402    Arg args[8];
1403
1404    XtSetArg (args[0], DtNfileMgrRec, file_mgr_rec);
1405    XtSetArg (args[1], DtNcurrentDirectory, file_mgr_data->current_directory);
1406    XtSetArg (args[2], DtNlargeIcons, file_mgr_data->view == BY_NAME_AND_ICON);
1407    XtSetArg (args[3], DtNiconsChanged, icons_changed);
1408    XtSetArg (args[4], "statusMsg", !file_mgr_data->show_status_line);
1409    XtSetValues(file_mgr_rec->iconic_path_da, args, 5);
1410 }
1411