      /********************************************************/
      /*                   Widget-Builder               (3)   */
      /* This program was written by Brian R. Gardner, 1988.  */
      /* It was created as a visual, easy to use, technique   */
      /* for rapid proto-typing of user interfaces. It allows */
      /* its user to design the layout of an X-window based   */
      /* user interface, complete with sub-windows, buttons,  */
      /* labels, and other "widgets". This program will also  */
      /* serve as a programmer's aid by writing out to a file */
      /* the source code required to re-generate the created  */
      /* visual user interface. The code generated is usually */
      /* substantial, reflecting immense savings in the time  */
      /* neccessary to program using X-windows.               */
      /*    Note that this program is only a simple test      */
      /* version. It was the author's first introduction to   */
      /* the Athena environment, as well as X-windows and the */
      /*  X-Toolkit. It was written in 2 weeks.               */
      /*    This was written under the roof of Project Athena */
      /* at Massachusetts Institute of Technology, by         */
      /* Brian Gardner (DEC), and hence reasonably available. */
      /* Read that as "FREE"         :-)                      */
      /* with the usual friendly restrictions.                */
      /********************************************************/

     /************************************************************/
     /* Copyright 1988, Massachusetts Institute of Technology.   */
     /* See X(1) for a full statement of rights and permissions. */
     /************************************************************/

#define OR  |
#define DIVIDOR "/*********************************************************/\n"

#define chain(var) ((var == XtChainTop) ? "XtChainTop" \
		    : ((var == XtChainLeft) ? "XtChainLeft" \
		       : ((var == XtChainRight) ? "XtChainRight" \
		         : ((var == XtChainBottom) ? "XtChainBottom" \
			    : "XtRubber"))))

#define fontvar(fontname) \
    ((strcmp(fontname,"times-roman14") == 0) ? "timesRoman14" \
	   : ((strcmp(fontname,"times-bold14") == 0) \
	               ? "timesBold14" \
          : ((strcmp(fontname,"times-roman12") == 0) ? "timesRoman12" \
		    : ((strcmp(fontname,"times-bold12") == 0) \
	               ? "timesBold12" : "fixed"))))

#define fontstruct(fontname) \
    ((strcmp(fontname,"times-roman14") == 0) ? timesRoman14 \
	   : ((strcmp(fontname,"times-bold14") == 0) \
	               ? timesBold14 \
          : ((strcmp(fontname,"times-roman12") == 0) ? timesRoman12 \
		    : ((strcmp(fontname,"times-bold12") == 0) \
	               ? timesBold12 : fixedFont))))

#define find_widgets_node(widget) \
          (find_widgets_node_in(widget, HeadWidgetList))

static int WBgennameValue = 0;   /* used by genname() to gen a unique string */
static int not_optimizing;       /* flags if Saving C code is done optimized */

struct widgetusage {
  int button;
  int label;
  int blankLine;
  int keyedMailField;
  int blankMailField;
  int vPaned;
  int box;
  int dialog;
  int composite;
  int scrollBar;
  int text;
  int form;
  int shell;
  int asciiText;
  int popup;
 } widgetsUsed;

extern struct widgetusage widgetsUsed;


/* Info for linked list of widgets created by the Widget Builder */
/* ------------------------------------------------------------- */
typedef struct _widgetNode {
  char *varName;    /* name of variable widget is assigned to in saved code */
  char *name;       /* unique name of widget for X, often gensym'ed         */
  char *type;       /* type of widget (e.g.: "button", "label", etc.)       */
  Widget widget;    /* pointer to the actual widget                         */
  Widget parent;    /* pointer to the widget's parent widget                */
  char *callback;   /* name of callback function for widget (written later) */
  char *font;       /* name of the font for the label of this widget        */
  char *string;     /* use for holding ptr to Ascii Text widget's XtNstring */
  XFontStruct *font_struct;        /* ptr to font info structure            */
  struct _widgetNode *parent_node; /* ptr to parent widget's node in list   */
  struct _widgetNode *first_child; /* ptr to widget's first child in list   */
  struct _widgetNode *last_child;  /* ptr to widget's last child in list    */
  struct _widgetNode *popup;       /* ptr to widget's popup child node      */
  struct _widgetNode *next; /* ptr to next widget node in linked list       */
 } WidgetNode;

/* Head and tail pointers to linked list of created Widgets */
WidgetNode *HeadWidgetList = NULL;
WidgetNode *TailWidgetList = NULL;

/* Global Variables Used in querying widget properties */
/* --------------------------------------------------- */
   char *label;
   XtJustify justify;
   int borderwidth, height, width, x, y, highlightThickness;
   Pixel foreground, background, borderColor;
   int vertDistance, horizDistance;
   XtEdgeType top, left, right, bottom;
   Boolean resizable;
   Widget fromHoriz, fromVert;

/* Defaults for Global Variables Used in Saving C Code (Optimized) */
/* --------------------------------------------------------------- */
   XtJustify default_justify;
   int default_borderwidth, default_highlightThickness;
   Pixel default_foreground, default_background, default_borderColor;
   int default_vertDistance, default_horizDistance;
   XtEdgeType default_top, default_left, default_right, default_bottom;
   Boolean default_resizable;

/****************************************************************/

char *genname()
 {
   char *str;
   int places;
   float n;

   /* Generate a unique symbol (string) for external Widget Builder use */
   /* ----------------------------------------------------------------- */
   n = WBgennameValue + 1;
   for (places = 1; n > 1; places++)
     n = n / 10.0;
   /* Generate a unique widget name */
   str = (char *) calloc((strlen("WBwidget") + places + 2), 1);
   sprintf(str, "WBwidget%d", WBgennameValue++);
   return(str);

 };       /* end of genname() */


/****************************************************************/

WidgetNode *find_widgets_node_in(widget, starting_node)
     Widget widget;
     WidgetNode *starting_node;
 {
    WidgetNode *current_node, *wn;

    /* Locate the widget node in linked list for the search widget */
    /* ----------------------------------------------------------- */
    for (current_node = starting_node;
	 (current_node != NULL) && (current_node->widget != widget);
	 current_node = current_node->next)
      if ((wn = find_widgets_node_in(widget, current_node->first_child))
	  != NULL)
	return(wn);

    return(current_node);
  };         /* end of find_widgets_node() */

/****************************************************************/

WidgetNode *add_widget_node(widget, parent_widget, type)
     Widget widget;
     Widget parent_widget;
     char *type;
 {
   WidgetNode *new_node;

   /* allocate space for the new node */
   new_node = (WidgetNode *) calloc(sizeof(WidgetNode), 1);

   /* unique name of widget for X, often genname'ed         */
   new_node->name = genname();

   /* name of variable widget is assigned to in saved code */
   new_node->varName = new_node->name;

   /* type of widget (e.g.: "button", "label", etc.)       */
   new_node->type = type;  

   /* pointer to the actual widget                         */
   new_node->widget = widget;

   /* pointer to the widget's parent widget                */
   new_node->parent = parent_widget;

   /* pointer to the widget's popup child widget           */
   new_node->popup = NULL;

   /* name of callback function for widget (written later) */
   new_node->callback = NULL;

   /* use for holding ptr to Ascii Text widget's XtNstring */
   new_node->string = NULL;

   /* the name of the font used for  label of this widget  */
   new_node->font = (char *) calloc(15, 1);
   strcpy(new_node->font, "times-roman12");

   /* the struct of the font used this widget's label      */
   new_node->font_struct = timesRoman12;

   /* pointer to next widget node in linked list           */
   new_node->next = NULL;

   /* Set the pointer to the parent's widget node          */
   new_node->parent_node = find_widgets_node(parent_widget);

   /* Link new node into linked list of child widget nodes */
   if (parent_widget == userArea)
     { /* add node to the top level list */
       if (HeadWidgetList == NULL)
	 {
	   HeadWidgetList = new_node;
	   TailWidgetList = new_node;
	 }
       else
	 {
	   TailWidgetList->next = new_node;
	   TailWidgetList = new_node;
	 };
     }
   else
     { /* add node to a parents children list */
       if ((new_node->parent_node)->first_child == NULL)
	 {
	   (new_node->parent_node)->first_child = new_node;
	   (new_node->parent_node)->last_child = new_node;
	 }
       else
	 {
	   ((new_node->parent_node)->last_child)->next = new_node;
	   (new_node->parent_node)->last_child = new_node;
	 };
     };
   return(new_node);

 };             /* end of add_widget_node() */

/**************************************************************************/

void write_headers(outfile)
     FILE *outfile;
 {
   /* Output all of the required headers first (with comments) */
   /* -------------------------------------------------------- */
   fprintf(outfile, "#include <stdio.h>\n");
   fprintf(outfile, "#include <X11/Xlib.h>\n");
   fprintf(outfile, "#include <X11/StringDefs.h>");
   fprintf(outfile, " /* string definitions for things like XtNwidth */\n");
   fprintf(outfile, "#include <X11/Xresource.h>\n");
   fprintf(outfile, "#include <X11/Intrinsic.h>  ");
   fprintf(outfile, "/* include all the intrinsic headers */\n");
   fprintf(outfile, "                            ");
   fprintf(outfile, "/* includes XToolkit definitions     */\n");
   fprintf(outfile, "#include <X11/Xatom.h>\n");
   fprintf(outfile, "#include <X11/Xutil.h>\n");
   fprintf(outfile, "#include <X11/Composite.h>  ");
   fprintf(outfile, "/* facilitate creation of composite widgets */\n");
   fprintf(outfile, "#include <X11/Shell.h>      ");
   fprintf(outfile, "/* include shell widget class header files  */\n");
   fprintf(outfile, "#include <X11/Form.h>       ");
   fprintf(outfile, "/* not only includes the Form widget defs   */\n");
   fprintf(outfile, "                            ");
   fprintf(outfile, "/* but also the constraint defs             */\n");


   /* Output only the optional headers which are actually needed */
   /* ---------------------------------------------------------- */
   if ((widgetsUsed.button == TRUE)
       OR (widgetsUsed.keyedMailField == TRUE)
       OR (widgetsUsed.blankMailField == TRUE))
     {
       fprintf(outfile, "#include <X11/Command.h>    ");
       fprintf(outfile, "/* include command widget class header file */\n");
     };
   if ((widgetsUsed.box == TRUE))
     {
       fprintf(outfile, "#include <X11/Box.h>        ");
       fprintf(outfile, "/* include box widget class header files    */\n");
     };
   if ((widgetsUsed.text == TRUE)
       OR (widgetsUsed.asciiText == TRUE)
       OR (widgetsUsed.keyedMailField == TRUE)
       OR (widgetsUsed.blankMailField == TRUE))
     {
       fprintf(outfile, "#include <X11/Text.h>       ");
       fprintf(outfile, "/* include text widget class header files   */\n");
       fprintf(outfile, "#include <X11/AsciiText.h>  ");
       fprintf(outfile, "/* for asciiStringWidgetClass widget (mail) */\n");
     };
   if (widgetsUsed.dialog == TRUE)
     {
       fprintf(outfile, "#include <X11/Dialog.h>     ");
       fprintf(outfile, "/* include dialog widget class header files */\n");
     };
   if (widgetsUsed.vPaned == TRUE)
     {
       fprintf(outfile, "#include <X11/VPaned.h>     ");
       fprintf(outfile, "/* include vPaned widget class header files */\n");
     };
   if (widgetsUsed.scrollBar == TRUE)
     {
       fprintf(outfile, "#include <X11/Scroll.h>  ");
       fprintf(outfile, "/* include scrollbar widget class header files */\n");
     };
   if ((widgetsUsed.label == TRUE)
       OR (widgetsUsed.blankLine == TRUE)
       OR (widgetsUsed.keyedMailField == TRUE))
     {
       fprintf(outfile, "#include <X11/Label.h>      ");
       fprintf(outfile, "/* include label widget class header files  */\n\n");
     };

   /* If Ascii Text Widgets are used, make a #define to set the size */
   /* -------------------------------------------------------------- */
   if (widgetsUsed.asciiText == TRUE)
       fprintf(outfile, "#define ASCII_TEXT_STRING_SIZE 155\n\n");

   /* If popup menus are used, output new actions for action table */
   /* ------------------------------------------------------------ */
   if (widgetsUsed.popup == TRUE)
     {
       fprintf(outfile, "\n  /* Widget Action related globals */\n");
       fprintf(outfile, "  /* ----------------------------- */\n");
       fprintf(outfile, "XtActionsRec action_list[] = {\n");
       fprintf(outfile, "  {\"EditWidget\",    EditWidget},\n");
       fprintf(outfile, "  {\"MarkWidget\",    MarkWidget},\n");
       fprintf(outfile, "  { NULL, NULL}\n");
       fprintf(outfile, "  };\n\n");
       fprintf(outfile, "static int num_actions = 2;\n\n");
     };

   /* Output all global variable definitions, typedefs, and structs */
   /* ------------------------------------------------------------- */
   fprintf(outfile, "static Arg arg_list[40];\n\n");
   fprintf(outfile,
           "   XFontStruct *timesRoman12, *timesBold12;  ");
   fprintf(outfile, "/* font structures needed   */\n");
   fprintf(outfile, "   XFontStruct *fixedFont;\n\n");

   fprintf(outfile, DIVIDOR);
   fprintf(outfile, "\n");

   /* Output WBstrgen function definition, if needed */
   /* ---------------------------------------------- */
   if (widgetsUsed.asciiText == TRUE)
     {
       fprintf(outfile, "char *WBstrgen(str)\n");
       fprintf(outfile, "      char *str;\n {\n");
       fprintf(outfile, "    char *new_str;\n\n");
       fprintf(outfile, 
	       "    /* alloc a new buffer for an Ascii Text Widget */\n");
       fprintf(outfile, 
	       "    /* ------------------------------------------- */\n");
       fprintf(outfile, 
	       "    new_str = (char *) calloc(ASCII_TEXT_STRING_SIZE, 1);\n");
       fprintf(outfile, "    strcpy(new_str, str);\n");
       fprintf(outfile, "    return(new_str);\n");
       fprintf(outfile, " };         /* end of WBstrgen()  */\n\n");
       fprintf(outfile, DIVIDOR);
       fprintf(outfile, "\n");
     };

 };          /* end of write_headers() */

/**************************************************************************/

void write_main(outfile)
     FILE *outfile;
 {
   /* Start To output the Main() C code */
   /* --------------------------------- */
   fprintf(outfile, DIVIDOR);
   fprintf(outfile, DIVIDOR);
   fprintf(outfile, "\nmain(argc, argv)\n");
   fprintf(outfile, "     int argc;\n");
   fprintf(outfile, "     char *argv[];\n {\n");
   fprintf(outfile, "   Widget shell;          ");
   fprintf(outfile, "/* the top level application shell      */\n");
   fprintf(outfile, "   Widget base_widget;    ");
   fprintf(outfile, "/* the base widget (visible background) */\n");

   /* If popup menus are used, output code to add the new actions */
   /* ----------------------------------------------------------- */
   if (widgetsUsed.popup == TRUE)
     {
       fprintf(outfile, "\n   /* Set up new widget actions needed for ");
       fprintf(outfile, "Popup Menus */\n   ");
       fprintf(outfile, 
	       "/* ------------------------------------------------ */\n");
       fprintf(outfile, "   XtAddActions(action_list, num_actions);\n");
     };

   /* Output Main Xtoolkit/Widget initialization code */
   /* ----------------------------------------------- */
   fprintf(outfile, "\n   /* Initialize a toplevel root shell widget */\n");
   fprintf(outfile, "   /* --------------------------------------- */\n");
   fprintf(outfile, "   shell = XtInitialize(argv[0],\n");
   fprintf(outfile, "		       \"Top Level Shell\",\n");
   fprintf(outfile, "		       NULL, 0, &argc, argv);\n\n");
   fprintf(outfile, "   /* Allow top level shell resize by child */\n");
   fprintf(outfile, "   /* ------------------------------------- */\n");
   fprintf(outfile, "   XtSetArg(arg_list[0], XtNallowShellResize, TRUE);\n");
   fprintf(outfile, "   XtSetArg(arg_list[1], NULL,  (XtArgVal) NULL);\n");
   fprintf(outfile, "   XtSetValues(shell, arg_list, 1);\n\n");
   fprintf(outfile, 
	   "   /* Create main (background) widget for the application */\n");
   fprintf(outfile,
	   "   /* --------------------------------------------------- */\n");
   fprintf(outfile, "   XtSetArg(arg_list[0], XtNresizable, TRUE);\n");
   fprintf(outfile,
	   "   base_widget = XtCreateManagedWidget(\"Top Level Form\",\n");
   fprintf(outfile, "			       boxWidgetClass, shell,\n");
   fprintf(outfile, "			       arg_list, 1);\n\n");
   fprintf(outfile, "   create_all_widgets(base_widget);  ");
   fprintf(outfile, "/* Hang all widgets off base_widget */\n\n");
   fprintf(outfile,
    "   XtRealizeWidget(shell);           /* Make all widgets visible */\n\n");
   fprintf(outfile,
    "   XtMainLoop();                     /* Infinite event loop */\n\n");
   fprintf(outfile, " };        /* end of main() */\n\n");

 };     /* end of write_main() */

/****************************************************************/

int load_widget_defaults_from(widget)
     Widget widget;
 {
   int i;

   /* Gather probable default information about widgets by querying a widget */
   /* ---------------------------------------------------------------------- */

   i = 0;

   /* Load common instance variables (for a XtGetValues) */
   /* -------------------------------------------------- */
   /* load arg_list with useful properties */
   XtSetArg(arg_list[i], XtNjustify, &default_justify);               i++;
   XtSetArg(arg_list[i], XtNborderWidth, &default_borderwidth);       i++;
   XtSetArg(arg_list[i], XtNhighlightThickness,
	    &default_highlightThickness);                             i++;
   XtSetArg(arg_list[i], XtNborderColor, &default_borderColor);       i++;
   XtSetArg(arg_list[i], XtNforeground, &default_foreground);         i++;
   XtSetArg(arg_list[i], XtNbackground, &default_background);         i++;

   /* Load Form related instance variables, about placement */
   XtSetArg(arg_list[i], XtNvertDistance, &default_vertDistance);     i++;
   XtSetArg(arg_list[i], XtNhorizDistance, &default_horizDistance);   i++;
   XtSetArg(arg_list[i], XtNtop, &default_top);                       i++;
   XtSetArg(arg_list[i], XtNleft, &default_left);                     i++;
   XtSetArg(arg_list[i], XtNright, &default_right);                   i++;
   XtSetArg(arg_list[i], XtNbottom, &default_bottom);                 i++;
   XtSetArg(arg_list[i], XtNresizable, &default_resizable);           i++;
   XtSetArg(arg_list[i], NULL, NULL);

   /* Gather all this information from the current widget */
   XtGetValues(widget, arg_list, i);

 };          /* end of load_widget_defaults_from()  */

/****************************************************************/

int load_basic_arg_list(start_index)
     int start_index;
 {
   int i;

   i = start_index;

   /* Initialize string variables to null strings, first */
/*    label[0] = '\0'; */

   /* Load common instance variables (for a XtGetValues) */
   /* -------------------------------------------------- */
   XtSetArg(arg_list[i], XtNlabel, &label);                           i++;
   XtSetArg(arg_list[i], XtNjustify, &justify);                       i++;
   XtSetArg(arg_list[i], XtNborderWidth, &borderwidth);               i++;
   XtSetArg(arg_list[i], XtNheight, &height);                         i++;
   XtSetArg(arg_list[i], XtNwidth, &width);                           i++;
   XtSetArg(arg_list[i], XtNx, &x);                                   i++;
   XtSetArg(arg_list[i], XtNy, &y);                                   i++;
   XtSetArg(arg_list[i], XtNhighlightThickness, &highlightThickness); i++;
   XtSetArg(arg_list[i], XtNborderColor, &borderColor);               i++;
   XtSetArg(arg_list[i], XtNforeground, &foreground);                 i++;
   XtSetArg(arg_list[i], XtNbackground, &background);                 i++;

   return(i);        /* return index to next available free slot */

 };                      /* end of load_basic_arg_list() */

/****************************************************************/

void write_basic_arg_list(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 {
   /* Output all information gathered by load_basic_arg_list() */
   /* -------------------------------------------------------- */
   if ((strcmp(node->type, "form") != 0)
       && (strcmp(node->type, "box") != 0)
       && (strcmp(node->type, "viewport") != 0)
       && (strcmp(node->type, "vPane") != 0)
       && (strcmp(node->type, "ascii text") != 0))
     {
       fprintf(outfile, "   XtSetArg(arg_list[i], XtNlabel,\n");
       fprintf(outfile, "      \"%s\"); i++;\n", label);
     };
   if (justify != default_justify)
     {
       if (justify == XtJustifyCenter)
         fprintf(outfile, 
            "   XtSetArg(arg_list[i], XtNjustify, XtJustifyCenter); i++;\n");
       else if (justify == XtJustifyRight)
         fprintf(outfile, 
	    "   XtSetArg(arg_list[i], XtNjustify, XtJustifyRight); i++\n");
       else
         fprintf(outfile, 
	     "   XtSetArg(arg_list[i], XtNjustify, XtJustifyLeft); i++;\n");
     };
   if (borderwidth != default_borderwidth)
     fprintf(outfile, "   XtSetArg(arg_list[i], XtNborderWidth, %d); i++;\n",
	     borderwidth);
   fprintf(outfile, "   XtSetArg(arg_list[i], XtNheight, %d); i++;\n",
           height);
   fprintf(outfile, "   XtSetArg(arg_list[i], XtNwidth, %d); i++;\n",
	   width);
   fprintf(outfile, "   XtSetArg(arg_list[i], XtNx, %d); i++;\n", x);
   fprintf(outfile, "   XtSetArg(arg_list[i], XtNy, %d); i++;\n", y);
   if (highlightThickness != default_highlightThickness)
     fprintf(outfile, 
	     "   XtSetArg(arg_list[i], XtNhighlightThickness, %d); i++;\n",
	     highlightThickness);
   if (borderColor != default_borderColor)
     fprintf(outfile, "   XtSetArg(arg_list[i], XtNborderColor, %d); i++;\n",
	     borderColor);
   if (foreground != default_foreground)
     fprintf(outfile, "   XtSetArg(arg_list[i], XtNforeground, %d); i++;\n",
	     foreground);
   if (background != default_background)
     fprintf(outfile, "   XtSetArg(arg_list[i], XtNbackground, %d); i++;\n",
	     background);

 };              /* end of write_basic_arg_list()  */

/****************************************************************/

int load_form_arg_list(start_index)
     int start_index;
 {
   int i;

   i = start_index;

   /* Load common form related instance variables (for XtGetValues) */
   /* ------------------------------------------------------------- */
   XtSetArg(arg_list[i], XtNvertDistance, &vertDistance);             i++;
   XtSetArg(arg_list[i], XtNhorizDistance, &horizDistance);           i++;
   XtSetArg(arg_list[i], XtNtop, &top);                               i++;
   XtSetArg(arg_list[i], XtNleft, &left);                             i++;
   XtSetArg(arg_list[i], XtNright, &right);                           i++;
   XtSetArg(arg_list[i], XtNbottom, &bottom);                         i++;
   XtSetArg(arg_list[i], XtNresizable, &resizable);                   i++;
   XtSetArg(arg_list[i], XtNfromHoriz, &fromHoriz);                   i++;
   XtSetArg(arg_list[i], XtNfromVert, &fromVert);                     i++;

   return(i);        /* return index to next available free slot */
 };                      /* end of load_form_arg_list() */

/****************************************************************/

int write_form_arg_list(outfile)
     FILE *outfile;
 {
   WidgetNode *w;

   /* Output all information gathered by load_form_arg_list() */
   /* ------------------------------------------------------- */
   fprintf(outfile,
	   "   /* Form related instance variables, about placement */\n");
   if ((default_vertDistance != vertDistance) OR not_optimizing)
     fprintf(outfile, "   XtSetArg(arg_list[i], XtNvertDistance, %d); i++;\n",
	     vertDistance);
   if ((default_horizDistance != horizDistance) OR not_optimizing)
     fprintf(outfile, "   XtSetArg(arg_list[i], XtNhorizDistance, %d); i++;\n",
	     horizDistance);
   if ((default_left != left) OR not_optimizing)
     fprintf(outfile, 
	     "   XtSetArg(arg_list[i], XtNleft, %s); i++;\n", chain(left));
   if ((default_right != right) OR not_optimizing)
     fprintf(outfile,
	     "   XtSetArg(arg_list[i], XtNright, %s); i++;\n", chain(right));
   if ((default_top != top) OR not_optimizing)
     fprintf(outfile,
	     "   XtSetArg(arg_list[i], XtNtop, %s); i++;\n", chain(top));
   if ((default_bottom != bottom) OR not_optimizing)
     fprintf(outfile,
	     "   XtSetArg(arg_list[i], XtNbottom, %s); i++;\n", chain(bottom));
   if ((default_resizable != resizable) OR not_optimizing)
       fprintf(outfile,
	       "   XtSetArg(arg_list[i], XtNresizable, %s); i++;\n",
	       ((resizable == FALSE) ? "FALSE" : "TRUE"));
   if (fromHoriz != NULL)
     {
       w = find_widgets_node(fromHoriz);
       fprintf(outfile, "   XtSetArg(arg_list[i], XtNfromHoriz, %s); i++;\n",
	       ((w == NULL) ? "NULL" : w->varName));
     };
   if (fromVert != NULL)
     {
       w = find_widgets_node(fromVert);
       fprintf(outfile, "   XtSetArg(arg_list[i], XtNfromVert, %s); i++;\n",
	       ((w == NULL) ? "NULL" : w->varName));
     };

 };          /* end of write_form_arg_list()  */

/****************************************************************/

void write_general_widget(outfile, node, start_index, class, proper_type_name)
     FILE *outfile;
     WidgetNode *node;
     int start_index; /* 1st pos to start indexing arg_list[] for XtSetArg() */
     char *class;
     char *proper_type_name;
 { 
   int i;

   if (node->name == NULL)      /* If widget is un-named, name it first */
     node->name = genname();

   /* Gather useful information about this widget by querying the widget */
   /* ------------------------------------------------------------------ */
   /* load arg_list with useful properties */
   i = load_basic_arg_list(start_index);

   /* Load Form related instance variables, about placement */
   i = load_form_arg_list(i);
   XtSetArg(arg_list[i], NULL, NULL);

   /* Gather all this information from the current widget */
   XtGetValues(node->widget, arg_list, i);

   /* Write out a header comment about what this section of code will do */
   /* ------------------------------------------------------------------ */
   if ((strcmp(node->type, "form") != 0)
       && (strcmp(node->type, "blank line") != 0)
       && (strcmp(node->type, "box") != 0)
       && (strcmp(node->type, "viewport") != 0)
       && (strcmp(node->type, "vPane") != 0)
       && (strcmp(node->type, "ascii text") != 0))
     fprintf(outfile,
	     "\n   /* Create %s Widget(\"%s\"), whose parent is %s */\n\n",
	     proper_type_name, label,
	     ((node->parent_node == NULL)
	      ? "base_widget" : (node->parent_node)->varName));
   else
     fprintf(outfile,
	     "\n   /* Create %s Widget, whose parent is %s */\n\n",
	     proper_type_name,
	     ((node->parent_node == NULL)
	      ? "base_widget" : (node->parent_node)->varName));

   /* Write out the information gathered */
   /* ---------------------------------- */
   write_basic_arg_list(outfile, node);
   write_form_arg_list(outfile);

   /* Write out information in WidgetNode (node) structure, & create widget */
   /* --------------------------------------------------------------------- */
   fprintf(outfile,
	   "   XtSetArg(arg_list[i], XtNfont, %s); i++;\n",
	   fontvar(node->font));
   if (widgetsUsed.asciiText == TRUE)
     fprintf(outfile,
	   "   XtSetArg(arg_list[i], XtNstring, WBstrgen(\"%s\")); i++;\n",
	   node->string);
   fprintf(outfile, "   XtSetArg(arg_list[i], NULL, NULL);\n\n");
   fprintf(outfile, "   %s =\n",
	   ((node->varName != NULL) ? node->varName : "current_widget"));

   /* Output code to actually create the widget, & manage it */
   fprintf(outfile, "      XtCreateManagedWidget(\"%s\",\n", node->name);
   fprintf(outfile, "               %s,\n", class);
   fprintf(outfile, "               %s, arg_list, i);\n",
	   ((node->parent_node == NULL)
	    ? "base_widget" : (node->parent_node)->varName));

 };        /* end of write_general_widget()  */
/****************************************************************/

void write_button(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 { 
   /* Output C code to create a Button living inside a form (typical) */
   /* --------------------------------------------------------------- */
   fprintf(outfile, "   i = 0;\n");     /* initialize the index in output */
   write_general_widget(outfile, node, 0, "commandWidgetClass", "Button");

   /* If widget has a callback function, output code for widget to access it */
   /* ---------------------------------------------------------------------- */
   if (node->callback != NULL)
     {
       fprintf(outfile, "   XtAddCallback(%s, XtNcallback,\n", 
		 ((node->varName != NULL) ? node->varName : "current_widget"));
       fprintf(outfile, "                %s, NULL);\n", node->callback);
     };
 };        /* end of write_button()  */

/****************************************************************/

void write_label(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 {

   /* Output C code to create a Label living inside a form (typical) */
   /* --------------------------------------------------------------- */
   fprintf(outfile, "   i = 0;\n");     /* initialize the index in output */
   write_general_widget(outfile, node, 0, "labelWidgetClass", "Label");

 };        /* end of write_label()  */

/****************************************************************/

void write_blank_line(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 {

   /* Output C code to create a Blank Line living inside a form (typical) */
   /* ------------------------------------------------------------------- */
   fprintf(outfile, "   i = 0;\n");     /* initialize the index in output */
   write_general_widget(outfile, node, 0, "labelWidgetClass", "Blank Line");

 };        /* end of write_blank_line()  */

/****************************************************************/

void write_form(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 {

   /* Output C code to create a Form living inside a form (typical) */
   /* ------------------------------------------------------------- */
   fprintf(outfile, "   i = 0;\n");     /* initialize the index in output */
   write_general_widget(outfile, node, 0, "formWidgetClass", "Form");

 };        /* end of write_form()  */
/****************************************************************/

void write_box(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 {

   /* Output C code to create a Box living inside a form (typical) */
   /* ------------------------------------------------------------ */
   fprintf(outfile, "   i = 0;\n");     /* initialize the index in output */
   write_general_widget(outfile, node, 0, "boxWidgetClass", "Box");

 };        /* end of write_box()  */

/****************************************************************/

void write_ascii_text(outfile, node)
     FILE *outfile;
     WidgetNode *node;
 {

   /* Output C code to create a Ascii Text living inside a form (typical) */
   /* ------------------------------------------------------------------- */
   fprintf(outfile, "   i = 0;\n");     /* initialize the index in output */
   fprintf(outfile,
	   "   /* Ascii Text Widget specific instance variables */\n");
   fprintf(outfile,
	   "   XtSetArg(arg_list[i], XtNeditType, XttextEdit); i++;\n");
   fprintf(outfile,
     "   XtSetArg(arg_list[i], XtNlength, ASCII_TEXT_STRING_SIZE); i++;\n");
   fprintf(outfile, "   XtSetArg(arg_list[i], XtNtextOptions, ");
   fprintf(outfile, "resizeHeight | resizeWidth); i++;\n");

   write_general_widget(outfile, node, 0,
			"asciiStringWidgetClass", "Ascii Text");

 };        /* end of write_ascii_text()  */

/****************************************************************/

void write_declarations(outfile, list)
     FILE *outfile;
     WidgetNode *list;
 {
   WidgetNode *current_node;

   /* Declare variables for all parenting widgets */
   /* ------------------------------------------- */
   for (current_node = list; current_node != NULL; 
	current_node = current_node->next)
     {
       if (current_node->varName == NULL)
	   current_node->varName = genname();
       fprintf(outfile, "   Widget %s;\n", current_node->varName);
       write_declarations(outfile, current_node->first_child);
     };

 };       /* end of write_declarations() */

/****************************************************************/

void write_tree(outfile, list)
     FILE *outfile;
     WidgetNode *list;
 {
   WidgetNode *current_node;

   /* Output code to reproduce the necessary widgets */
   /* ---------------------------------------------- */
   for (current_node = list; current_node != NULL; 
	current_node = current_node->next)
     {
       if (strcmp(current_node->type, "button") == 0)     /* button     */
	 { write_button(outfile, current_node);
	   write_tree(outfile, current_node->first_child);
	 }
       else if (strcmp(current_node->type,
		       "label") == 0)                     /* label      */
	 {
	   write_label(outfile, current_node);
	   write_tree(outfile, current_node->first_child);
	 }
       else if (strcmp(current_node->type,
		       "blank line") == 0)                /* blankline  */
	 {
	   write_blank_line(outfile, current_node);
	   write_tree(outfile, current_node->first_child);
	 }
       else if (strcmp(current_node->type,
		       "form") == 0)                      /* form       */
	 {
	   write_form(outfile, current_node);
	   write_tree(outfile, current_node->first_child);
	 }
       else if (strcmp(current_node->type,
		       "box") == 0)                       /* box        */
	 {
	   write_box(outfile, current_node);
	   write_tree(outfile, current_node->first_child);
	 }
       else if (strcmp(current_node->type,
		       "ascii text") == 0)                /* ascii text */
	 {
	   write_ascii_text(outfile, current_node);
	   write_tree(outfile, current_node->first_child);
	 }
       else                                               /* ignore     */
	 ; 
     };
 };       /* end of write_tree() */

/****************************************************************/

void write_widgets(outfile)
     FILE *outfile;
 {
   fprintf(outfile, " create_all_widgets(base_widget)\n");
   fprintf(outfile, "     Widget base_widget;\n {\n   int i;\n");
   fprintf(outfile, "   Display *the_display;\n");
   write_declarations(outfile, HeadWidgetList);

   fprintf(outfile, "\n   /* Load in necessary fonts */\n");
   fprintf(outfile, "   /* ----------------------- */\n");
   fprintf(outfile, "   the_display = XtDisplay(base_widget);");
   fprintf(outfile, "      /* first get the display */\n");
   fprintf(outfile, "   timesRoman12 = XLoadQueryFont(the_display");
   fprintf(outfile, ", \"times-roman12\");\n");
   fprintf(outfile, "   timesBold12 = XLoadQueryFont(the_display");
   fprintf(outfile, ", \"times-bold12\");\n");
   fprintf(outfile, "   fixedFont = XLoadQueryFont(the_display");
   fprintf(outfile, ", \"fixed\");\n");

   /* output C code to create all widgets in tree */
   write_tree(outfile, HeadWidgetList);
   fprintf(outfile, "\n };    /* end of create_all_widgets() */\n\n");

 };       /* end of write_widgets() */
