
 /*
  * Khoros: $Id: form_util.c,v 1.5 1992/03/20 22:47:52 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: form_util.c,v 1.5 1992/03/20 22:47:52 dkhoros Exp $";
#endif

 /*
  * $Log: form_util.c,v $
 * Revision 1.5  1992/03/20  22:47:52  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "forms.h"
#include "jp.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>		       Form  Utility Routines                 <<<<
   >>>>                                                       <<<<
   >>>>                xvf_get_line_type()                    <<<<
   >>>>                xvf_reverse_colors()		      <<<<
   >>>>		       xvf_lower()			      <<<<
   >>>>                                                       <<<<
   >>>>                xvf_gen_parse()		              <<<<
   >>>>                xvf_gen_deparse()		      <<<<
   >>>>                                                       <<<<
   >>>>                xvf_clear_selections()		      <<<<
   >>>>                                                       <<<<
   >>>>                form2command()	 		      <<<<
   >>>>                xvf_strip_dash()                       <<<<
   >>>>                xvf_prepend_env_dir()                  <<<<
   >>>>                                                       <<<<
   >>>>                xvf_place_widget()		      <<<<
   >>>>                xvf_update_glyph()		      <<<<
   >>>>                xvf_cap_first_letter()                 <<<<
   >>>> 	       xvf_def_number_sign_digit              <<<<
   >>>>                                                       <<<<
   >>>>		       xvf_realize_widget()		      <<<<
   >>>>		       xvf_map_widget()			      <<<<
   >>>>		       xvf_unmap_widget()		      <<<<
   >>>>                                                       <<<<
   >>>>		       xvf_form_geometry()		      <<<<
   >>>>		       xvf_subform_geometry()		      <<<<
   >>>>                                                       <<<<
   >>>>		       xvf_sync()			      <<<<
   >>>>		       xvf_process_event()		      <<<<
   >>>>		       xvf_consolidate_args()		      <<<<
   >>>>		       xvf_set_cantata()		      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/************************************************************
*
*  Routine Name: xvf_get_line_type
*
*      Purpose:  returns a #define'd integer (see line_info.h)
*		 that indicates what type of line we have
*
*        Input:  line - line from the database
*
*       Output:  type of line
*
*   Written By:  Danielle Argiro 
*
*************************************************************/

int xvf_get_line_type(line)
char *line;
{
	char flag;

	if (line == NULL)
	{
	     fprintf(stderr, "\nxvf_get_line_type:\n");
             fprintf(stderr, "   ERROR: UIS line sent in is NULL.\n");
             return(-1);
	}

	else if (line[0] == '-') flag = line[1];

	else if ((sscanf(line, " -%c", &flag))!=1) 
  	{
	    fprintf(stderr, "\nxvf_get_line_type:\n");
	    if (line[xvf_strlen(line)-1] == '\n') 
		line[xvf_strlen(line)-1] = '\0';
	    fprintf(stderr, "     ERROR: encountering unknown line '%s' in UIS file\n", line);
	    return(-1);
	}

	switch (flag) {

		case 'F': 	return(StartForm); 	break;

		case 'S': 	return(StartMaster); 	break;

		case 'D': 	return(StartSubMenu); 	break;

		case 'M': 	return(StartSubForm); 	break;

		case 'P': 	return(StartPane); 	break;

		case 'G': 	return(StartGuide); 	break;

		case 'E': 	return(End); 		break;

		case 'd': 	return(SubFormButton); 	break;

		case 'u': 	return(PsuedoSubForm); 	break;

		case 'n':	return(MasterAction); 	break;

		case 'g': 	return(GuideButton); 	break;

		case 'Q': 	return(QuitForm); 	break;

		case 'm': 	return(SubformAction); 	break;

		case 'I': 	return(InputFile); 	break;

		case 'O':	return(OutputFile); 	break;

		case 'i': 	return(IntegerOpt); 	break;

		case 'f': 	return(FloatOpt); 	break;

		case 's': 	return(StringOpt); 	break;

		case 'l': 	return(LogicOpt); 	break;

		case 'T': 	return(Toggle); 	break;

		case 'R': 	return(Routine); 	break;

		case 'H': 	return(HelpSel); 	break;

		case 'b': 	return(Blank); 		break;

		case 'a': 	return(PaneAction); 	break;

		case 'C': 	return(MutExcl); 	break;

		case 'p': 	return(IncludePane); 	break;

		case 'k': 	return(IncludeSubForm);	break;

		case 'w': 	return(WorkWidget); 	break;

		case 'L': 	return(LibCall); 	break;

		case 'c': 	return(Cycle); 		break;

		case 'x': 	return(List); 		break;

		case 'A': 	return(AnswerInfile); 	break;

		case 'Z': 	return(AnswerOutfile); 	break;

		default:  	
			fprintf(stderr, "xvf_get_line_type:\n");
			fprintf(stderr, "   ERROR: Unknown UIS line type:\n");
			fprintf(stderr, "          '-%c' in line \n", flag);
			fprintf(stderr, "          '%s'", line);
				return(-1); 		
				break;

		}  /* end switch */

} /* end xvf_get_line_type */





/************************************************************
*
*  Routine Name: xvf_reverse_colors
*
*      Purpose:  highlights (or un-highlights) the widget passed in
*
*        Input:  widget - the widget to be highlighted (un-highlighted)
*
*       Output:  none
*
*    Called By:  misc. routines
*
*   Written By:  Stephanie Hallett and Danielle Argiro
*
*************************************************************/


xvf_reverse_colors(widget)
Widget widget;
{
   Arg arg[MaxArgs];
   int  n;
   Pixel	fg,bg;

   if (XtIsRealized(widget) == False)
      return;

   /*
    * get current fg & bg
    */
   n = 0;
   XtSetArg(arg[n],XtNforeground,&fg);	n++;
   XtSetArg(arg[n],XtNbackground,&bg);	n++;
   XtGetValues(widget,arg,n);

   /*
    * toggle current fg & bg
    */
   n = 0;
   XtSetArg(arg[n],XtNforeground,bg);         n++;
   XtSetArg(arg[n],XtNbackground,fg);         n++;
   XtSetValues(widget,arg,n);

} /* end xvf_reverse_colors */



/**************************************************************
*
*Routine Name: xvf_lower
*
*     Purpose:  This routine is used to convert any string to lower
*               case.  It first copies the incoming string into a
*               new string and then converts all upper case characters
*               to lower case.  The resulting lower case string is
*               then passed back to the calling routine.
*
*       Input:  string  -  the string to be converted to lower case.
*
*      Output:  lower   -  the resulting lower case string.
*
*
*   Written By: Mark Young
*
***************************************************************/


char *xvf_lower(string)

char *string;
{
        int  i;
        char *lower;

        lower = xvf_strcpy(string);
        for (i = 0; i < xvf_strlen(string); i++)
        {
           if (isupper(lower[i]))
              lower[i] = tolower(lower[i]);
        }
        return(lower);
}


/************************************************************
*
*  Routine Name: xvf_gen_parse
*
*      Purpose:  parses an unknown type of line -
*		 returns the Line_Info structure and the type
*		 of line in question.
*
*        Input:  line - the line from the database
*
*       Output:  line_info structure and type flag
*
*    Called By:  misc. routines
*
*   Written By:  Danielle Argiro & Stephanie Hallett
*
*
*************************************************************/

int xvf_gen_parse(line, line_info)

char *line;
Line_Info *line_info;

{
 	int	typeflag, status;

	typeflag = xvf_get_line_type(line);
	xvf_clear_line_info(line_info);

	switch (typeflag) {
		case StartForm:
			status = xvf_parse_startform_line(line, line_info);
			break;

		case StartMaster:
			status = xvf_parse_startmaster_line(line, line_info);
			break;

		case StartSubMenu:
			status = xvf_parse_startsubmenu_line(line, line_info);
			break;

		case PsuedoSubForm:
			status = xvf_parse_psuedosubform_line(line, line_info);
			break;

		case StartSubForm:
			status = xvf_parse_startsubform_line(line, line_info);
			break;

		case StartPane:
			status = xvf_parse_startpane_line(line, line_info);
			break;

		case StartGuide:
			status = xvf_parse_startguide_line(line, line_info);
			break;

		case GuideButton:
			status = xvf_parse_guide_line(line, line_info);
			break;

		case MasterAction:
			status = xvf_parse_master_action_line(line, line_info);
			break;

		case SubFormButton:
			status = xvf_parse_subformbutton_line(line, line_info);
			break;
	
		case QuitForm:
			status = xvf_parse_quit_line(line, line_info);
			break;
	 
		case SubformAction:
			status = xvf_parse_subform_action_line(line, line_info);
			break;
	
		case InputFile:
			status = xvf_parse_input_line(line, line_info);
			break;

		case OutputFile:
			status = xvf_parse_output_line(line, line_info);
			break;

		case IntegerOpt:
			status = xvf_parse_int_line(line, line_info);
			break;

		case FloatOpt:
			status = xvf_parse_float_line(line, line_info);
			break;

		case StringOpt:
			status = xvf_parse_string_line(line, line_info);
			break;

		case LogicOpt:
			status = xvf_parse_logic_line(line, line_info);
			break;

		case Toggle:
			status = xvf_parse_toggle_line(line, line_info);
			break;

		case Routine:
			status = xvf_parse_routine_line(line, line_info);
			break;

		case HelpSel:
			status = xvf_parse_help_line(line, line_info);
			break;

		case Blank:
			status = xvf_parse_blank_line(line, line_info);
			break;

		case PaneAction:
			status = xvf_parse_pane_action_line(line, line_info);
			break;

		case IncludePane:
			status = xvf_parse_includepane_line(line, line_info);
			break;

		case IncludeSubForm:
			status = xvf_parse_includesubform_line(line, line_info);
			break;

		case WorkWidget:
			status = xvf_parse_workspace_line(line, line_info);
			break;

		case MutExcl:
			status = xvf_parse_mutexcl_line(line, line_info);
			break;

		case Cycle:
			status = xvf_parse_cycle_line(line, line_info);
			break;

		case List:
			status = xvf_parse_list_line(line, line_info);
			break;

		case AnswerInfile:
			status = xvf_parse_ansinfile_line(line, line_info);
			break;

		case AnswerOutfile:
			status = xvf_parse_ansoutfile_line(line, line_info);
			break;

		case End:
			status = xvf_parse_end_line(line, line_info);
			break;

                default:
	                line_info->typeflag = -1;
			return(false);
			break;

		}  /* end switch */

        return(status);
}
	


/************************************************************
*
*  Routine Name: xvf_gen_deparse
*
*      Purpose:  deparses an unknown type of line -
*		 returns the Line_Info structure and the type
*		 of line in question.
*
*       Input:  line_info structure (with CORRECT type flag)
*		database - the internal database structure
*		index	 - index into the database
*
*    Called By:  misc. routines
*
*   Written By:  Danielle Argiro & Stephanie Hallett
*
*
*************************************************************/

xvf_gen_deparse(line_info, database, index)

Line_Info *line_info;
char	  *database[];
int	  index;

{
	switch (line_info->typeflag)
	{

		case StartForm:
		     xvf_deparse_startform_line(line_info, database, index);
		     break;

		case StartMaster:
		     xvf_deparse_startmaster_line(line_info, database, index);
		     break;

		case StartSubMenu:
		     xvf_deparse_startsubmenu_line(line_info, database, index);
		     break;

		case PsuedoSubForm:
		     xvf_deparse_psuedosubform_line(line_info, database, index);
		     break;

		case StartSubForm:
		     xvf_deparse_startsubform_line(line_info, database, index);
		     break;

		case StartPane:
		     xvf_deparse_startpane_line(line_info, database, index);
		     break;

		case StartGuide:
		     xvf_deparse_startguide_line(line_info, database, index);
		     break;

		case GuideButton:
		     xvf_deparse_guide_line(line_info, database, index);
		     break;
	
		case MasterAction:
		     xvf_deparse_master_action_line(line_info, database, index);
		     break;
	 
		case SubFormButton:
		     xvf_deparse_subformbutton_line(line_info,database,index);
		     break;
	
		case SubformAction:
		     xvf_deparse_subform_action_line(line_info,database,index);
		     break;
	
		case QuitForm:
		     xvf_deparse_quit_line(line_info, database, index);
		     break;
	 
		case InputFile:
		     xvf_deparse_input_line(line_info, database, index);
		     break;

		case OutputFile:
		     xvf_deparse_output_line(line_info, database, index);
		     break;

		case IntegerOpt:
		     xvf_deparse_int_line(line_info, database, index);
		     break;

		case FloatOpt:
		     xvf_deparse_float_line(line_info, database, index);
		     break;

		case StringOpt:
		     xvf_deparse_string_line(line_info, database, index);
		     break;

		case LogicOpt:
		     xvf_deparse_logic_line(line_info, database, index);
	     	     break;

		case Toggle:
		     xvf_deparse_toggle_line(line_info, database, index);
		     break;

		case Routine:
		     xvf_deparse_routine_line(line_info, database, index);
		     break;

		case HelpSel:
		     xvf_deparse_help_line(line_info, database, index);
		     break;

		case Blank:
		     xvf_deparse_blank_line(line_info, database, index);
		     break;

		case PaneAction:
		     xvf_deparse_pane_action_line(line_info, database, index);
		     break;

		case IncludePane:
		     xvf_deparse_includepane_line(line_info, database, index);
		     break;

		case IncludeSubForm:
		     xvf_deparse_includesubform_line(line_info, database,index);
		     break;

		case MutExcl:
		     xvf_deparse_mutexcl_line(line_info, database, index);
		     break;

		case WorkWidget:
		     xvf_deparse_workspace_line(line_info, database, index);
		     break;

		case Cycle:
		     xvf_deparse_cycle_line(line_info, database, index);
		     break;

		case List:
		     xvf_deparse_list_line(line_info, database, index);
		     break;

		case AnswerInfile:
		     xvf_deparse_ansinfile_line(line_info, database, index);
		     break;

		case AnswerOutfile:
		     xvf_deparse_ansoutfile_line(line_info, database, index);
		     break;

		case End:
		     xvf_deparse_end_line(line_info, database, index);
		
                default:
	  	     break;

	} /* end switch */
}





/************************************************************
*
*  Routine Name: xvf_clear_selections
*
*      Purpose:  after calling run_form, in preparation for another
*		 call to run_form, this routine clears out all
*		 the old 'selected' fields in preparation for a new run.
*
*        Input:  database - the internal array of strings that
*			    define the form
*		 size - the size of the database (number of lines)
*
*       Output:  none
*
*    Called By:  application program
*
*   Written By:  Danielle Argiro
*
*
*************************************************************/

xvf_clear_selections(database, size)
char *database[];
int  size;

{

	int flag, index;
	Line_Info line_info;

	xvf_clear_line_info(&line_info);

	for (index = 0; index < size; index++)
	{

	   flag = xvf_get_line_type(database[index]);
	
	   switch (flag)
	   {

		case QuitForm:
		     xvf_parse_quit_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_quit_line(&line_info, database, index);
		     }
		     break;

		case MasterAction:
		     xvf_parse_master_action_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_master_action_line(&line_info, 
							database, index);
		     }
		     break;

		case SubformAction:
		     xvf_parse_subform_action_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_subform_action_line(&line_info, 
							database, index);
		     }
		     break;

		case InputFile:
		     xvf_parse_input_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_input_line(&line_info, database, index);
		     }
		     break;

		case OutputFile:
		     xvf_parse_output_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_output_line(&line_info, database, index);
		     }
		     break;

		case IntegerOpt:
		     xvf_parse_int_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_int_line(&line_info, database, index);
		     }
		     break;
			
		case FloatOpt:
		     xvf_parse_float_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_float_line(&line_info, database, index);
		     }
		     break;
			
		case LogicOpt:
		     xvf_parse_logic_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_logic_line(&line_info, database, index);
		     }
		     break;
			
		case StringOpt:
		     xvf_parse_string_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_string_line(&line_info, database, index);
		     }
		     break;
			
		case Toggle:
		     xvf_parse_toggle_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_toggle_line(&line_info, database, index);
		     }
		     break;
			
		case PaneAction:
		     xvf_parse_pane_action_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_pane_action_line(&line_info, 
						      database, index);
		     }
		     break;

		case Cycle:
		     xvf_parse_cycle_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_cycle_line(&line_info, 
						      database, index);
		     }
		     break;

		case AnswerInfile:
		     xvf_parse_ansinfile_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_ansinfile_line(&line_info, 
						    database, index);
		     }
		     break;

		case AnswerOutfile:
		     xvf_parse_ansoutfile_line(database[index], &line_info);
		     if (line_info.selected == true)
		     {
		         line_info.selected = false;
		         xvf_deparse_ansoutfile_line(&line_info, 
						    database, index);
		     }
		     break;


		default:
		     break;
			
	   } /* end switch */
	
	} /* end for */

} /* end xvf_clear_selection */


/************************************************************
*
*  Routine Name:  form2command(form, subform, machine)
*
*      Purpose:   gathers information from the form and
*		  creates a command line representation
*		  of the current pane in the form.
*
*        Input:   form	      - pointer to the form tree
*		  subform     - pointer to a subform tree.
*		  machine     - pointer to machine in which to execute
*				the command
*
*       Output:   gives back a string representing the
*		  command line.  (The string has been
*		  malloced).
*
*    Called By:   the application program
*
*   Written By:   Stephanie Hallett, Mark Young
*
*
*************************************************************/

char *form2command(form, subform, machine)

xvf_form     *form;
xvf_sub_form *subform;
char	     *machine;
{
   char	    leftover[50], line[5*MaxLength], command[5*MaxLength],
	    tmp_str[MaxLength], error[1024], buffer[MaxLength];
   long	    id;
   float    fvalue;
   int	    ivalue, num, flag;
   char     *comd_line, *tmp_name, *toggle_name, *filename;
   char	    **db;

   Line_Info line_info;
   xvf_guide_button *guide;
   xvf_selection    *sel, *start_tog;

   db    = form->db;
   id    = (long) form;
   guide = xvf_search_sel_guide(subform);
   sel   = guide->pane->sel_list;

   line[0]    = '\0';
   command[0] = '\0';
   xvf_clear_line_info(&line_info);

   while (sel != NULL)
   {
      tmp_str[0] = '\0';
      flag = xvf_get_line_type(db[sel->index]);

      switch (flag)
      {
	 case InputFile:
	    xvf_parse_input_line(db[sel->index],&line_info);
	    if ((line_info.optional == true && line_info.opt_sel == false) ||
		 line_info.literal == NULL)
	       break;

	    filename = vfullpath(line_info.literal, NULL, NULL); 
	    if (filename == NULL)
	    {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper input file expression\n\n", line_info.title, line_info.literal);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);

	    }
	    if (!(xve_eval_string(id, filename, buffer, error)))
	    {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper input file expression\n\n %s", line_info.title, line_info.literal, error);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);
	    }
	    free(filename);
            if (buffer != NULL)
	    {
               if (!(tmp_name = xvf_prepend_env_dir(buffer)))
		  break;

	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %s ",
			xvf_strip_dash(line_info.variable), tmp_name);
               else
	          sprintf(tmp_str,"%s ",tmp_name);

	       if ((line_info.optional == false) ||
		  ((line_info.optional == true) && (line_info.opt_sel == true)))
               strcat(line,tmp_str);

	       free(tmp_name);
            }
	    break;

	 case OutputFile:
	    xvf_parse_output_line(db[sel->index],&line_info);
	    if ((line_info.optional == true && line_info.opt_sel == false) ||
		 line_info.literal == NULL)
	       break;

	    filename = vfullpath(line_info.literal, NULL, NULL); 
	    if (filename == NULL)
	    {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper output file expression\n\n", line_info.title, line_info.literal);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);

	    }
	    if (!(xve_eval_string(id, filename, buffer, error)))
	    {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper output \
file expression\n\n %s", line_info.title, line_info.literal, error);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);
	    }
	    free(filename);
            if (buffer != NULL)
	    {
               if (!(tmp_name = xvf_prepend_env_dir(buffer)))
		  break;

	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %s ",
			xvf_strip_dash(line_info.variable), tmp_name);
               else
	          sprintf(tmp_str,"%s ",tmp_name);

	       if ((line_info.optional == false) ||
		  ((line_info.optional == true) && (line_info.opt_sel == true)))
               strcat(line,tmp_str);

	       free(tmp_name);
            }
	    break;

	 case IntegerOpt:
	    xvf_parse_int_line(db[sel->index],&line_info);
	    if ((line_info.optional == true) && (line_info.opt_sel == false))
	       break;
	    if (sscanf(line_info.literal,"%d%s", &ivalue, leftover) != 1)
	    {
	       if (!(xve_eval_int(id, line_info.literal, &ivalue, error)))
               {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper integer \
expression\n\n %s", line_info.title, line_info.literal, error);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);
	       }
 	    }
	    if (VStrcmp(line_info.variable,"-") != 0)
	       sprintf(tmp_str,"-%s %d ", xvf_strip_dash(line_info.variable),
		       ivalue);
            else
	       sprintf(tmp_str,"%d ", ivalue);

	    if ((line_info.optional == false) ||
	        ((line_info.optional == true) && (line_info.opt_sel == true)))
            strcat(line,tmp_str);
	    break;

	 case FloatOpt:
	    xvf_parse_float_line(db[sel->index],&line_info);
	    if ((line_info.optional == true) && (line_info.opt_sel == false))
	       break;
	    if (sscanf(line_info.literal,"%f%s", &fvalue, leftover) != 1)
	    {
	       if (!(xve_eval_float(id, line_info.literal, &fvalue, error)))
               {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper float \
expression\n\n %s", line_info.title, line_info.literal, error);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);
	       }
 	    }
	    if (VStrcmp(line_info.variable,"-") != 0)
	       sprintf(tmp_str,"-%s %g ", xvf_strip_dash(line_info.variable),
		       fvalue);
            else
	       sprintf(tmp_str,"%g ", fvalue);

	    if ((line_info.optional == false) ||
	       ((line_info.optional == true) && (line_info.opt_sel == true)))
            strcat(line,tmp_str);
	    break;

	 case StringOpt:
	    xvf_parse_string_line(db[sel->index],&line_info);
	    if ((line_info.optional == true && line_info.opt_sel == false) ||
		 line_info.literal == NULL)
	       break;

	    if (!(xve_eval_string(id, line_info.literal, buffer, error)))
	    {
                  sprintf(tmp_str,"Error: '%s' %s\n is not a proper string \
expression\n\n %s", line_info.title, line_info.literal, error);
                  xvf_error_wait(tmp_str, "form2command", NULL);
                  return(NULL);
	    }
            if (buffer != NULL)
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s \"%s\" ",
			xvf_strip_dash(line_info.variable), buffer);
               else
	          sprintf(tmp_str,"\"%s\" ", buffer);

	       if ((line_info.optional == false) ||
		  ((line_info.optional == true) && (line_info.opt_sel == true)))
               strcat(line,tmp_str);
            }
	    break;

	 case LogicOpt:
	    xvf_parse_logic_line(db[sel->index],&line_info);
	    if ((line_info.optional == true) && 
	       (line_info.opt_sel== false))
	       break;
	    if (line_info.logical_val== false) 
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s 0 ",
			xvf_strip_dash(line_info.variable));
	       else
	          sprintf(tmp_str,"0 ");
   
	       if ((line_info.optional == false) ||
		  ((line_info.optional == true) && (line_info.opt_sel == true))||
                   (sel->mut_excl == false))
               strcat(line,tmp_str);
	    }
	    else
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s 1 ",
			xvf_strip_dash(line_info.variable));
	       else
	          sprintf(tmp_str,"1");

	       if ((line_info.optional == false) ||
		  ((line_info.optional == true) && (line_info.opt_sel == true))||
                   (sel->mut_excl == false))
               strcat(line,tmp_str);
	    }
	    break;

	 case Cycle:
	    xvf_parse_cycle_line(db[sel->index],&line_info);
	    if ((line_info.optional == true) && 
	       (line_info.opt_sel == false))
	       break;

	    if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %d ",
			xvf_strip_dash(line_info.variable), line_info.cycle_val);

	    else
	          sprintf(tmp_str,"%d", line_info.cycle_val);

	    if ((line_info.optional == false) ||
		((line_info.optional == true) && (line_info.opt_sel == true))||
                (sel->mut_excl == false))
               strcat(line,tmp_str);
	    break;

	 case Toggle:
	    xvf_parse_toggle_line(db[sel->index],&line_info);
	    if ((line_info.optional == true) && 
	       (line_info.opt_sel== false))
	       break;
            if (line_info.toggle_val == 0)
               line_info.toggle_val = line_info.toggle_def;

 	    toggle_name = xvf_strcpy(line_info.variable);

            num = line_info.toggle_val-1;
            start_tog = sel->toggle_next;
            while (num > 0)
            {
               start_tog = start_tog->next;
               num = num-1;
            }
            num = line_info.toggle_val;
	    xvf_gen_parse(db[start_tog->index],&line_info);

	    if (line_info.typeflag == IntegerOpt)
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %d ",
			xvf_strip_dash(toggle_name),
		  	line_info.int_def);
               else
	          sprintf(tmp_str,"%d ",line_info.int_def);
	    }
	    else if (line_info.typeflag == FloatOpt)
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %g ",
			xvf_strip_dash(toggle_name),
		  	line_info.float_def);
               else
	          sprintf(tmp_str,"%g ",line_info.float_def);
	    }
	    else if (line_info.typeflag == InputFile)
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %s ",
			xvf_strip_dash(toggle_name),
		  	line_info.file_def);
               else
	          sprintf(tmp_str,"%s ",line_info.file_def);
	    }
	    else if (line_info.typeflag == OutputFile)
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %s ",
			xvf_strip_dash(toggle_name),
		  	line_info.file_def);
               else
	          sprintf(tmp_str,"%s ",line_info.file_def);
	    }
	    else if (line_info.typeflag == StringOpt)
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s \"%s\" ",
			xvf_strip_dash(toggle_name),
		  	line_info.string_def);
               else
	          sprintf(tmp_str,"\"%s\" ",line_info.string_def);
	    }
            else
	    {
	       if (VStrcmp(line_info.variable,"-") != 0)
	          sprintf(tmp_str,"-%s %d ",
			xvf_strip_dash(toggle_name),num);
               else
	          sprintf(tmp_str,"%d ",num);
	    }

            strcat(line,tmp_str);
	    break;

	 case Routine:
	    xvf_parse_routine_line(db[sel->index],&line_info);
	    /* I am assuming here that there is only one routine
               to be performed on a pane.  This may need to be
               changed later */
	    if (machine == NULL)
	    {
	       if (vfullpath(line_info.routine, NULL, command) == NULL)
	          sprintf(command,"%s ",line_info.routine);
	       else
	          strcat(command, " ");
	    }
	    else
	    {
	       if (vfullpath(line_info.routine, NULL, command) == NULL)
	          sprintf(command,"%s@%s ",line_info.routine, machine);
	       else
	       {
	          strcat(command, "@");
	          strcat(command, machine);
	          strcat(command, " ");
	       }
	    }
	    break;

	 case HelpSel:
	 case PaneAction:
	 case QuitForm:
	 default:
	    /* these don't effect the command line */
	    break;
      }
      sel = sel->next;
   }
   strcat(command,line);
   comd_line = xvf_strcpy(command);
   return(comd_line);
}

/************************************************************
*
*  Routine Name:  xvf_strip_dash(string)
*
*      Purpose:   takes a string and makes sure there is no
*                 dash on the front end.  Will return the
*                 original string if no dash.  Will malloc
*                 and copy without dash if one is present.
*
*        Input:   string to be checked
*
*       Output:   
*
*    Called By:   the application program
*
*   Written By:   Stephanie Hallett
*
*
*************************************************************/
char *xvf_strip_dash(string)
char *string;
{
   if (string[0] == '-')
   {
      string++;
      return(xvf_strcpy(string));
   }
   else
      return(string);
}


/************************************************************
*
*  Routine Name:  xvf_prepend_env_dir(filename)
*
*      Purpose:   if filename has no path attached,
*                 then XVF_FILE_DIR is prepended as the path
*
*        Input:   filename  - file to be checked
*
*       Output:   mallocs and passes back filename with path
*
*    Called By:   the application program
*
*   Written By:   Stephanie Hallett
*
*
*************************************************************/
char *xvf_prepend_env_dir(filename)
char *filename;
{
        char    *file;

        file = vfullpath(filename, XVF_FILE_DIR, NULL);
	if (file != NULL)
          return(xvf_strcpy(file));
	else return(NULL);
}



/************************************************************
*
*  Routine Name: xvf_place_widget
*
*      Purpose:  places the widget centered about the cursor.
*
*        Input:  widget - the widget to placed
*
*       Output:  none
*
*   Written By:  Mark Young, & Danielle Argiro, Stephanie Hallett
*
*************************************************************/

xvf_place_widget(widget, placement)

Widget widget, placement;
{
   Arg    arg[5];

   Window   rw, cw;
   unsigned int mask;
   XWindowAttributes  xwa, pwa;
   int	    rx, ry, wx, wy, x, y, xoff, yoff;

   XtSetMappedWhenManaged(widget, false);
   XtRealizeWidget(widget);
   XSync(xvf_display, false);

   XQueryPointer(xvf_display, XDefaultRootWindow(xvf_display), &rw, &cw,
		 &rx, &ry, &wx, &wy, &mask);

   if (placement != NULL)
   {
      Position x1, x2, y1, y2;

      XtTranslateCoords(widget, 0, 0, &x1, &y1);
      XtTranslateCoords(placement, 0, 0, &x2, &y2);
      XGetWindowAttributes(xvf_display, XtWindow(widget), &xwa);
      XGetWindowAttributes(xvf_display, XtWindow(placement), &pwa);

      x = rx - (x2 - x1) - pwa.width + 3;
      y = ry - (y2 - y1) - pwa.height/2;

      xoff = xwa.width - (x2 - x1);
      yoff = xwa.height - (y2 - y1);
   }
   else
   {
      XGetWindowAttributes(xvf_display, XtWindow(widget), &xwa);

      xoff =  xwa.width/2;
      yoff = xwa.height/2;

      x = rx - xoff;
      y = ry - yoff;
   }

   if ((x + xoff) > XDisplayWidth(xvf_display, xvf_screen_num))
      x = XDisplayWidth(xvf_display, xvf_screen_num) - xwa.width;

   if ((y + yoff) > XDisplayHeight(xvf_display, xvf_screen_num))
      y = XDisplayHeight(xvf_display, xvf_screen_num) - xwa.height;

   if (x < 0) x = 0;
   if (y < 0) y = 0;

   XtSetArg(arg[0], XtNx, x);
   XtSetArg(arg[1], XtNy, y);
   XtSetValues(widget, arg, 2);
   XtMapWidget(widget);
   XFlush(xvf_display);
}



/************************************************************
*
*  Routine Name: xvf_cap_first_letter(name)
*
*      Purpose: Takes a string, mallocs a new string containing the old
* 		string with its first letter capitalized.
*  		ex.   "name" returns "Name"
*
*        Input:  name  - name to be capitalized
*
*       Output:  the capitalized string
*
*   Written By:  Stephanie Hallet
*
****************************************************************/

char *xvf_cap_first_letter(name)
char *name;
{
   char *new_name;

   if (name == NULL)
      return(NULL);

   new_name = xvf_strcpy(name);
   if (islower(new_name[0]))
      new_name[0] = toupper(new_name[0]);

   return(new_name);
}
    

/************************************************************
*
*  Routine Name: xvf_def_number_sign_digits
*
*       Purpose: When an float selection has a scroll bar, 
*		 figures out how many significant digits
*		 to the right of the decimal place should be used
*		 for the value widget.
*
*        Input:  interval - interval in world coordinates
*
*	 Output: returns the number of significant digits
*
*	Called by: xvf_create_float_sel()
*
*   Written By:  Danielle Argiro
*
**************************************************************/

int xvf_def_number_sign_digits(interval, literal)
float interval;
char  *literal;
{
	int current_length;
	char *digits, *strrchr();

	if ((digits = strrchr(literal, '.')) == NULL)
	{
	    if (interval <= 1)
		current_length = 6;

	   else if (interval <= 2)
		current_length = 5;

	   else if (interval <= 5)
		current_length = 4;

	   else if (interval <= 10)
		current_length = 3;

	   else if (interval <= 50)
		current_length = 2;
	   else 
		current_length = 1;
	}
	else 
	    current_length = xvf_strlen(digits)-1;
	
	if (interval <= 1)
	   return(MAX(6, current_length));
	else if (interval <= 2)
	   return(MAX(5, current_length));
	else if (interval <= 5)
	   return(MAX(4, current_length));
	else if (interval <= 10)
	   return(MAX(3, current_length));
	else if (interval <= 50)
	   return(MAX(2, current_length));
	else 
	   return(MAX(1, current_length));

}


/******************************************************************
*
*  Routine Name:  xvf_realize_widget
*
*	Purpose:  realizes a widget, setting XtNmappedWhenManaged to false.
*
*	  Input:  widget - the widget to be realized
*
*    Written By: Danielle Argiro
*
*******************************************************************/

xvf_realize_widget(widget)
Widget widget;
{
   Arg arg[10];

   XtSetArg(arg[0],XtNmappedWhenManaged, False);
   XtSetValues(widget,arg,1);
   XtRealizeWidget(widget);
}

/******************************************************************
*
*  Routine Name:  xvf_map_widget
*
*	Purpose:  maps a widget, if the widget pointer is not NULL
*
*	  Input:  widget - the widget to be realized
*
*    Written By: Danielle Argiro
*
*******************************************************************/

xvf_map_widget(widget)

Widget widget;
{
	if (widget != NULL)
	{
	   XMapRaised(XtDisplay(widget), XtWindow(widget));
	}
}

/******************************************************************
*
*  Routine Name:  xvf_unmap_widget
*
*	Purpose:  unmaps a widget, if the widget pointer is not NULL
*
*	  Input:  widget - the widget to be realized
*
*    Written By: Danielle Argiro
*
*******************************************************************/

xvf_unmap_widget(widget)

Widget widget;
{
	if (widget != NULL)
	   XtUnmapWidget(widget);
}


/******************************************************************
*
*  Routine Name:  xvf_iconify_widget
*
*	Purpose:  iconify a widget, if the widget pointer is not NULL
*
*	  Input:  widget - the widget to be realized
*
*    Written By: Danielle Argiro
*
*******************************************************************/

xvf_iconify_widget(widget)

Widget widget;
{
	if (widget != NULL)
	{
	   XIconifyWindow(XtDisplay(widget), XtWindow(widget),
		XDefaultScreen(XtDisplay(widget)));
	}
}

/******************************************************************
*
*  Routine Name:  xvf_form_geometry
*
*	Purpose:  Get the geometry of a form.  This is done by getting
*		  the window geometry of the form's toplevel widget.
*
*	  Input:  form   - the form to be inquired
*		  x, y   - the form's x and y position.
*		  width  - the form's width
*		  height - the form's height
*
*    Written By: Mark Young
*
*******************************************************************/

xvf_form_geometry(form, x, y, width, height)

xvf_form *form;
int	 *x, *y, *width, *height;
{
	Widget	 widget;
	Position xpos, ypos;
	XWindowAttributes  xwa;


	if (form->toplevel != NULL)
	{
	   widget = form->toplevel;
	   XtTranslateCoords(widget, 0, 0, &xpos, &ypos);
	   XGetWindowAttributes(xvf_display, XtWindow(widget), &xwa);

	   *x = xpos - xwa.border_width;
	   *y = ypos - xwa.border_width;
	}
	else
	{
	   xvf_error_wait("Unable to get form geometry. Form toplevel is NULL.",
			  "xvf_form_geometry", NULL);
	}
}

/******************************************************************
*
*  Routine Name:  xvf_subform_geometry
*
*	Purpose:  Get the geometry of a subform.  This is done by getting
*		  the window geometry of the subform's toplevel widget.
*
*	  Input:  subform - the subform to be inquired
*		  x, y    - the subform's x and y position.
*		  width   - the subform's width
*		  height  - the subform's height
*
*    Written By: Mark Young
*
*******************************************************************/

xvf_subform_geometry(subform, x, y, width, height)

xvf_sub_form *subform;
int	 *x, *y, *width, *height;
{
	Widget	 widget;
	Position xpos, ypos;
	XWindowAttributes  xwa;


	if (subform->toplevel != NULL)
	{
	   widget = subform->toplevel;
	   XtTranslateCoords(widget, 0, 0, &xpos, &ypos);
	   XGetWindowAttributes(xvf_display, XtWindow(widget), &xwa);

	   *x = xpos - xwa.border_width;
	   *y = ypos - xwa.border_width;
	}
	else
	   xvf_error_wait("Unable to get subform geometry. Form toplevel is \
NULL.", "xvf_subform_geometry", NULL);
}



/************************************************************
*
*  Routine Name: static process_event
*
*      Purpose:  gathers and dispatches events.  This routine
*		 will read the event and then dispatch it.  If
*		 no events remain and block is set to False then
*		 we return with False, which indicates that no
*		 more events remain.
*
*		 The other purpose of this routine is to record
*		 the event if journal record is set.
*		
*        Input:  block - whether we should block ("wait") until
*			 an event arrives.
*
*       Output:  returns True if more events are pending, otherwise
*		 False is returned.  Note: if block is set to True
*		 then we will always return True.
*
*   Written By:  Mark Young, Stephanie Hallett, Danielle Argiro 
*
*************************************************************/


static int process_event(block)

int	block;
{
	XEvent event;
	char   *name;
	int    type, toplevel;
	XtInputMask mask;
	Boolean ignoreInputs = false, 
	        ignoreEvents = false, 
		ignoreTimers = false;
	unsigned long *howlong = NULL;


	/*
	 *  Get the next event.
	 */
	if (jp_playing == False && jp_recording == False && block == True)
	   XtAppNextEvent(xvf_app_context, &event);
	else
	{
	   if ((mask = XtAppPending(xvf_app_context)) & XtIMXEvent)
	   {
	      XtAppNextEvent(xvf_app_context, &event);
	   }
	   else if (mask != 0)
	   {
	      XtAppProcessEvent(xvf_app_context, mask);
	      return(True);
	   }
	   else if (block == True)
	   {
	      (void) _XtwaitForSomething(ignoreTimers, ignoreInputs,
			ignoreEvents, True, howlong, xvf_app_context);
	      return(True);
	   }
	   else
	      return(False);

	}

	/*
	 *  if journal recording is on and we have a valid window name for the
	 *  event then record the event.
	 */
	if (jp_recording == true && event.xany.window != jp_window)
	{
	   /*
	    * look up the name of the current event's window 
	    * before dispatch the event.
	    */
	   if ((name = xvf_find_name(event.xany.window, &type, &toplevel))
			!= NULL)
	   {
	      if (strncmp(name, "jp_control_wid", 14) != 0)
	          jp_record(&event, name, type, toplevel);
	      free(name);
	   }
	}

	if (jp_playing == True && jp_recording == False && jp_halt == False)
	{
	   if (event.xany.window == jp_window || event.type >= EnterNotify)
	      XtDispatchEvent(&event);
	}
	else XtDispatchEvent(&event);

	return(True);
}



/************************************************************
*
*  Routine Name: xvf_sync
*
*      Purpose:  gathers and dispatches events until none are
*		 left.  In essence what xvf_sync() purpose is to
*		 remove all pending events by either discarding
*		 them from the queue or by processing them.  This
*		 is repeated until no events remain to be processed
*		 in the Toolkit's event queue.
*
*		 This is done by calling xvf_clean_event_list() if
*		 all pending events are to be discarded or repeatedly
*		 calling process_event() with block set to False.
*
*        Input:  discard - whether the pending events should be
*			   processed or simply removed from the
*			   queue.
*
*       Output:  none
*
*   Written By:  Mark Young & Danielle Argiro 
*
*************************************************************/

xvf_sync(discard)

int discard;
{
	int	more_events;


	if (discard == True)
	{
	    (void) xvf_clean_event_list(NULL);
	}
	else
	{
	    do
	    {
		more_events = process_event(False);
	    } while (more_events == True);
	}
}



/************************************************************
*
*  Routine Name: xvf_process_event
*
*      Purpose:  gathers and dispatches events
*		
*        Input:  none
*
*       Output:  none
*
*   Written By:  Mark Young, Stephanie Hallett, Danielle Argiro 
*
*************************************************************/

xvf_process_event()
{
	(void) process_event(True);
}



/************************************************************
*
*  Routine Name: xvf_clean_event_list()
*
*      Purpose:  cleans out the event list, discarding all events
*		 that we are not interested in, including:
*		 KeyPress, KeyRelease, ButtonPress, ButtonRelease, 
*		 and MotionNotify events.  The user is allowed to 
*		 initiate these events, but they will not be dispatched.
*
*		 A stop widget may be passed in; if the stop widget is not
*		 NULL, then we will react to ButtonPress events within this
*		 widget; this allows the user to utilize a control widget
*		 to abort the current process.
*		
*        Input:  stop widget (if applicable)
*
*       Output:  returns (0) if the user wants to abort the current process
*		 returns (1) otherwise
*
*
*   Written By:  Mark Young, Stephanie Hallett, Danielle Argiro 
*
*************************************************************/


int xvf_clean_event_list(jp_control)

Widget jp_control;
{
	XtInputMask mask;
	XEvent      event;
	Window	    jp_window;


	XSync(xvf_display, False);  

	if (jp_control != NULL)
	   jp_window = XtWindow(jp_control);
	else
	   jp_window = NULL;

	do
	{
	   mask = XtAppPending(xvf_app_context);
	   if (mask & XtIMXEvent)
	   {
	      XtAppNextEvent(xvf_app_context, &event);
	      if (event.xany.window == jp_window)
	      {
		 if (event.type == ButtonPress)
		    return(False);
		 else
		    XtDispatchEvent(&event);
	      }
	      else if (event.type >= EnterNotify)
	      {
		 XtDispatchEvent(&event);
	      }
	   }
	   else if (mask != 0)
	   {
	      XtAppProcessEvent(xvf_app_context, mask);
	   }
#ifdef DEBUG
	   if (FORM_DONE == True)
	      fprintf(stderr,"form done equals TRUE\n");
	   else
	      fprintf(stderr,"form done equals FALSE\n");
#endif
	}
	while (mask != 0 && FORM_DONE == False);

	return(True);
}



/************************************************************
*
*  Routine Name: xvf_change_colors
*
*      Purpose:  changes a widgets foreground and blackground
*		 color.
*		
*        Input:  widget - the widget to be changed
*		 bg     - the background color
*		 fg     - the foreground color
*
*       Output:  none
*
*   Written By:  Mark Young, Stephanie Hallett, Danielle Argiro 
*
*************************************************************/


xvf_change_colors(widget,bg,fg)
Widget widget;
Pixel bg,fg;
{
	int  n;
	Arg arg[MaxArgs];

	/*
	 * set current fg & bg
	 */
	n = 0;
	XtSetArg(arg[n],XtNforeground,fg);         n++;
	XtSetArg(arg[n],XtNbackground,bg);         n++;
	XtSetValues(widget,arg,n);

} /* end xvf_change_colors */



/************************************************************
*
*  Routine Name: xvf_change_form_glyph
*
*      Purpose:  changes the glyph and type for a given form.  Currently
*		 the forms support two types of widgets.  The first is the
*		 SIMPLE widget which is really a command button widget
*		 in which the user toggles from glyphed state to
*		 un-glyphed state.
*
*        Input:  glyph_widget - the widget that will be the glyph
*		 glyph_type   - the type of glyph
*		 form   - the form structure to associate the glyph
*
*       Output:  none
*
*   Written By:  Mark Young, & Danielle Argiro
*
*************************************************************/


xvf_change_form_glyph(form, glyph_widget, glyph_type)

xvf_form *form;
Widget   glyph_widget;
int	 glyph_type;
{
	int	i;
	Arg	args[10];
	unsigned long mask;
	Callback_Data *cb_data; 
	void    xvf_glyph_handler();


	if (form->glyph_type == ICON && glyph_type != ICON)
	{
	   i = 0;
	   XtSetArg(args[i], XtNiconWindow, NULL);		i++;
	   XtSetValues(form->toplevel, args, i);
	}

	if (form->glyph_toplevel != glyph_widget)
	   XtDestroyWidget(form->glyph_toplevel);

	if (glyph_type == ICON)
	{
	   i = 0;
	   XtSetArg(args[i], XtNiconWindow, XtWindow(glyph_widget)); i++;
	   XtSetValues(form->toplevel, args, i);

	   cb_data = xvf_init_cb_data(form, NULL, NULL, NULL, false, NULL);

	   mask = StructureNotifyMask;
	   XtAddEventHandler(form->toplevel, mask, FALSE, xvf_glyph_handler,
			(caddr_t) cb_data);
	}
	form->glyph_toplevel = glyph_widget;
	form->glyph_type = glyph_type;
}



/************************************************************
*
*  Routine Name: xvf_change_subform_glyph
*
*      Purpose:  changes the glyph and type for a given subform.  Currently
*		 the xvforms support two types of widgets.  The first is the
*		 SIMPLE widget which is really a command button widget
*		 in which the user toggles from glyphed state to
*		 un-glyphed state.
*
*        Input:  glyph_widget - the widget that will be the glyph
*		 glyph_type   - the type of glyph
*		 subform   - the subform structure to associate the glyph
*		 form      - the form structure to associate the subform
*
*       Output:  none
*
*   Written By:  Mark Young, & Danielle Argiro
*
*************************************************************/


xvf_change_subform_glyph(form, subform, glyph_widget, glyph_type)

xvf_sub_form *subform;
Widget   glyph_widget;
int	 glyph_type;
{
	int	i;
	Arg	args[10];
	unsigned long mask;
	Callback_Data *cb_data; 
	void    xvf_glyph_handler();


	if (subform->glyph_type == ICON && glyph_type != ICON)
	{
	   i = 0;
	   XtSetArg(args[i], XtNiconWindow, NULL);		i++;
	   XtSetValues(subform->toplevel, args, i);
	}

	if (subform->glyph_toplevel != glyph_widget)
	   XtDestroyWidget(subform->glyph_toplevel);

	if (glyph_type == ICON)
	{
	   i = 0;
	   XtSetArg(args[i], XtNiconWindow, XtWindow(glyph_widget)); i++;
	   XtSetValues(subform->toplevel, args, i);

	   cb_data = xvf_init_cb_data(form, subform, NULL, NULL, false, NULL);

	   mask = StructureNotifyMask;
	   XtAddEventHandler(subform->toplevel, mask, FALSE, xvf_glyph_handler,
			(caddr_t) cb_data);
	}
	subform->glyph_toplevel = glyph_widget;
	subform->glyph_type = glyph_type;
}


/************************************************************
*
*  Routine Name: xvf_consolidate_args
*
*      Purpose:  This routine searches the command and packs all the
*                arguments to the front of the argv array. The argc count is
*                set to the new number of arguments. Basically this
*                consolidates arguments by ridding all NULL arguments.
*
*        Input:  argc - number of command line arguments originally
*		 argv - command line arguments to be consolidated
*
*       Output:  none
*
*   Written By:  Mark Young, & Danielle Argiro
*
*************************************************************/

xvf_consolidate_args(argc, argv)
unsigned int *argc;
char *argv[];
{
	int i, count;
	count = 1;
	for (i = 1; i < *argc; i++)
	{
	    if (argv[i] != NULL)
		argv[count++] = argv[i];
	}
	*argc = count;
}


/************************************************************
*
*  Routine Name: xvf_set_cantata
*
*      Purpose:  supports a kludge to get cantata working
*		 with journal playback, but preserve working
*		 jp files by leaving old widget names alone
*
*        Input:  line - line from the database
*
*       Output:  type of line
*
*   Written By:  Danielle Argiro 
*
*************************************************************/

xvf_set_cantata()
{
	client_cantata = true;
}
