/*************************************************************************
 * File: $Source: /usr/usrs/xsource/xmfm/RCS/applicat.c,v $
 * Author: Jan Newmarch
 * Last modified: $Date: 1992/11/17 00:35:34 $
 * Version: $Revision: 1.10 $
 * Purpose: Create the application windows and set up callbacks
 *
 * Revision history:
 *	4 Aug 92	added filter stuff to ResetFilesInPanes
 *	4 Aug 92	added R5 hooks to allow editres to look at this applic
 *	5 Aug 92	put Toolbars in scrolled windows, 
 *			to stop clipping on resize
 *	5 Aug 92	set dir label above panes only, instead of across form
 *	6 Aug 92	removed scrolled windows from Toolbars,
 *			reset dir label as before. let left edge of
 *			toolbars be free
 *	16 Oct 92	caddr_t changed to XtPointer
 *       3 Nov 92       lint-ed
 *	11 Nov 92	follow symbolic links to show dirs as dirs, not files.
 *			Moved Rogers drag 'n drop to drag.c
 ************************************************************************/ 

#include "copyright.h"

/*************************************************************************
 * System includes
 ************************************************************************/ 
#include <sys/types.h>
#include <sys/stat.h>

/*************************************************************************
 * Local includes
 ************************************************************************/ 
#include "xmvararg.h"
#include "DirMgr.h"
#include "const.h"
#include "types.h"

#ifdef RDD
#include "rdd.h"
#endif /* RDD */

/*************************************************************************
 * Functions exported
 ************************************************************************/ 
extern Widget CreateApplication (
#ifdef UseFunctionPrototypes
	Widget parent
#endif
);
extern void ResetFilesInPanes (
#ifdef UseFunctionPrototypes
	dir_pane_info *dpi
#endif
);
extern void ClearToolbar (
#ifdef UseFunctionPrototypes
	Widget *toolbar
#endif
);

/*************************************************************************
 * Variables exported
 ************************************************************************/ 

/*************************************************************************
 * Extern functions
 ************************************************************************/ 
extern Widget CreateMenu (
#ifdef UseFunctionPrototypes
	Widget parent, XtPointer user_data
#endif
);
extern void FileButtonPressedCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);
extern void FileButtonReleasedCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);
extern void FileToolButtonPressedCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);

#ifdef ALLOW_EDITRES
extern void _XEditResCheckMessages ();
#endif /* ALLOW_EDITRES */

#ifdef MOTIF_DD
extern  void MotifDDRegisterToolbar (
#ifdef UseFunctionPrototypes
	Widget button
#endif
);
#endif /* MOTIF_DD */

#ifdef RDD
extern void DirDrop (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer call, XtPointer client_data
#endif
);
extern void ExecutableDrop (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer call, XtPointer client_data
#endif
);
extern void MainWindowDrop (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer call, XtPointer client_data
#endif
);
extern void ToolbarDrop (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer call, XtPointer client_data
#endif
);
#endif /* RDD */

/*************************************************************************
 * Extern variables
 ************************************************************************/ 
extern GC gc;
extern GC gc_reversed;
extern file_action *actions;

#ifdef RDD
extern XtTranslations trans_table;
#endif /* RDD */

#ifdef MOTIF_DD
extern XtTranslations trans_table;
#endif /* MOTIF_DD */

/*************************************************************************
 * Forward functions
 ************************************************************************/ 
Widget CreateApplication (
#ifdef UseFunctionPrototypes
	Widget parent
#endif
);	/*  create main window		*/ 
DirectoryMgr *GetFilesInDir (
#ifdef UseFunctionPrototypes
	void
#endif
);


/*************************************************************************
 * Local variables
 ************************************************************************/ 
XmString empty_string;


/* #define SIZE_KLUDGE */


/*************************************************************************
 * Function: SetGeometry ()
 * Purpose: set the geometry of components in the form
 * In parameters: directory_label, files_toolbar, dirs_toobar, pane
 * Function result:
 * Precondition: all args are non-null children of a form
 * Postcondition: all args are set in the following geometry
 *		--------------------------
 *             |               dir label  |
 *             |--------------------------|
 *             | files       |            |
 *             | toolbar     |  pane      |
 *             |-------------|            |
 *             | dirs        |            |
 *             | toolbar     |            |
 *              --------------------------
 ************************************************************************/ 
static void
SetGeometry 
#ifdef UseFunctionPrototypes
	(Widget directory_label, Widget files_toolbar, Widget dirs_toolbar, Widget pane)
#else
	(directory_label, files_toolbar, dirs_toolbar, pane)
	Widget directory_label;
	Widget files_toolbar;
	Widget dirs_toolbar;
	Widget pane;

#endif
{
	XtVaSetValues (directory_label,
			XmNtopAttachment,	(XtArgVal) XmATTACH_FORM,
			XmNleftAttachment,	(XtArgVal) XmATTACH_FORM,
			XmNrightAttachment,	(XtArgVal) XmATTACH_FORM,
			NULL);

	XtVaSetValues (files_toolbar,
			XmNtopAttachment,	(XtArgVal) XmATTACH_WIDGET,
			XmNtopWidget,		(XtArgVal) directory_label,
			XmNleftAttachment,	(XtArgVal) XmATTACH_FORM,
			XmNbottomAttachment,	(XtArgVal) XmATTACH_POSITION,
			XmNbottomPosition,	(XtArgVal) 45,
			NULL);

	XtVaSetValues (dirs_toolbar,
			XmNtopAttachment,	(XtArgVal) XmATTACH_POSITION,
			XmNtopPosition,		(XtArgVal) 50,
			XmNleftAttachment,	(XtArgVal) XmATTACH_FORM,
                        XmNbottomAttachment,    (XtArgVal) XmATTACH_FORM,
			NULL);

	XtVaSetValues (pane,
			XmNtopAttachment,	(XtArgVal) XmATTACH_WIDGET,
			XmNtopWidget,		(XtArgVal) directory_label,
			XmNleftAttachment,	(XtArgVal) XmATTACH_WIDGET,
			XmNleftWidget,		(XtArgVal) files_toolbar,
			XmNrightAttachment,	(XtArgVal) XmATTACH_FORM,
			XmNbottomAttachment,	(XtArgVal) XmATTACH_FORM,
			NULL);
}

/*************************************************************************
 * Function: CreateFilesToolbar ()
 * Purpose: create the files toolbar and populate it with toolbar buttons
 * In parameters: form, dpi
 * Function result: files toolbar widget
 * Precondition: form is non-null
 * Postcondition: toolbar + buttons created, each button has dpi in user data
 ************************************************************************/ 
static Widget
CreateFilesToolbar 
#ifdef UseFunctionPrototypes
	(Widget form, dir_pane_info *dpi)
#else
	(form, dpi)
	Widget form;
	dir_pane_info *dpi;

#endif
{
	Widget	button,
		files_toolbar,
		*files_toolbar_buttons;
	int 	i;
	tool_button_info *tbi;
		
	files_toolbar_buttons = (Widget *) XtMalloc (sizeof (Widget) *
						FILES_TOOLBAR_SIZE);
	dpi -> files_toolbar = files_toolbar_buttons;

	files_toolbar = XmVaCreateRowColumn (form, "files_toolbar",
			XmNpacking,		(XtArgVal) XmPACK_COLUMN,
			XmNorientation,		(XtArgVal) XmHORIZONTAL,
#ifdef SIZE_KLUDGE
			/* set to 4 when we only show 3 is because of
			   dummy widget in 4th row */
			XmNnumColumns, 		(XtArgVal) 4,
#else
                        XmNnumColumns,          (XtArgVal) 3,
#endif /*SIZE_KLUDGE*/
			XmNadjustLast,		(XtArgVal) False,
			NULL);
	XtManageChild (files_toolbar);

	for (i = 0; i < FILES_TOOLBAR_SIZE; i++)
	{
		tbi = (tool_button_info *) XtMalloc (sizeof (tool_button_info));
		tbi -> dpi = dpi;

		button =
		files_toolbar_buttons[i] =
			XmVaCreatePushButton (files_toolbar, "file_button",
				XmNlabelString, (XtArgVal) empty_string,
				XmNuserData, (XtArgVal) tbi,
				NULL);
		XtAddCallback (button,
			XmNactivateCallback, FileToolButtonPressedCB,
			NULL);
		XtManageChild (button);
		XtSetSensitive (button, False);

#ifdef RDD
		rddAddDropHandler (button,
				ToolbarDrop, NULL);
#endif /* RDD */

#ifdef MOTIF_DD
                MotifDDRegisterToolbar (button);
#endif /* MOTIF_DD */
	}

#ifdef SIZE_KLUDGE
	{	/* kludge to force the row column to give
		   us the size buttons we want.  It doesn't
		   tamper with the size of DrawButtons
		*/

	 	Widget dummy;
		dummy = XmVaCreateDrawnButton (files_toolbar, "dummy",
				XmNmappedWhenManaged, (XtArgVal) False,
				NULL);
		XtManageChild (dummy);
	}
#endif /*SIZE_KLUDGE */

	return files_toolbar;
}

/*************************************************************************
 * Function: ClearToolbar ()
 * Purpose: empty out the files toolbar of any actions
 * In parameters: toolbar
 * Function result: 
 * Precondition: 
 * Postcondition: all toolbar buttons show empty string
 ************************************************************************/ 
void
ClearToolbar 
#ifdef UseFunctionPrototypes
	(Widget *toolbar)
#else
	(toolbar)
	Widget *toolbar;

#endif
{
	int i;
	
	for (i = 0; i < FILES_TOOLBAR_SIZE; i++)
	{
		if ( !XtIsSensitive (*toolbar))
			return;	
		XtVaSetValues (*toolbar,
				XmNlabelString, empty_string,
				NULL);
		XtSetSensitive (*toolbar, False);
		toolbar++;
	}
}

/*************************************************************************
 * Function: CreateDirsToolbar ()
 * Purpose: create the dirs toolbar and populate it with toolbar buttons
 * In parameters: form, dpi
 * Function result: dirs toolbar widget
 * Precondition: form is non-null
 * Postcondition: toolbar + buttons created, each button has dpi in user data
 ************************************************************************/ 
static Widget
CreateDirsToolbar 
#ifdef UseFunctionPrototypes
	(Widget form, dir_pane_info *dpi)
#else
	(form, dpi)
	Widget form;
	dir_pane_info *dpi;

#endif
{
	Widget	button,
		dirs_toolbar,
		*dirs_toolbar_buttons;
	int	i;
	tool_button_info *tbi;

	dirs_toolbar_buttons = (Widget *) XtMalloc (sizeof (Widget) *
						DIRS_TOOLBAR_SIZE);
	dpi -> dirs_toolbar = dirs_toolbar_buttons;

	dirs_toolbar = XmVaCreateRowColumn (form, "dirs_toolbar",
			XmNpacking,		(XtArgVal) XmPACK_COLUMN,
			XmNorientation,		(XtArgVal) XmHORIZONTAL,
#ifdef SIZE_KLUDGE
			/* set to 4 when we only show 3 is because of
			   dummy widget in 4th row */
			XmNnumColumns, 		(XtArgVal) 4,
#else
                        XmNnumColumns,          (XtArgVal) 3,
#endif /*SIZE_KLUDGE*/
                        XmNadjustLast,           (XtArgVal) False,
			NULL);
	XtManageChild (dirs_toolbar);

	for (i = 0; i < DIRS_TOOLBAR_SIZE; i++)
	{	tbi = (tool_button_info *) XtMalloc (sizeof (tool_button_info));
		tbi -> dpi = dpi;

		button =
		dirs_toolbar_buttons[i] =
			XmVaCreatePushButton (dirs_toolbar, "dir_button",
				XmNlabelString, (XtArgVal) empty_string,
				XmNuserData, (XtArgVal) tbi,
				NULL);
		XtAddCallback (button,
			XmNactivateCallback, FileToolButtonPressedCB,
			NULL);
		XtManageChild (button);
		XtSetSensitive (button, False);

#ifdef RDD
		rddAddDropHandler (button,
				ToolbarDrop, NULL);
#endif /* RDD */

#ifdef MOTIF_DD
                MotifDDRegisterToolbar (button);
#endif /* MOTIF_DD */
	}

#ifdef SIZE_KLUDGE
	{	/* kludge to force the row column to give
		   us the size buttons we want.  It doesn't
		   tamper with the size of DrawButtons
		*/
	 	Widget dummy;
		dummy = XmVaCreateDrawnButton (dirs_toolbar, "dummy",
				XmNmappedWhenManaged, (XtArgVal) False,
				NULL);
		XtManageChild (dummy);
	}
#endif /*SIZE_KLUDGE*/

	return dirs_toolbar;
}

#ifdef ALLOW_ROWCOL_RESIZE

/*************************************************************************
 * Function: ScrolledWindowResized ()
 * Purpose: the scrolled window containing files has changed in size.
 *	Need to rearrange widgets in it.
 * In parameters: w, event, args, num_args
 * Function result: 
 * Precondition: 
 * Postcondition: number of columns is maximum for new width
 ************************************************************************/

/* ARGSUSED */ 
static void
ScrolledWindowResized 
#ifdef UseFunctionPrototypes
	(Widget w, XEvent *event, char **args, Cardinal *num_args)
#else
	(w, event, args, num_args)
	Widget w;
	XEvent *event;
	char **args;
	Cardinal *num_args;

#endif
{       Dimension pane_width, button_width;
        int num_columns;
        Widget button;
        dir_pane_info *dpi;
	XConfigureEvent *cevent = event;

#ifdef DEBUG
	fprintf (stderr, "resize on scrolled widget to width %d height %d\n",
			cevent -> width,
			cevent -> height);
#endif

        XtVaGetValues (w,
                        XmNuserData, &dpi,
                        XmNwidth, &pane_width,
                        NULL);

        /* find a non-null button, or give up */
        if (dpi -> files_buttons != NULL)
                button = dpi -> files_buttons -> widget;
        else if (dpi -> dirs_buttons != NULL)
                button = dpi -> dirs_buttons -> widget;

        else if (dpi -> executables_buttons != NULL)
                button = dpi -> executables_buttons -> widget;

        else return;

        XtVaGetValues (button, XmNwidth, &button_width, NULL);

#ifdef DEBUG
	fprintf (stderr, "Pane Width: %d\tButton Width: %d\n", pane_width,
			button_width);
#endif
        num_columns = (int) (pane_width / button_width);

#ifdef DEBUG
        fprintf (stderr, "number of columns in panes set to %d\n",
                        num_columns);
#endif /* DEBUG */

        /* set the numColumns in each pane */
        XtVaSetValues (dpi -> executables_pane,
                        XmNnumColumns, (XtArgVal) num_columns,
                        XmNpacking, (XtArgVal) XmPACK_COLUMN,
                        NULL);
        XtVaSetValues (dpi -> files_pane,
                        XmNnumColumns, (XtArgVal) num_columns,
                        XmNpacking, (XtArgVal) XmPACK_COLUMN,
                       NULL);
        XtVaSetValues (dpi -> dirs_pane,
                        XmNnumColumns, (XtArgVal) num_columns,
                        XmNpacking, (XtArgVal) XmPACK_COLUMN,
                        NULL);
}

#endif /* ALLOW_ROWCOL_RESIZE */

/*************************************************************************
 * Function: CreatePane ()
 * Purpose: create files, directories display area
 * In parameters: form, dpi
 * Function result: pane widget
 * Side effects; fields in dpi point to 3 pane children
 * Precondition: form is non-null
 * Postcondition: pane created with children in this geometric relation
 *                --------------
 *               | executables  |
 *               | pane         |
 *                --------------
 *               | files pane   |
 *                --------------
 *               | dirs pane    |
 *                --------------
 *		  except for OpenVMS which will have this geometric relation
 *                --------------
 *               | executables  |
 *               | pane         |
 *                --------------
 *               | dirs pane    |
 *                --------------
 *               | files pane   |
 *                --------------
 ************************************************************************/ 
static Widget
CreatePane 
#ifdef UseFunctionPrototypes
	(Widget form, dir_pane_info *dpi)
#else
	(form, dpi)
	Widget form;
	dir_pane_info *dpi;

#endif
{
	Widget	pane,
		dirs_pane,
		files_pane,
		executables_pane,
		rc1, rc2, rc3,
		file_filter_label,
		dir_filter_label,
		executable_filter_label,
		sw1, sw2, sw3;
	XtActionsRec actions_rec;
	XtTranslations trans_table;

#ifdef ALLOW_ROWCOL_RESIZE
	/* the action called by this is to allow the number of columns
	   to be dynamically reset when the enclosing pane is resized.
	   It throws up a RowCol bug under Motif 1.1.0
	*/
	/* we need to spot when the user horizontally resizes panes
	   to reset number of columns of files shown */
        actions_rec.string = "resize";
        actions_rec.proc = ScrolledWindowResized;

	XtAddActions (&actions_rec, 1);
	trans_table = XtParseTranslationTable ("<Configure>: resize()");
#endif /* ALLOW_ROWCOL_RESIZE */

	pane = XmVaCreatePanedWindow (form, "pane",
			NULL);

	/* create the executable files section */
	/* a row column of a label and a row column of drawn buttons */

	rc1 = XmVaCreatePanedWindow (pane, "exec_rc", 
                        XmNsashHeight, (XtArgVal) 1,
                        XmNseparatorOn, (XtArgVal) False,
                        XmNspacing, (XtArgVal) 0,
                        XmNuserData, (XtArgVal) dpi,
                        NULL);

	executable_filter_label = XmVaCreateLabel (rc1,
					"executable_filter_label",
					NULL);

	sw1 = XmVaCreateScrolledWindow (rc1, "exec_sw",
			XmNscrollingPolicy, (XtArgVal) XmAUTOMATIC,
                        XmNuserData, (XtArgVal) dpi,
			NULL);

#ifdef ALLOW_ROWCOL_RESIZE
	/* look for configure (resize) events on one of the panes */
	XtOverrideTranslations (sw1, trans_table);
#endif /* ALLOW_ROWCOL_RESIZE */

	executables_pane = XmVaCreateRowColumn (sw1, "executables_pane",
				       NULL);
	{	/* kludge to force the row column to give
		   us the size buttons we want.  It doesn't
		   tamper with the size of DrawButtons
		*/
	 	Widget dummy;
		dummy = XmVaCreateDrawnButton (executables_pane, "dumm",
				XmNmappedWhenManaged, (XtArgVal) False,
				NULL);
		XtManageChild (dummy);
		XtUnmanageChild (dummy);
	}
	XtVaSetValues (sw1,
			XmNworkWindow, (XtArgVal) executables_pane,
			NULL);

#ifdef vax11c
	/* create the directories section */
	/* a row column of a label and a row column (in a scrolled window)
	   of drawn buttons */

	rc3 = XmVaCreatePanedWindow (pane, "dir_rc", 
                        XmNsashHeight, (XtArgVal) 1,
                        XmNseparatorOn, (XtArgVal) False,
                        XmNspacing, (XtArgVal) 0,
                        NULL);

	dir_filter_label = XmVaCreateLabel (rc3,
					"dir_filter_label",
					NULL);

	sw3 = XmVaCreateScrolledWindow (rc3, "dir_sw",
			XmNscrollingPolicy, (XtArgVal) XmAUTOMATIC,
			NULL);

	dirs_pane = XmVaCreateRowColumn (sw3, "dirs_pane",
		 	NULL);

	XtVaSetValues (sw3,
			XmNworkWindow, (XtArgVal) dirs_pane,
			NULL);

	/* create the ordinary files section */
	/* a row column of a label and a row column of drawn buttons */

	rc2 = XmVaCreatePanedWindow (pane, "file_rc", 
                        XmNsashHeight, (XtArgVal) 1,
                        XmNseparatorOn, (XtArgVal) False,
                        XmNspacing, (XtArgVal) 0,
                        NULL);

	file_filter_label = XmVaCreateLabel (rc2,
					"file_filter_label",
					NULL);

	sw2 = XmVaCreateScrolledWindow (rc2, "file_sw",
			XmNscrollingPolicy, (XtArgVal) XmAUTOMATIC,
			NULL);

	files_pane = XmVaCreateRowColumn (sw2, "files_pane",
				          NULL);

	XtVaSetValues (sw2,
			XmNworkWindow, (XtArgVal) files_pane,
			NULL);

#else
	/* create the ordinary files section */
	/* a row column of a label and a row column of drawn buttons */

	rc2 = XmVaCreatePanedWindow (pane, "file_rc", 
                        XmNsashHeight, (XtArgVal) 1,
                        XmNseparatorOn, (XtArgVal) False,
                        XmNspacing, (XtArgVal) 0,
                        NULL);

	file_filter_label = XmVaCreateLabel (rc2,
					"file_filter_label",
					NULL);

	sw2 = XmVaCreateScrolledWindow (rc2, "file_sw",
			XmNscrollingPolicy, (XtArgVal) XmAUTOMATIC,
			NULL);

	files_pane = XmVaCreateRowColumn (sw2, "files_pane",
				          NULL);

	XtVaSetValues (sw2,
			XmNworkWindow, (XtArgVal) files_pane,
			NULL);

	/* create the directories section */
	/* a row column of a label and a row column (in a scrolled window)
	   of drawn buttons */

	rc3 = XmVaCreatePanedWindow (pane, "dir_rc", 
                        XmNsashHeight, (XtArgVal) 1,
                        XmNseparatorOn, (XtArgVal) False,
                        XmNspacing, (XtArgVal) 0,
                        NULL);

	dir_filter_label = XmVaCreateLabel (rc3,
					"dir_filter_label",
					NULL);

	sw3 = XmVaCreateScrolledWindow (rc3, "dir_sw",
			XmNscrollingPolicy, (XtArgVal) XmAUTOMATIC,
			NULL);

	dirs_pane = XmVaCreateRowColumn (sw3, "dirs_pane",
		 	NULL);

	XtVaSetValues (sw3,
			XmNworkWindow, (XtArgVal) dirs_pane,
			NULL);

#endif /* vax11c */

	XtManageChild (executables_pane);
	XtManageChild (executable_filter_label);
	XtManageChild (rc1);
	XtManageChild (sw1);

#ifdef vax11c
	XtManageChild (dirs_pane);
	XtManageChild (dir_filter_label);
	XtManageChild (rc3);
	XtManageChild (sw3);

	XtManageChild (files_pane);
	XtManageChild (file_filter_label);
	XtManageChild (rc2);
	XtManageChild (sw2);
#else
	XtManageChild (files_pane);
	XtManageChild (file_filter_label);
	XtManageChild (rc2);
	XtManageChild (sw2);

	XtManageChild (dirs_pane);
	XtManageChild (dir_filter_label);
	XtManageChild (rc3);
	XtManageChild (sw3);
#endif /* vax11c */

	dpi -> executables_pane = executables_pane;
	dpi -> files_pane = files_pane;
	dpi -> dirs_pane = dirs_pane;
        dpi -> file_filter_label = file_filter_label;
        dpi -> dir_filter_label = dir_filter_label;
        dpi -> executable_filter_label = executable_filter_label;

	return pane;
}

/*************************************************************************
 * Function: CreateApplication ()
 * Purpose: create a toplevel widget
 * In parameters: parent
 * Function result: toplevel widget in managed state
 * Precondition: parent is non-null widget
 * Postcondition: widget hierarchy set up and managed
 ************************************************************************/ 
Widget CreateApplication 
#ifdef UseFunctionPrototypes
	(Widget parent)
#else
	(parent)  
Widget		parent;		/*  parent widget	*/ 

#endif
{ 
	Widget		main,
			form,
			directory_label,
			pane,
			menu,
			dirs_toolbar,
			files_toolbar;
 
	char	str[128];
	DirectoryMgr *files;
	dir_pane_info *dpi;

#ifdef ALLOW_EDITRES
	XtAddEventHandler (parent, (EventMask) 0, True,
				_XEditResCheckMessages, NULL);
#endif

	empty_string = XmStringCreateSimple ("           ");

	dpi = (dir_pane_info *) XtMalloc (sizeof (dir_pane_info));

	main = XmVaCreateMainWindow (parent, "main", 
			XmNuserData, (XtArgVal) dpi,
			NULL);
#ifdef RDD
/*	seems to override other drops 
	rddAddDropHandler (main,
				MainWindowDrop, NULL);
*/
#endif /* RDD */

	form = XmVaCreateForm (main, "form",
			NULL);


	directory_label = XmVaCreateLabel (form, "directory_label",
					NULL);
	files_toolbar = CreateFilesToolbar (form, dpi);

	dirs_toolbar = CreateDirsToolbar (form, dpi);

	pane = CreatePane (form, dpi);

	files = GetFilesInDir ();
	dpi -> dirs_buttons = NULL;
	dpi -> files_buttons = NULL;
	dpi -> executables_buttons = NULL;

	menu = CreateMenu (main, (XtPointer) dpi);

	XtManageChild (menu);
	XtManageChild (dirs_toolbar);
	XtManageChild (files_toolbar);
	XtManageChild (pane);
	XtManageChild (directory_label);
	XtManageChild (form);
	XtManageChild (main);

	SetGeometry (directory_label, files_toolbar, dirs_toolbar, pane);

	/* set up the user data stuff */
	dpi -> directory_label = directory_label;
	dpi -> directory_manager = files;
	dpi -> file_selected = NULL;
	dpi -> file_button_selected = NULL;
	dpi -> dir_selected = NULL;
	dpi -> executable_selected = NULL;
	dpi -> toplevel = parent;
        dpi -> run_dialog = NULL;
        dpi -> info_dialog = NULL;

	XmMainWindowSetAreas (main, menu, NULL, NULL, NULL, form);

	return (main);
} 


/*************************************************************************
 * Function: GetFilesInDir ()
 * Purpose: return a list of files in current directory
 * Function result: list of files
 * Precondition: none
 * Postcondition: list of files returned
 ************************************************************************/ 
DirectoryMgr *GetFilesInDir 
#ifdef UseFunctionPrototypes
	(void)
#else
	()

#endif
{
        DirectoryMgr *dm;
	char path[MAXPATHLEN];

	getcwd (path, MAXPATHLEN);

	dm = DirectoryMgrSimpleOpen(path,DIR_MGR_SORT_NAME_DIRS_FIRST, (char *)NULL);
        if (dm == NULL)
        {
                fprintf(stderr,"Can't open directory mgr for '%s'\n",path);
                exit(-1);
        }
	return (dm);
}

#ifdef OLD_CODE
/*************************************************************************
 * Function: SetFilesInPane ()
 * Purpose: Set up the file names in buttons in each of the panes
 * In parameters: dm, dirs_pane, executables_pane, files_pane, dpi
 * Out parameters: dpi contents changed by indirection
 * Precondition: directory list in dm, 3 non-null pane widgets,
 *               dpi points to existing structure
 * Postcondition: some fields in dpi filled in, panes populated with
 *                buttons of file names
 ************************************************************************/ 
int
SetFilesInPanes (dm, dirs_pane, executables_pane, files_pane, dpi)
	DirectoryMgr *dm;
	Widget dirs_pane;
	Widget files_pane;
	dir_pane_info *dpi;
{
        DirEntry *de;
	Widget button;
	aWidgetList *dbi, *fbi, *xbi;
	pane_button_info *pbi;

	while (1)
        {
                de = DirectoryMgrNextEntry(dm);
                if (de == NULL) break;

		pbi = (pane_button_info *)
			XtMalloc (sizeof (pane_button_info));
		pbi -> name = de -> filename;
		pbi -> dpi = dpi;


		/* place dirs in dir pane */
		if (DirEntryIsDir (de) ||
			DirEntryIsSymLink (de) &&
				S_ISDIR (FileInfoOrigMode (DirEntryActualInfo (de))))
		{
			pbi -> file_type = DIR_TYPE;
			button = XmVaCreatePushButton (dirs_pane,
					de -> filename,
					XmNuserData, (XtArgVal) pbi,
					NULL);
			/* link into list */
			if (dpi -> dirs_buttons == NULL)
			{	dpi -> dirs_buttons =
				dbi = (aWidgetList *)
					XtMalloc (sizeof (aWidgetList));
			} else {
				dbi -> next = (aWidgetList *)
						 XtMalloc (sizeof (aWidgetList));
				dbi = dbi -> next;
			}
			dbi -> widget = button;
			dbi -> next = NULL;

			XtAddCallback (button, XmNarmCallback,
						FileButtonPressedCB,
						NULL);
			XtAddCallback (button,
				XmNactivateCallback, FileButtonReleasedCB,
				NULL);
		}
		/* and executables in executables pane */
		else if ((FileInfoProt( DirEntryActualInfo (de))
				& (S_IXUSR | S_IXOTH | S_IXGRP)) != 0)
		{
			pbi -> file_type = EXECUTABLE_TYPE;
			button = XmVaCreatePushButton (executables_pane,
					de -> filename,
					XmNuserData, (XtArgVal) pbi,
					NULL);
			/* link into list */
			if (dpi -> executables_buttons == NULL)
			{	dpi -> executables_buttons =
				xbi = (aWidgetList *)
					XtMalloc (sizeof (aWidgetList));
			} else {
				xbi -> next = (aWidgetList *)
						 XtMalloc (sizeof (aWidgetList));
				xbi = xbi -> next;
			}
			xbi -> widget = button;
			xbi -> next = NULL;

			XtAddCallback (button, XmNarmCallback,
						FileButtonPressedCB,
						NULL);
			XtAddCallback (button,
				XmNactivateCallback, FileButtonReleasedCB,
				NULL);
		}
		/* everything else in files pane */
		else
		{
			pbi -> file_type = FILE_TYPE;
			button = XmVaCreatePushButton (files_pane,
					de -> filename,
					XmNuserData, (XtArgVal) pbi,
					NULL);

			/* link into list */
			if (dpi -> files_buttons == NULL)
			{	dpi -> files_buttons =
				fbi = (aWidgetList *)
					XtMalloc (sizeof (aWidgetList));
			} else {
				fbi -> next = (aWidgetList *)
						 XtMalloc (sizeof (aWidgetList));
				fbi = fbi -> next;
			}
			fbi -> widget = button;
			fbi -> next = NULL;
			XtAddCallback (button, XmNarmCallback,
						FileButtonPressedCB,
						NULL);
			XtAddCallback (button,
				XmNactivateCallback, FileButtonReleasedCB,
				NULL);
		}
		XtManageChild (button);
        }
}
#endif /* OLD_CODE */


/*************************************************************************
 * Function: DrawnButtonExposedCB ()
 * Purpose: handle expose events on file buttons
 * In parameters: button, client_data, call_data
 * Function returns:
 * Precondition: expose event generated for w
 * Postcondition: label redrawn
 *************************************************************************/
/* ARGSUSED */
void
DrawnButtonExposedCB 
#ifdef UseFunctionPrototypes
	(Widget button, XtPointer client_data, XtPointer call_data)
#else
	(button, client_data, call_data)
	Widget button;
	XtPointer client_data, call_data;

#endif
{	pane_button_info *pbi;
	Dimension width, height, new_width;
	GContext gcid;
	XFontStruct *xfstr;

	/*
	 *	Retrieve require info from the widget
	 */ 
	XtVaGetValues (button,
			XmNuserData, (XtArgVal) &pbi,
			XmNwidth, (XtArgVal) &width,
			XmNheight, (XtArgVal) &height,
			NULL);

	/*
	 *	Check and enlarge the button iff the
	 *	text string is too long
	 */
	gcid = XGContextFromGC(pbi->gc);

 	xfstr = XQueryFont(XtDisplay(button), gcid);

	new_width = XTextWidth(xfstr, pbi -> name, strlen(pbi -> name));

#ifdef DEBUG
	fprintf (stderr, "Old Width: %d\tPurposed New Width: %d\n",
			width, new_width);
#endif

	if (width < new_width) {
		XtVaSetValues(button,
				XmNwidth, (XtArgVal) new_width,
				NULL);
	}

	/*
	 *	Display the filename
	 */
	XDrawImageString (XtDisplay (button),
			XtWindow (button),
			pbi -> gc, 0, (int) height - 5, 
			pbi -> name,
			strlen (pbi -> name));
}

/*************************************************************************
 * Function: set_pixmap ()
 * Purpose: set the visual pixmap for this file type
 * In parameters: button, name, file_type
 * Function returns:
 * Side effects: pbi for this button has pixmap, insensitive_pixmap set
 * Precondition: none 
 * Postcondition: pixmap set as labelPixmap resource
 *************************************************************************/
static void
set_pixmap 
#ifdef UseFunctionPrototypes
	(Widget button, char *name, char file_type)
#else
	(button, name, file_type)
	Widget button;
	char *name;
	char file_type;

#endif
{
	Pixmap pixmap, pixmap_reversed;
	file_action *pfa;
	Pixel fg, bg;
	pane_button_info *pbi;
#ifdef vax11c
	char pixmap_full_name[256], temp_file_name[256];
	static char *pixmap_location = NULL;
#endif /* vax11c */

	/* find existing colours used in button */
	XtVaGetValues (button,
			XmNforeground, &fg,
			XmNbackground, &bg,
			NULL);

#ifdef vax11c
	/*
	 *	If this is the "[-]" equivalent to ".." then
	 *	substitue a dummy name to allow the regular expression
	 *	to match to the correct pixmap
	 */
	if (!strcmp(name, "[-]"))
		strcpy(temp_file_name, "VMS_UNIX_DIR_HACK.DIR;1");
	else
		strcpy(temp_file_name, name);
#endif /* vax11c */
        /* find file pattern matching this name */
        pfa = actions;
        while (pfa != NULL) {
                if (pfa -> file_type == file_type &&
#ifdef vax11c
                        RegExpMatch (temp_file_name, pfa -> fsm_ptr))
#else
                        RegExpMatch (name, pfa -> fsm_ptr))
#endif /* vax11c */
                        break;
                else    pfa = pfa -> next;
	}

        if (pfa == NULL)
        {
		fprintf (stderr, "cant find pattern for %s\n", name);
		return;
        }

	/* destroy old pixmaps */
	XtVaGetValues (button,
			XmNuserData, (XtArgVal) &pbi,
			NULL);
	XmDestroyPixmap (XtScreen (button), pbi -> pixmap);
	XmDestroyPixmap (XtScreen (button), pbi -> pixmap_reversed);

#ifdef vax11c
	{
		register char *ep;

		if (pixmap_location == NULL)
			pixmap_location = getenv("XMFM_PIXMAPS");
		if (!pixmap_location) {
			fprintf(stderr, "Missing logical XMFM_PIXMAPS, please define to be the location of the XMFM Pixmaps\n");
			exit(1);
		}
		ep = (char *)strrchr(pfa->pixmap, ':');
		if (!ep) {
			strcpy(pixmap_full_name, pixmap_location);
			strcat(pixmap_full_name, pfa->pixmap);
		} else {
			strcpy(pixmap_full_name, pfa->pixmap);
		}
	}
#endif /* vax11c */

#ifdef DEBUG
	fprintf(stderr, "Locating Pixmap \"%s\" for file \"%s\"\n", pixmap_full_name, name);
#endif /* DEBUG */

	/* find the pixmap for this file */
	pixmap = XmGetPixmap ( XtScreen (button),
#ifdef vax11c
				pixmap_full_name, fg, bg);
#else
				pfa -> pixmap, fg, bg);
#endif /* vax11c */
	pixmap_reversed = XmGetPixmap ( XtScreen (button),
#ifdef vax11c
				pixmap_full_name, bg, fg);
#else
				pfa -> pixmap, bg, fg);
#endif /* vax11c */

	if (pixmap == XmUNSPECIFIED_PIXMAP)
#ifdef vax11c
	{	fprintf (stderr, "cant find pixmap %s\n", pixmap_full_name);
#else
	{	fprintf (stderr, "cant find pixmap %s\n", pfa -> pixmap);
#endif /* vax11c */
		/* reasonable default */
		pixmap = XmGetPixmap ( XtScreen (button),
#ifdef vax11c
					"xmfm_pixmaps:xlogo32.xbm", fg, bg);
#else
					"xlogo32", fg, bg);
#endif /* vax11c */
		pixmap_reversed = XmGetPixmap ( XtScreen (button),
#ifdef vax11c
					"xmfm_pixmaps:xlogo32.xbm", bg, fg);
#else
					"xlogo32", bg, fg);
#endif /* vax11c */
	}
		
	XtVaSetValues (button,
			XmNlabelPixmap, (XtArgVal) pixmap,
			NULL);
	pbi -> pixmap = pixmap;
	pbi -> pixmap_reversed = pixmap_reversed;
}

/*************************************************************************
 * Function: new_pane_button ()
 * Purpose: crete a new button in one of the panes
 * In parameters: de, dpi, file_type
 * Function returns: new node of a widget list 
 * Precondition: 
 * Postcondition: new node created with callbacks set
 *************************************************************************/
#ifdef UseFunctionPrototypes
aWidgetList *new_pane_button (char *filename, char *button_name, dir_pane_info *dpi, Widget parent, char file_type)
#else
aWidgetList *new_pane_button (filename, button_name, dpi, parent, file_type)
	char *filename;
	char *button_name;
	dir_pane_info *dpi;
	Widget parent;
	char file_type;
#endif
{
	pane_button_info *pbi;
	Widget button;
	aWidgetList *dbi;
	static Pixmap label_bug_pixmap = NULL;

	/* set information needed for this button */
	pbi = (pane_button_info *)
		XtMalloc (sizeof (pane_button_info));
	pbi -> name = filename;
	pbi -> dpi = dpi;
	pbi -> file_type = file_type;
	pbi -> pixmap = XmUNSPECIFIED_PIXMAP;
	pbi -> pixmap_reversed = XmUNSPECIFIED_PIXMAP;
	pbi -> gc = gc;
	pbi -> gc_reversed = gc_reversed;

	/* if recompute_size == True, and we don't have a pixmap
	   set at create time, then it always takes its size as 0x0.
	   This is (at least) a Motif 1.1.0 fix, that sets a dummy one
	*/
	if (label_bug_pixmap == NULL)
	{	Pixel fg, bg;

		XtVaGetValues (parent,
				XmNforeground, (XtArgVal) &fg,
				XmNbackground, (XtArgVal) &bg,
				NULL);
		label_bug_pixmap = XmGetPixmap (XtScreen (parent),
#ifdef vax11c
					"xmfm_pixmaps:xlogo32.xbm", bg, fg);
#else
					"xlogo32", bg, fg);
#endif /* vax11c */
	}

	button = XmVaCreateDrawnButton (parent,
				button_name,
				XmNuserData, (XtArgVal) pbi,
				XmNlabelType, (XtArgVal) XmPIXMAP,
				XmNlabelPixmap, (XtArgVal) label_bug_pixmap,
				XmNmultiClick, (XtArgVal) XmMULTICLICK_KEEP,
				XmNrecomputeSize, (XtArgVal) False,
#ifdef RDD
				XmNtranslations, (XtArgVal) trans_table,
#endif /* RDD */
#ifdef MOTIF_DD
				XmNtranslations, (XtArgVal) trans_table,
#endif /* MOTIF_DD */
				NULL);
	/* create a new node for list */
	dbi = (aWidgetList *)
			XtMalloc (sizeof (aWidgetList));
	dbi -> widget = button;
	dbi -> next = NULL;

	XtAddCallback (button, XmNarmCallback,
				FileButtonPressedCB,
				NULL);
	XtAddCallback (button, XmNactivateCallback,
				FileButtonReleasedCB,
				NULL);
	XtAddCallback (button, XmNexposeCallback,
				DrawnButtonExposedCB,
				NULL);
	XtManageChild (button);

	set_pixmap (button, pbi -> name, file_type);


	return dbi;
}

/*************************************************************************
 * Function: reset_label ()
 * Purpose: change the label in a widget
 * In parameters: w, label
 * Out parameters: 
 * Precondition: w is a child of Label.
 * Postcondition: w has label set
 *************************************************************************/
void
reset_label 
#ifdef UseFunctionPrototypes
	(Widget w, char *label, char file_type)
#else
	(w, label, file_type)
	Widget w;
	char * label;
	char file_type;

#endif
{	XmString xmstr;
	pane_button_info *pbi;

	/* reset the label in the button */
	xmstr = XmStringCreateSimple (label);
	XtVaSetValues (w,
			XmNlabelString, (XtArgVal) xmstr,
			NULL);
	XmStringFree (xmstr);

	/* reset the name in the button info */
	XtVaGetValues (w, XmNuserData, &pbi, NULL);
	pbi -> name = label;

	set_pixmap (w, label, file_type);
}

/*************************************************************************
 * Function: SetDirectoryLabel ()
 * Purpose: set the current dir path in the Label widget showing above panes
 * In parameters:  dir_label, dm
 * Out parameters: 
 * Precondition: 
 * Postcondition: labelString in dir_label set to current dir
 ************************************************************************/ 
static void
SetDirectoryLabel 
#ifdef UseFunctionPrototypes
	(Widget dir_label, DirectoryMgr *dm)
#else
	(dir_label, dm)
	Widget dir_label;
	DirectoryMgr *dm;

#endif
{
	char *dir;
	XmString xmdir;
	char full_dir[MAXPATHLEN];

	dir = DirectoryPath (DirectoryMgrDir (dm));
	strcpy (full_dir, "Directory: ");
	strcat (full_dir, dir);
	xmdir = XmStringCreateSimple (full_dir);
	XtVaSetValues (dir_label,
			XmNlabelString, xmdir,
			NULL);
	XmStringFree (xmdir);
}


/*************************************************************************
 * Function: ResetFilesInPane ()
 * Purpose: Set up the file names in buttons in each of the panes
 * In parameters:  dpi
 * Out parameters: dpi contents changed by indirection
 * Precondition: directory list in dm, 3 non-null pane widgets,
 *               dpi points to existing structure
 * Postcondition: some fields in dpi filled in, panes populated with
 *                buttons of file names
 ************************************************************************/ 
void
ResetFilesInPanes 
#ifdef UseFunctionPrototypes
	(dir_pane_info *dpi)
#else
	(dpi)
	dir_pane_info *dpi;

#endif
{
	DirectoryMgr *dm;
        DirEntry *de;
	aWidgetList *dbi, *fbi, *xbi;
	Bool first_dbi = True;
	Bool first_fbi = True;
	Bool first_xbi = True;

	dm = dpi -> directory_manager;
	dbi = dpi -> dirs_buttons;
	fbi = dpi -> files_buttons;
	xbi = dpi -> executables_buttons;

	SetDirectoryLabel (dpi -> directory_label, dm);

	/* turn off visibility to stop flickering */
	XtUnmapWidget (XtParent (dpi -> files_pane));
	XtUnmapWidget (XtParent (dpi -> executables_pane));
	XtUnmapWidget (XtParent (dpi -> dirs_pane));

        /* ensure we are at the beginning of the directory list */
        DirectoryMgrRestart (dm);

	while ( (de = DirectoryMgrNextEntry(dm)) != NULL)
        {
		/* explanation of grotty code:
		   there are three lists of buttons, and buttons are
		   added to or modified in each list.  A procedure is
		   not used because parameterisation looks grotty.
		   For each list, there are four cases, like this:

		   if list is NULL, create new button, with trailing
			pointer set to it
		   else if list is non-NULL, but you are at the beginning,
				change the label of first button
				and keep the pointer set to it
		   else if next button is NULL, create next button and set
				pointer to it
		   else move to next button and change its label
		*/

#ifdef DEBUG
		fprintf(stderr, "Placing file \"%s\"\n", DirEntryFileName(de));
#endif /* DEBUG */

		/* place dirs in dir pane */
		if (DirEntryIsDir (de) ||
			DirEntryIsSymLink (de) &&
				S_ISDIR (FileInfoOrigMode (DirEntryActualInfo (de))))
		{
#ifdef vax11c
			char temp_dir_name[256];

			/*
			 *	Hack to allow inclusion of "[-]" which is the
			 *	VMS equivalent of the Unix "..".  This is to
			 *	allow for the reqular expression parser to
			 *	pass on this.
			 */
			if (!strcmp(DirEntryFileName(de), "[-]"))
				strcpy(temp_dir_name, "VMS_UNIX_DIR_HACK.DIR;1");
			else
				strcpy(temp_dir_name, DirEntryFileName(de));

			/* does it match pattern? else discard it */
			if ( !RegExpMatch (temp_dir_name,
					dpi -> dir_filter_regexp))
				continue;
#else
			/* does it match pattern? else discard it */
			if ( !RegExpMatch (DirEntryFileName (de),
					dpi -> dir_filter_regexp))
				continue;
#endif /* vax11c */

			if (dpi -> dirs_buttons == NULL) 
			{	/* create another button with its info */
				dpi -> dirs_buttons =
				dbi = new_pane_button (de -> filename,
							"dir_pane_button", dpi,
							dpi -> dirs_pane,
							DIR_TYPE);
#ifdef RDD
				rddAddDropHandler (dbi -> widget,
					DirDrop, NULL);
#endif /* RDD */
				first_dbi = False;
			}
			else if (first_dbi)
			{	reset_label (dbi -> widget,
						de -> filename,
						DIR_TYPE);
				first_dbi = False;
				XtManageChild (dbi -> widget);
			}
			else if (dbi -> next == NULL)
			{
				dbi -> next = new_pane_button (de -> filename,
							"dir_pane_button",
							dpi,
							dpi -> dirs_pane,
							DIR_TYPE);
				dbi = dbi -> next;
#ifdef RDD
				rddAddDropHandler (dbi -> widget,
					DirDrop, NULL);
#endif /* RDD */
			} else
			{
				dbi = dbi -> next;
				reset_label (dbi -> widget,
						de -> filename,
						DIR_TYPE);
				/* in case it was unmanaged by earlier dir change */
				XtManageChild (dbi -> widget);
			}
		}
#ifdef vax11c
		/* under vms, executables are ident by .EXE not by protections */
		else if ( RegExpMatch(DirEntryFileName (de),
					dpi -> executable_filter_regexp))
#else
		/* and executables in executables pane */
		else if ((FileInfoOrigMode( DirEntryActualInfo (de))
				& (S_IXUSR | S_IXOTH | S_IXGRP)) != 0)
#endif /* vax11c */
		{
#ifndef vax11c
			/* does it match pattern? else discard it */
			if ( !RegExpMatch (DirEntryFileName (de),
					dpi -> executable_filter_regexp))
				continue;
#endif /* vax11c */

			if (dpi -> executables_buttons == NULL) 
			{	/* create another button with its info */
				dpi -> executables_buttons =
				xbi = new_pane_button (de -> filename,
							"exec_pane_button", dpi,
							dpi -> executables_pane,
							EXECUTABLE_TYPE);
#ifdef RDD
				rddAddDropHandler (xbi -> widget,
					ExecutableDrop, NULL);
#endif /* RDD */
				first_xbi = False;
			}
			else if (first_xbi)
			{	reset_label (xbi -> widget,
						de -> filename,
						EXECUTABLE_TYPE);
				first_xbi = False;
				XtManageChild (xbi -> widget);
			}
			else if (xbi -> next == NULL)
			{
				xbi -> next = new_pane_button (de -> filename,
							"exec_pane_button",
							dpi,
							dpi -> executables_pane,
							EXECUTABLE_TYPE);
				xbi = xbi -> next;
#ifdef RDD
				rddAddDropHandler (xbi -> widget,
					ExecutableDrop, NULL);
#endif /* RDD */
			} else
			{
				xbi = xbi -> next;
				reset_label (xbi -> widget,
						de -> filename,
						EXECUTABLE_TYPE);

				/* in case it was unmanaged by earlier dir change */
				XtManageChild (xbi -> widget);
			}
		}
		/* everything else in files pane */
		else
		/* does it match pattern? else discard it */
		if (RegExpMatch (DirEntryFileName (de),
				dpi -> file_filter_regexp))
		{
			if (dpi -> files_buttons == NULL) 
			{	/* create another button with its info */
				dpi -> files_buttons =
				fbi = new_pane_button (de -> filename,
							"file_pane_button", dpi,
							dpi -> files_pane,
							FILE_TYPE);
				first_fbi = False;
			}
			else if (first_fbi)
			{	reset_label (fbi -> widget,
						de -> filename,
						FILE_TYPE);
				first_fbi = False;
				XtManageChild (fbi -> widget);
			}
			else if (fbi -> next == NULL)
			{
				fbi -> next = new_pane_button (de -> filename,
							"file_pane_button",
							dpi,
							dpi -> files_pane,
							FILE_TYPE);
				fbi = fbi -> next;
			} else
			{
				fbi = fbi -> next;
				reset_label (fbi -> widget,
						de -> filename,
						FILE_TYPE);
				XtManageChild (fbi -> widget);
			}
		}
        }
	/* if the new lists are shorter than the old ones, there will
	   be buttons left over that should have no contents. They
	   have to be unmanaged. First, advance trailing pointers */
	if (!first_dbi && dbi != NULL) dbi = dbi -> next;
	if (!first_xbi && xbi != NULL) xbi = xbi -> next;
	if (!first_fbi && fbi != NULL) fbi = fbi -> next;

	while (dbi != NULL)
	{
		XtUnmanageChild (dbi -> widget);
		dbi = dbi -> next;
	}
	while (xbi != NULL)
	{
		XtUnmanageChild (xbi -> widget);
		xbi = xbi -> next;
	}
	while (fbi != NULL)
	{
		XtUnmanageChild (fbi -> widget);
		fbi = fbi -> next;
	}

 
	/* turn visibility back on for panes */
	XtMapWidget (XtParent (dpi -> files_pane));
	XtMapWidget (XtParent (dpi -> executables_pane));
	XtMapWidget (XtParent (dpi -> dirs_pane));
}
