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