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