/*************************************************************************
 * File: $Source: /usr/usrs/xsource/xmfm/RCS/runcb.c,v $
 * Author: Jan Newmarch
 * Last modified: $Date: 1992/11/10 05:12:41 $
 * Version: $Revision: 1.6 $
 * Purpose: This file handles the run operations from the system menu
 *
 * Revision history:
 *      22 Aug 92      Separate run dialogs per pane (needed in case a pane
 *                     gets iconified or destroyed
 *	16 Oct 92	caddr_t changed to XtPointer
 *       3 Nov 92      lint-ed
 ************************************************************************/ 

#include "copyright.h"

/*************************************************************************
 * System includes
 ************************************************************************/ 
#include <stdlib.h>
#include <stdio.h> 

#include <Xm/CascadeB.h>     
#include <Xm/FileSB.h>      
#include <Xm/Label.h>
#include <Xm/PushB.h>    
#include <Xm/RowColumn.h>    
#include <Xm/SelectioB.h>    

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

/*************************************************************************
 * Functions exported
 ************************************************************************/ 
extern void RunCommandCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);
extern void RunXtermCB (
#ifdef UseFunctionPrototypes
	Widget w, XtPointer client_data, XtPointer call_data
#endif
);

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

/*************************************************************************
 * Extern variables
 ************************************************************************/ 

/*************************************************************************
 * Extern functions
 ************************************************************************/ 
extern void GotoCurrentDir (
#ifdef UseFunctionPrototypes
	Widget w
#endif
);
#ifdef vax11c
extern void do_command (
#ifdef UseFunctionPrototypes
	char *command, int refresh_dir, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi
#endif
);
#else
extern void do_command (
#ifdef UseFunctionPrototypes
	char *command, int run_in_xterm, int pause_after_exec, dir_pane_info *dpi
#endif
);
#endif /* vax11c */

/*************************************************************************
 * Forward functions
 ************************************************************************/ 

/*************************************************************************
 * Local variables
 ************************************************************************/ 
#ifdef vax11c
static Bool refresh_dir = False;
#endif /* vax11c */
static Bool run_in_xterm = False;
static Bool pause_after_exec = False;

#define LIST_SIZE 10

#define min(x,y)	((x) < (y) ? (x) : (y))

/*************************************************************************
 * Function: ButtonToggledCB ()
 * Purpose: a check button has been changed
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition; 
 * Postcondition: appropriate Boolean for Check box is updated
 ************************************************************************/

/* ARGSUSED */ 
static void
ButtonToggledCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)
	Widget w;
	XtPointer client_data;
	XtPointer call_data;

#endif
{
	/* toggle value of correct Boolean */
	if ( (int) client_data == 0)
		run_in_xterm = (run_in_xterm ? False : True);
	else 	pause_after_exec = (pause_after_exec ? False : True);
}

/*************************************************************************
 * Function: OkCB ()
 * Purpose: run the command entered
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition: Ok button pressed in Command dialog
 * Postcondition: user command executed, dialog killed
 ************************************************************************/ 

/* ARGSUSED */
static void
OkCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)
	Widget w;
	XtPointer client_data;
	XtPointer call_data;

#endif
{
	XmString xmstr_command;
	String command;
	int i, new_size, curr_size;
	XmString new_list[LIST_SIZE], *curr_list;
        dir_pane_info *dpi;

	XtVaGetValues (w,
			XmNtextString, &xmstr_command,
                        XmNuserData, &dpi,
			NULL);
	XmStringGetLtoR (xmstr_command, XmSTRING_DEFAULT_CHARSET, &command);

#ifdef vax11c
	do_command (command, refresh_dir, run_in_xterm, pause_after_exec, dpi);
#else
	do_command (command, run_in_xterm, pause_after_exec, dpi);
#endif /* vax11c */
	
	XtFree (command);

	XtUnmanageChild (w);

	/* before we leave this: add the command into the list of
	  previous commands, as long as it isn't already there */
	XtVaGetValues (w,
			XmNlistItems, &curr_list,
			XmNlistItemCount, &curr_size,
			NULL);
	for (i = 0; i < curr_size; i++)
		if (XmStringCompare (xmstr_command, curr_list[i]))
			/* already in list */
			return;
	/* new elmt. put in front, and shuffle up the rest */
	new_list[0] = xmstr_command;
	new_size = min (curr_size + 1, LIST_SIZE);
	for (i = 1; i < new_size; i++)
		new_list[i] = XmStringCopy (curr_list[i - 1]);
	XtVaSetValues (w,
			XmNlistItems, new_list,
			XmNlistItemCount, (XtArgVal) new_size,
			NULL);
	/* and garbage collect */
/*
	for (i = 0; i < new_size; i++)
		XmStringFree (new_list[i]);
*/
}

/*************************************************************************
 * Function: RunCommandCB ()
 * Purpose: run a user command in current dir
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition; Command button pressed in Run menu
 * Postcondition: user command dialog showing
 ************************************************************************/ 

/* ARGSUSED */
void
RunCommandCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)  
	Widget		w;		/*  widget id		*/ 
	XtPointer		client_data;	/*  data from applicaiton   */ 
	XtPointer		call_data;	/*  data from widget class  */ 

#endif
{	 
	dir_pane_info *dpi;
	Widget	run_command;
	Widget	rowcol;
	XmString xmstr_buttons[2];
	XmString xmstr_prompt;
	Widget help_button, apply_button;
	static XmString null_str;

	GotoCurrentDir (w);

        XtVaGetValues (w, XmNuserData, &dpi, NULL);
        run_command = dpi -> run_dialog;
	/* create new dialog if not already existing */
	if (run_command == NULL)
	{
		xmstr_prompt = XmStringCreateSimple ("Enter run command:");
		run_command = XmVaCreateSelectionDialog (w,
					"run command",
					XmNpromptString, xmstr_prompt,
					NULL);
                /* save this back into dpi */
                dpi -> run_dialog = run_command;

		XmStringFree (xmstr_prompt);

		XtAddCallback (run_command, XmNokCallback, OkCB, NULL);
		/* no cancel callback - default pops it down */

		/* remove the help and cancel */
		help_button = XmSelectionBoxGetChild (run_command, 
				XmDIALOG_HELP_BUTTON);
		XtUnmanageChild (help_button);
		apply_button = XmSelectionBoxGetChild (run_command, 
				XmDIALOG_APPLY_BUTTON);
		XtUnmanageChild (apply_button);
	
		xmstr_buttons[0] = XmStringCreateSimple ("Run in xterm");
		xmstr_buttons[1] = XmStringCreateSimple ("Pause after exec");
	
		null_str = XmStringCreateSimple ("");

		rowcol = XmVaCreateSimpleCheckBox (run_command, "rowcol",
				ButtonToggledCB,
				XmNbuttonCount, (XtArgVal) 2,
				XmNbuttons, xmstr_buttons,
				XmVaCHECKBUTTON, xmstr_buttons[0],
					NULL, NULL, NULL,
				XmVaCHECKBUTTON, xmstr_buttons[1],
					NULL, NULL, NULL,
				NULL);
		XtManageChild (rowcol);

		XmStringFree (xmstr_buttons[0]);
		XmStringFree (xmstr_buttons[1]);
	}

	/* ensure text field is empty for new command */
/*	both these methods dump core
	XtVaSetValues (w,
			XmNtextString, null_str,
			NULL);
	XmCommandSetValue (w, null_str);
*/

        XtVaSetValues (run_command, XmNuserData, dpi, NULL);
      	XtManageChild (run_command);
}
 
/*************************************************************************
 * Function: RunXtermCB()
 * Purpose: run a new xterm
 * In parameters: w, client_data, call_data
 * Out parameters:
 * Precondition; Xterm selected from Run menu
 * Postcondition: new xterm running
 ************************************************************************/ 

/* ARGSUSED */
void
RunXtermCB 
#ifdef UseFunctionPrototypes
	(Widget w, XtPointer client_data, XtPointer call_data)
#else
	(w, client_data, call_data)  
	Widget		w;		/*  widget id		*/ 
	XtPointer		client_data;	/*  data from applicaiton   */ 
	XtPointer		call_data;

#endif
{
        dir_pane_info *dpi;

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

	GotoCurrentDir (w);

#ifdef DEBUG
	fprintf (stderr, "xterm, display is %s\n",
		DisplayString (XtDisplay (w));
#endif
#ifdef vax11c
	do_command ("create/term/detach", False, False, False, dpi);
#else
	do_command ("xterm", False, False, dpi);
#endif /* vax11c */
}

