 /*
  * Khoros: $Id: createglyph.c,v 1.4 1992/03/20 22:42:49 dkhoros Exp $
  */

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

 /*
  * $Log: createglyph.c,v $
 * Revision 1.4  1992/03/20  22:42:49  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 "cantata.h"

static int  make_glyph();
static void create_glyph(), 
	    create_macro(), 
	    create_control(),
	    create_comment();

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name:  createglyph.c                         <<<<
   >>>>                                                       <<<<
   >>>>   description:  This file is to take a tree structure <<<<
   >>>>                 form of the form and make a widget    <<<<
   >>>>                 glyph representing it.                <<<<
   >>>>                                                       <<<<
   >>>>      routines:  				      <<<<
   >>>>                 xvl_create_pixmap()                   <<<<
   >>>>                 xvl_create_clipboard()                <<<<
   >>>>			xvl_create_glyph()                    <<<<
   >>>>                                                       <<<<
   >>>> modifications:					      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/* includes for bitmaps */
#include "bitmap/form.bit"
#include "bitmap/io.bit"
#include "bitmap/io_opt.bit"
#include "bitmap/run.bit"
#include "bitmap/error.bit"
#include "bitmap/reset.bit"
#include "bitmap/kill.bit"
#include "bitmap/stop.bit"
#include "bitmap/remote.bit"

#include "bitmap/forms.bit"
#include "bitmap/ios.bit"
#include "bitmap/io_opts.bit"
#include "bitmap/runs.bit"
#include "bitmap/errors.bit"
#include "bitmap/resets.bit"
#include "bitmap/kills.bit"
#include "bitmap/stops.bit"
#include "bitmap/remotes.bit"
#include "bitmap/dav.bit"
#include "bitmap/clipboard.bit"

static	 XtTranslations button_translation;
static	 char	        button_translation_table[] =
	"<Btn1Down>:	set() notify() unset()	\n\
	 <Btn1Up>:	reset()			";

static Pixmap form, io, io_opt, run, destroy, stop, error, reset, remote;



/************************************************************
*
* Routine Name:  xvl_create_pixmap
*
*      Purpose:  This routine is used to create the local pixmaps
*		 used to build the glyphs.  There are two sets of
*		 pixmaps.  Normal and small.  The small pixmaps help
*		 enable us to make smaller glyphs.
*
*        Input:  display - the display in which we will initialize the
*			   pixmaps for.
*
*       Output:  Update local pixmaps for glyph creation
*
*
*   Written By: Stephanie Hallet & Mark Young
*
*************************************************************/


xvl_create_pixmaps(display)

Display *display;
{
	int	 screen = XDefaultScreen(display);
	Window	 rootwindow = XRootWindow(display, screen);


	/*
	 *  Create the new translations for the bitmap command (button)
	 *  widgets.
	 */
	button_translation = XtParseTranslationTable(button_translation_table);


	/*
	 *  Create the regular bitmaps to be used to create our glyphs.
	 */
	run_pix = XCreateBitmapFromData(display, rootwindow, run_bits,
					 run_width, run_height);
	error_pix = XCreateBitmapFromData(display, rootwindow, error_bits,
					 error_width, error_height);
	reset_pix = XCreateBitmapFromData(display, rootwindow, reset_bits,
					 reset_width, reset_height);
	form_pix = XCreateBitmapFromData(display, rootwindow, form_bits,
					 form_width, form_height);
	destroy_pix = XCreateBitmapFromData(display, rootwindow, kill_bits,
					    kill_width, kill_height);
	io_pix = XCreateBitmapFromData(display, rootwindow, io_bits, io_width,
				       io_height);
	io_opt_pix = XCreateBitmapFromData(display, rootwindow, io_opt_bits,
					   io_opt_width, io_opt_height);
	stop_pix = XCreateBitmapFromData(display, rootwindow, stop_bits,
					 stop_width, stop_height);
	remote_pix = XCreateBitmapFromData(display, rootwindow, remote_bits,
					 remote_width, remote_height);

	/*
	 *  Create the small bitmaps to be used to create our small glyphs.
	 */
	runs_pix = XCreateBitmapFromData(display, rootwindow, runs_bits,
					 runs_width, runs_height);
	errors_pix = XCreateBitmapFromData(display, rootwindow, errors_bits,
					 errors_width, errors_height);
	resets_pix = XCreateBitmapFromData(display, rootwindow, resets_bits,
					 resets_width, resets_height);
	forms_pix = XCreateBitmapFromData(display, rootwindow, forms_bits,
					 forms_width, forms_height);
	destroys_pix = XCreateBitmapFromData(display, rootwindow, kills_bits,
					    kills_width, kills_height);
	ios_pix = XCreateBitmapFromData(display, rootwindow, ios_bits,
					ios_width, ios_height);
	io_opts_pix = XCreateBitmapFromData(display, rootwindow, io_opts_bits,
					   io_opts_width, io_opts_height);
	stops_pix = XCreateBitmapFromData(display, rootwindow, stops_bits,
					 stops_width, stops_height);
	remotes_pix = XCreateBitmapFromData(display, rootwindow, remotes_bits,
					 remotes_width, remotes_height);

	/*
	 *  Create data available (dav) and modified glyph label bitmaps
	 */
	dav_pix = XCreateBitmapFromData(display, rootwindow, dav_bits,
					 dav_width, dav_height);
}



/************************************************************
*
* Routine Name:  xvl_create_clipboard
*
*      Purpose:  This routine is used to create the local pixmaps
*		 used to build the glyphs.  There are two sets of
*		 pixmaps.  Normal and small.  The small pixmaps help
*		 enable us to make smaller glyphs.
*
*        Input:  None
*
*       Output:  Update local pixmaps for glyph creation
*
*
*   Written By: Mark Young
*
*************************************************************/


xvl_create_clipboard(workspace)

Workspace *workspace;
{
	Workspace *attributes;
	static  Pixmap clipboard_icon = NULL;

	Display *display = XtDisplay(workspace->toplevel);
	Window	rootwindow = XRootWindow(display, XDefaultScreen(display));


	/*
	 *  First make sure that a clipboard_menu exists.  If not then we
	 *  should not create the clipboard icon.  Or if the clipboard is
	 *  the workspace we are creating then don't create the clipboard
	 *  icon.
	 */
	if (clipboard_menu == NULL || clipboard == workspace)
	   return;

	/*
	 *  Create clipboard icon
	 */
	if (clipboard_icon == NULL)
	{
	   clipboard_icon =
	   clipboard_pix  = XCreateBitmapFromData(display, rootwindow,
			clipboard_bits, clipboard_width, clipboard_height);
	}
	workspace->clipboard = xvf_create_bitmap(workspace->toplevel,"clipicon",
			clipboard_icon, NULL, NULL, 10, 10, NULL, 0);
	XtAddCallback(workspace->clipboard, XtNcallback, xvl_clipboard_cb,
		(char *) workspace);
	XRaiseWindow(display, XtWindow(workspace->clipboard));

	attributes = xvl_get_attributes(workspace);
	if (attributes->show_clipboard)
	   XtMapWidget(workspace->clipboard);
	else
	   XtUnmapWidget(workspace->clipboard);

	xvl_update_clipboard(workspace);
}



/************************************************************
*
* Routine Name:  xvl_create_glyph
*
*      Purpose:  This routine is used to destroy the old glyph
*		 and create a new glyph in it's place, if a previous
*		 glyph existed.  We use make_glyph to actually recreate
*		 it.  The routine saves whether the glyph was mapped
*		 at the time of creation.
*
*        Input:  glyph  - the glyph that we are going to (re)create.
*
*
*   Written By: Mark Young
*
*************************************************************/


int xvl_create_glyph(glyph)

Glyph	*glyph;
{
	Widget	  widget;

	/*
	 *  Check to see if the glyph exists so that we can destroy it later.
	 */
	if (glyph->toplevel)
	   widget = glyph->toplevel;
	else
	   widget = NULL;

	/*
	 *  build the glyph
	 */
	if (glyph->workspace->toplevel == NULL)
	{
	   if (widget != NULL)
	      XtUnmapWidget(widget);
	   return(True);
	}
	else if (!make_glyph(glyph))
	{
	   glyph->toplevel = widget;
	   return(False);
	}

	/*
	 *  Destroy the old glyph
	 */
	if (widget != NULL)
	{
	   XtUnmapWidget(widget);
	   XtDestroyWidget(widget);
	   xvl_update_mapping(glyph);
	}
	return(True);
}



/************************************************************
*
* Routine Name:  make_glyph
*
*      Purpose:  This routine is used to create an cantata glyph.
*		 We use the xvforms creation routines to create
*		 the actual widgets.  The routine is used to
*		 compute the layout of the widget.
*
*        Input:  glyph      - the glyph to be created
*
*
*   Written By: Mark Young
*
*************************************************************/


static int make_glyph(glyph)

Glyph		*glyph;		
{
	Workspace    *workspace, *attributes;


	workspace = glyph->workspace;
	attributes = xvl_get_attributes(workspace);

	if (attributes->small_glyphs == True)
	{
	   io		 = ios_pix;
	   io_opt	 = io_opts_pix;
	   run		 = runs_pix;
	   error	 = errors_pix;
	   reset	 = resets_pix;
	   destroy	 = destroys_pix;
	   form		 = forms_pix;
	   stop		 = stops_pix;
	   remote	 = remotes_pix;
	}
	else
	{
	   io		 = io_pix;
	   io_opt	 = io_opt_pix;
	   run		 = run_pix;
	   error	 = error_pix;
	   reset	 = reset_pix;
	   destroy	 = destroy_pix;
	   form		 = form_pix;
	   stop		 = stop_pix;
	   remote	 = remote_pix;
	}

	switch(glyph->type)
	{
	   case GLYPH:
	   case COMMAND:
		create_glyph(glyph);
		break;

	   case PROCEDURE:
		create_macro(glyph);
		break;

	   case CONTROL:
		create_control(glyph);
		break;

	   case COMMENT:
		create_comment(glyph);
		break;

	   case IMAGES:
	        xvf_error_wait("Unsupported glyph type (IMAGES)!",
				"make_glyph", NULL);
		return(False);

	   default:
	        xvf_error_wait("Unknown glyph type!", "make_glyph", NULL);
	        return(False);
	}

	/*
	 *  Create the glyph and update the glyph to show if the glyph
	 *  is currently modified or not 
	 */
	xvf_realize_widget(glyph->toplevel);
	xvl_query_widget(glyph->toplevel, NULL, NULL, &glyph->width,
			&glyph->height);
	xvl_update_modified(glyph);
	xvl_update_selected(glyph);
	xvl_update_distributed(glyph);

	if (glyph->xpos != -1 && glyph->ypos != -1)
	   xvl_position_glyph(glyph);
	else
	   xvl_map_glyph(glyph);

	return(True);
}

static void create_glyph(glyph)

Glyph		*glyph;		
{
	Node		*node;
	NodeList	*list;
	Workspace	*workspace, *attributes;

	Dimension  width;
	Arg	   args[25], input_args[10], output_args[10];
	char	   name[512];
	Widget     widget, back, vert_off, horz_off, label_off;
	int	   i, j, x, y, output_num, input_num, temp,
		   pixmap_height, y_off;

	workspace = glyph->workspace;
	attributes = xvl_get_attributes(workspace);

	display   = XtDisplay(workspace->back);
	if (attributes->small_glyphs == True)
	{
	   pixmap_height = kills_height;
	   x = 1;
	   y_off = 5;
	}
	else
	{
	   pixmap_height = kill_height;
	   x = 2;
	   y_off = 8;
	}

	/*
	 *  Create the back to the glyph.
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.glyph_bd);
	glyph->toplevel =
	glyph->back     = xvf_create_back(workspace->back, glyph->toplevel_name,
				 NULL, NULL, glyph->xpos, glyph->ypos, args, i);

        /*
         *  Place the "destroy", "form" & "run" buttons at the top of 
         *  the widget.
         */
	back = glyph->back;

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.destroy_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.destroy_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.destroy_bd);
	glyph->destroy = xvf_create_bitmap(back, "destroy", destroy,
				NULL, NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.form_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.form_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.form_bd);
	glyph->form = xvf_create_bitmap(back,"glyph_form",form, glyph->destroy,
				NULL, x, x, args, i);
	horz_off = glyph->form;

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.error_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.error_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.error_bd);
	XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	XtSetArg(args[i], XtNshapeStyle, XmuShapeOval);		i++;
	glyph->error = xvf_create_bitmap(back, "error", error,
				glyph->destroy, glyph->form, x, x + 5, args, i);


	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.remote_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.remote_bg);
	XtSetArg(args[i], XtNborderWidth, 0);			i++;
	XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	glyph->remote = xvf_create_bitmap(back, "remote", remote,
				glyph->destroy, glyph->form, x+2, x+5, args, i);

	if (glyph->type == CONTROL)
	{
	   i = 0;
	   xvl_set_color(args, &i, XtNforeground, wresource.reset_fg);
	   xvl_set_color(args, &i, XtNbackground, wresource.reset_bg);
	   xvl_set_color(args, &i, XtNborderColor, wresource.reset_bd);
	   glyph->reset = xvf_create_bitmap(back, "reset", reset, horz_off,
				NULL, x, x, args, i);
	   XtAddCallback(glyph->reset, XtNcallback, xvl_reset_cb, 
	                        (caddr_t) glyph);
	   XtOverrideTranslations(glyph->reset, button_translation);
	   horz_off = glyph->reset;

	}

	if (glyph->exec_type != NORUN)
	{

	   i = 0;
	   xvl_set_color(args, &i, XtNforeground, wresource.stop_fg);
	   xvl_set_color(args, &i, XtNbackground, wresource.stop_bg);
	   xvl_set_color(args, &i, XtNborderColor, wresource.stop_bd);
	   glyph->stop = xvf_create_bitmap(back, "stop", stop, horz_off,
				NULL, x, x, args, i);

	   i = 0;
	   xvl_set_color(args, &i, XtNforeground, wresource.run_fg);
	   xvl_set_color(args, &i, XtNbackground, wresource.run_bg);
	   xvl_set_color(args, &i, XtNborderColor, wresource.run_bd);
	   glyph->run = xvf_create_bitmap(back, "run", run, horz_off,
				NULL, x, x, args, i);

	   XtOverrideTranslations(glyph->stop, button_translation);
	   XtOverrideTranslations(glyph->run, button_translation);
	   XtAddCallback(glyph->stop, XtNcallback, xvl_run_cb, (caddr_t) glyph);
	   XtAddCallback(glyph->run,  XtNcallback, xvl_run_cb, (caddr_t) glyph);
	}

	/*
	 *  Add the appropriate callback routines to the widgets
	 */
	XtOverrideTranslations(glyph->form, button_translation);
	XtAddCallback(glyph->form, XtNcallback, xvl_form_cb, (caddr_t) glyph);
	XtAddCallback(glyph->error, XtNcallback, xvl_error_cb, (caddr_t) glyph);
	XtAddCallback(glyph->destroy, XtNcallback, xvl_destroy_cb,
		      (caddr_t) glyph);
	XtAddCallback(glyph->remote, XtNcallback, xvl_distributed_cb,
		      (caddr_t) glyph);

	/*
	 *  Build the output widget buttons.
	 */
	output_num = 0;
	vert_off = glyph->destroy;
	list = glyph->output_list;
	y = y_off;

	/*
	 *  Set the args for the dav available pixmap
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	XtSetArg(args[i], XtNbitmap, dav_pix);				i++;
	XtSetArg(args[i], XtNwidth, dav_height+2);			i++;
	XtSetArg(args[i], XtNheight, dav_width+2);			i++;
	XtSetArg(args[i], XtNinternalHeight, 1);			i++;
	XtSetArg(args[i], XtNinternalWidth, 1);				i++;
	XtSetArg(args[i], XtNborderWidth, 0);				i++;

	/*
	 *  Set the args for the dav available pixmap
	 */
	j = 0;
	xvl_set_color(output_args, &j, XtNforeground, wresource.output_fg);
	xvl_set_color(output_args, &j, XtNbackground, wresource.output_bg);
	xvl_set_color(output_args, &j, XtNborderColor, wresource.output_bd);
	while (list != NULL)
	{
	   /*
	    *  Make unique output names for the i/o widgets.
	    */
	   sprintf(name, "output%d", output_num);

	   node = list->node;

	   /*
	    *  Create the data available (dav) label widget
	    */
	   node->dav_widget = xvf_create_label(back, NULL, horz_off, vert_off,
			x-(dav_width+2), y+y_off/2, 0, NULL, args, i);
	   xvl_update_dav(node);

	   if (node->selected)
	      widget = xvf_create_bitmap(back, name, io, node->dav_widget, 
                                         vert_off, 0, y, output_args, j);
	   else
	      widget = xvf_create_bitmap(back, name, io_opt, node->dav_widget, 
                                         vert_off, 0, y, output_args, j);

	   node->widget = widget;
	   XtAddCallback(widget, XtNcallback, xvl_output_cb, node);
	   XtOverrideTranslations(widget, button_translation);

	   /*
	    *  Advance to the next output widget node.
	    */
	   list = list->next; output_num++;
	   vert_off = widget;
	   y = 1;
	}
	label_off = vert_off;
	y = y_off;

	/*
	 *  Build the input widget buttons.
	 */
	input_num = 0;
	vert_off = glyph->destroy;
	list = glyph->input_list;

	j = 0;
	xvl_set_color(input_args, &j, XtNforeground, wresource.input_fg);
	xvl_set_color(input_args, &j, XtNbackground, wresource.input_bg);
	xvl_set_color(input_args, &j, XtNborderColor, wresource.input_bd);
	while (list != NULL)
	{
	   /*
	    *  Make a unique input names for the i/o widgets.
	    */
	   sprintf(name, "input%d", input_num);

	   node = list->node;
	   if (node->selected)
	      widget = xvf_create_bitmap(back, name, io, NULL, vert_off, 2, y,
					 input_args, j);
	   else
	      widget = xvf_create_bitmap(back, name, io_opt, NULL, vert_off,2,y,
					 input_args, j);

	   node->widget = widget;
	   XtAddCallback(widget, XtNcallback, xvl_input_cb, node);
	   XtOverrideTranslations(widget, button_translation);

	   /*
	    *  Create the data available (dav) label widget
	    */
	   node->dav_widget = xvf_create_label(back, NULL, widget, vert_off,
				0, y+y_off/2, 0, NULL, args, i);
	   xvl_update_dav(node);

	   /*
	    *  Advance to the next input widget node.
	    */
	   list = list->next; input_num++;
	   vert_off = widget;
	   y = 1;
	}

	/*
	 *  Place the glyph label on the bottom of the widget
	 *  below the input and output widgets buttons.
	 */
	if (input_num > output_num)
	{
	   label_off = vert_off;
	   temp = input_num;
	}
	else
	{
	   temp = output_num;
	}

	/* Compute the vertical offset */
	y = (MAX(temp, 2) - temp) * (pixmap_height + 2) + 1;
	if (temp <= 1)
	   y = y - 3;

	/*
	 *  Create the glyph's label.
	 */
	xvl_query_widget(glyph->back, NULL, NULL, &width, NULL);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.label_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.label_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.label_bd);
	XtSetArg(args[i], XtNleft, XtChainLeft);			i++;
	XtSetArg(args[i], XtNright, XtChainRight);			i++;
	XtSetArg(args[i], XtNinternalHeight, 0);			i++;
	XtSetArg(args[i], XtNinternalWidth, 0);				i++;
	XtSetArg(args[i], XtNborderWidth, 0);				i++;
	glyph->label = xvf_create_label(back, glyph->label_str, NULL,
			label_off, 0, y, (int) width-4, xvf_font, args, i);

	XRaiseWindow(XtDisplay(glyph->error), XtWindow(glyph->error));
}


static void create_macro(glyph)

Glyph		*glyph;		
{
	Node		*node;
	NodeList	*list;
	Workspace	*workspace, *attributes;

	Dimension  width;
	Arg	   args[25], input_args[10], output_args[10];
	char	   name[512];
	Widget     widget, back, vert_off, horz_off, label_off;

	int	   i, j, x, y, output_num, input_num, temp,
		   pixmap_height, y_off;

	workspace = glyph->workspace;
	attributes = xvl_get_attributes(workspace);

	display   = XtDisplay(workspace->back);
	if (attributes->small_glyphs == True)
	{
	   pixmap_height = kills_height;
	   x = 1;
	   y_off = 5;
	}
	else
	{
	   pixmap_height = kill_height;
	   x = 2;
	   y_off = 8;
	}

	/*
	 *  Create the back to the glyph.
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.glyph_bd);
	glyph->toplevel = xvf_create_back(workspace->back, glyph->toplevel_name,
				 NULL, NULL, glyph->xpos, glyph->ypos, args, i);

	i = 0;
	XtSetArg(args[i], XtNmappedWhenManaged, True);		i++;
	back =
	glyph->back = xvf_create_back(glyph->toplevel, glyph->toplevel_name,
				NULL, NULL, x, x, args, i);

        /*
         *  Place the "destroy", "form" & "run" buttons at the top of 
         *  the widget.
         */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.destroy_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.destroy_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.destroy_bd);
	glyph->destroy = xvf_create_bitmap(back, "destroy", destroy, NULL,
				NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.form_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.form_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.form_bd);
	glyph->form = xvf_create_bitmap(back, "glyph_form", form,glyph->destroy,
				NULL, x, x, args, i);
	horz_off = glyph->form;

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.error_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.error_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.error_bd);
	XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	XtSetArg(args[i], XtNshapeStyle, XmuShapeOval);		i++;
	glyph->error = xvf_create_bitmap(back, "error", error, glyph->destroy,
				glyph->form, x, x + 5, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.stop_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.stop_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.stop_bd);
	glyph->stop = xvf_create_bitmap(back, "stop", stop, horz_off,
				NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.run_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.run_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.run_bd);
	glyph->run = xvf_create_bitmap(back, "run", run, horz_off,
				NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.remote_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.remote_bg);
	XtSetArg(args[i], XtNborderWidth, 0);			i++;
	XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	glyph->remote = xvf_create_bitmap(back, "remote", remote,
				glyph->destroy, glyph->form, x+2, x+5, args, i);

	/*
	 *  Add the appropriate callback routines to the widgets
	 */
	XtAddCallback(glyph->stop, XtNcallback, xvl_run_cb, (caddr_t) glyph);
	XtAddCallback(glyph->run,  XtNcallback, xvl_run_cb, (caddr_t) glyph);
	XtAddCallback(glyph->form, XtNcallback, xvl_form_cb, (caddr_t) glyph);
	XtAddCallback(glyph->error, XtNcallback, xvl_error_cb, (caddr_t) glyph);
	XtAddCallback(glyph->destroy, XtNcallback, xvl_destroy_cb,
		      (caddr_t) glyph);
	XtAddCallback(glyph->remote, XtNcallback, xvl_distributed_cb,
		      (caddr_t) glyph);
	XtOverrideTranslations(glyph->stop, button_translation);
	XtOverrideTranslations(glyph->run, button_translation);
	XtOverrideTranslations(glyph->form, button_translation);

	/*
	 *  Set the args for the dav available pixmap
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	XtSetArg(args[i], XtNbitmap, dav_pix);				i++;
	XtSetArg(args[i], XtNwidth, dav_height+2);			i++;
	XtSetArg(args[i], XtNheight, dav_width+2);			i++;
	XtSetArg(args[i], XtNinternalHeight, 1);			i++;
	XtSetArg(args[i], XtNinternalWidth, 1);				i++;
	XtSetArg(args[i], XtNborderWidth, 0);				i++;

	/*
	 *  Set the args for the dav available pixmap
	 */
	j = 0;
	xvl_set_color(output_args, &j, XtNforeground, wresource.output_fg);
	xvl_set_color(output_args, &j, XtNbackground, wresource.output_bg);
	xvl_set_color(output_args, &j, XtNborderColor, wresource.output_bd);

	/*
	 *  Build the output widget buttons.
	 */
	output_num = 0;
	vert_off = glyph->destroy;
	list = glyph->output_list;
	y = y_off;
	while (list != NULL)
	{
	   /*
	    *  Make unique output names for the i/o widgets.
	    */
	   sprintf(name, "output%d", output_num);

	   node = list->node;

	   /*
	    *  Create the data available (dav) label widget
	    */
	   node->dav_widget = xvf_create_label(back, NULL, horz_off, vert_off,
				x-(dav_width+2), y+y_off/2, 0, NULL, args, i);
	   xvl_update_dav(node);

	   if (node->selected)
	      widget = xvf_create_bitmap(back, name, io, node->dav_widget, 
                                         vert_off, 0, y, output_args, j);
	   else
	      widget = xvf_create_bitmap(back, name, io_opt, node->dav_widget, 
                                         vert_off, 0, y, output_args, j);

	   node->widget = widget;
	   XtAddCallback(widget, XtNcallback, xvl_output_cb, node);
	   XtOverrideTranslations(widget, button_translation);

	   /*
	    *  Advance to the next output widget node.
	    */
	   list = list->next; output_num++;
	   vert_off = widget;
	   y = 1;
	}
	label_off = vert_off;
	y = y_off;

	/*
	 *  Build the input widget buttons.
	 */
	input_num = 0;
	vert_off = glyph->destroy;
	list = glyph->input_list;

	j = 0;
	xvl_set_color(input_args, &j, XtNforeground, wresource.input_fg);
	xvl_set_color(input_args, &j, XtNbackground, wresource.input_bg);
	xvl_set_color(input_args, &j, XtNborderColor, wresource.input_bd);
	while (list != NULL)
	{
	   /*
	    *  Make a unique input names for the i/o widgets.
	    */
	   sprintf(name, "input%d", input_num);

	   node = list->node;
	   if (node->selected)
	      widget = xvf_create_bitmap(back, name, io, NULL, vert_off, 2, y,
					 input_args, j);
	   else
	      widget = xvf_create_bitmap(back, name, io_opt, NULL, vert_off,2,y,
					 input_args, j);

	   node->widget = widget;
	   XtAddCallback(widget, XtNcallback, xvl_input_cb, node);
	   XtOverrideTranslations(widget, button_translation);

	   /*
	    *  Create the data available (dav) label widget
	    */
	   node->dav_widget = xvf_create_label(back, NULL, widget, vert_off,
				0, y+y_off/2, 0, NULL, args, i);
	   xvl_update_dav(node);

	   /*
	    *  Advance to the next input widget node.
	    */
	   list = list->next; input_num++;
	   vert_off = widget;
	   y = 1;
	}

	/*
	 *  Place the glyph label on the bottom of the widget
	 *  below the input and output widgets buttons.
	 */
	if (input_num > output_num)
	{
	   label_off = vert_off;
	   temp = input_num;
	}
	else
	{
	   temp = output_num;
	}

	/* Compute the vertical offset */
	y = (MAX(temp, 2) - temp) * (pixmap_height + 2) + 1;
	if (temp <= 1)
	   y = y - 3;

	/*
	 *  Create the glyph's label.
	 */
	xvl_query_widget(glyph->back, NULL, NULL, &width, NULL);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.label_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.label_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.label_bd);
	XtSetArg(args[i], XtNleft, XtChainLeft);                        i++;
	XtSetArg(args[i], XtNright, XtChainRight);                      i++;
	XtSetArg(args[i], XtNinternalHeight, 0);                        i++;
	XtSetArg(args[i], XtNinternalWidth, 0);                         i++;
	XtSetArg(args[i], XtNborderWidth, 0);                           i++;
	glyph->label = xvf_create_label(back, glyph->label_str, NULL,
			label_off, 0, y, (int) width-4, xvf_font, args, i);

	XRaiseWindow(XtDisplay(glyph->error), XtWindow(glyph->error));
}

static void create_control(glyph)

Glyph		*glyph;		
{
	Node		*node;
	NodeList	*list;
	Workspace	*workspace, *attributes;

	Dimension  width;
	Arg	   args[25], input_args[10], output_args[10];
	char	   name[512];
	Widget     widget, back, vert_off, horz_off, label_off;
	int	   i, j, x, y, output_num, input_num, temp, pixmap_height,y_off;


	workspace = glyph->workspace;
	attributes = xvl_get_attributes(workspace);

	display   = XtDisplay(workspace->back);
	if (attributes->small_glyphs == True)
	{
	   pixmap_height = kills_height;
	   x = 1;
	   y_off = 5;
	}
	else
	{
	   pixmap_height = kill_height;
	   x = 2;
	   y_off = 8;
	}

	/*
	 *  Create the back to the glyph.
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.glyph_bd);
	glyph->toplevel =
	glyph->back     = xvf_create_back(workspace->back, glyph->toplevel_name,
				 NULL, NULL, glyph->xpos, glyph->ypos, args, i);

        /*
         *  Place the "destroy", "form" & "run" buttons at the top of 
         *  the widget.
         */
	back = glyph->back;

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.destroy_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.destroy_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.destroy_bd);
	glyph->destroy = xvf_create_bitmap(back, "destroy", destroy, NULL,
				NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.form_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.form_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.form_bd);
	glyph->form = xvf_create_bitmap(back, "glyph_form", form, glyph->destroy,
				NULL, x, x, args, i);
	horz_off = glyph->form;

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.error_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.error_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.error_bd);
	XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	XtSetArg(args[i], XtNshapeStyle, XmuShapeOval);		i++;
	glyph->error = xvf_create_bitmap(back, "error", error, glyph->destroy,
				glyph->form, x, x + 5, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.reset_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.reset_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.reset_bd);
	glyph->reset = xvf_create_bitmap(back, "reset", reset, horz_off,
				NULL, x, x, args, i);
	XtAddCallback(glyph->reset, XtNcallback, xvl_reset_cb, 
	                        (caddr_t) glyph);
	XtOverrideTranslations(glyph->reset, button_translation);
	horz_off = glyph->reset;

	if (glyph->exec_type != NORUN)
	{
	   /*
	    *  Check to see if this a control loop.  If so then enable remote
	    *  execution so that a loop can be scheduled remotely.
	    *
	    *  *This is currently disabled since we can't efficiently check
	    *  if a glyph is part of some sub-loop*
	    */

	   /* if (xvl_check_if_control_loop(glyph) == True) */
	   {
	      i = 0;
	      xvl_set_color(args, &i, XtNforeground, wresource.remote_fg);
	      xvl_set_color(args, &i, XtNbackground, wresource.remote_bg);
	      XtSetArg(args[i], XtNborderWidth, 0);			i++;
	      XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	      glyph->remote = xvf_create_bitmap(back, "remote", remote,
				glyph->destroy, glyph->form, x+2, x+5, args, i);
	   }

	   i = 0;
	   xvl_set_color(args, &i, XtNforeground, wresource.stop_fg);
	   xvl_set_color(args, &i, XtNbackground, wresource.stop_bg);
	   xvl_set_color(args, &i, XtNborderColor, wresource.stop_bd);
	   glyph->stop = xvf_create_bitmap(back, "stop", stop, horz_off,
				NULL, x, x, args, i);

	   i = 0;
	   xvl_set_color(args, &i, XtNforeground, wresource.run_fg);
	   xvl_set_color(args, &i, XtNbackground, wresource.run_bg);
	   xvl_set_color(args, &i, XtNborderColor, wresource.run_bd);
	   glyph->run = xvf_create_bitmap(back, "run", run, horz_off,
				NULL, x, x, args, i);
	   XtAddCallback(glyph->stop, XtNcallback, xvl_run_cb, (caddr_t) glyph);
	   XtAddCallback(glyph->run,  XtNcallback, xvl_run_cb, (caddr_t) glyph);
	   XtAddCallback(glyph->remote, XtNcallback, xvl_distributed_cb,
		      (caddr_t) glyph);
	   XtOverrideTranslations(glyph->stop, button_translation);
	   XtOverrideTranslations(glyph->run, button_translation);
	}

	/*
	 *  Add the appropriate callback routines to the widgets
	 */
	XtOverrideTranslations(glyph->form, button_translation);
	XtAddCallback(glyph->form, XtNcallback, xvl_form_cb, (caddr_t) glyph);
	XtAddCallback(glyph->error, XtNcallback, xvl_error_cb, (caddr_t) glyph);
	XtAddCallback(glyph->destroy, XtNcallback, xvl_destroy_cb,
		      (caddr_t) glyph);

	/*
	 *  Set the args for the dav available pixmap
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	XtSetArg(args[i], XtNbitmap, dav_pix);				i++;
	XtSetArg(args[i], XtNwidth, dav_height+2);			i++;
	XtSetArg(args[i], XtNheight, dav_width+2);			i++;
	XtSetArg(args[i], XtNinternalHeight, 1);			i++;
	XtSetArg(args[i], XtNinternalWidth, 1);				i++;
	XtSetArg(args[i], XtNborderWidth, 0);				i++;

	/*
	 *  Set the args for the dav available pixmap
	 */
	j = 0;
	xvl_set_color(output_args, &j, XtNforeground, wresource.output_fg);
	xvl_set_color(output_args, &j, XtNbackground, wresource.output_bg);
	xvl_set_color(output_args, &j, XtNborderColor, wresource.output_bd);

	/*
	 *  Build the output widget buttons.
	 */
	output_num = 0;
	vert_off = glyph->destroy;
	list = glyph->output_list;
	y = y_off;
	while (list != NULL)
	{
	   /*
	    *  Make unique output names for the i/o widgets.
	    */
	   sprintf(name, "output%d", output_num);

	   node = list->node;

	   /*
	    *  Create the data available (dav) label widget
	    */
	   node->dav_widget = xvf_create_label(back, NULL, horz_off, vert_off,
				x-9, y+y_off/2, 0, NULL, args, i);
	   xvl_update_dav(node);

	   if (node->selected)
	      widget = xvf_create_bitmap(back, name, io, node->dav_widget, 
                                         vert_off, 0, y, output_args, j);
	   else
	      widget = xvf_create_bitmap(back, name, io_opt, node->dav_widget, 
                                         vert_off, 0, y, output_args, j);

	   node->widget = widget;
	   XtAddCallback(widget, XtNcallback, xvl_output_cb, node);
	   XtOverrideTranslations(widget, button_translation);

	   /*
	    *  Advance to the next output widget node.
	    */
	   list = list->next; output_num++;
	   vert_off = widget;
	   y = 1;
	}
	label_off = vert_off;
	y = y_off;

	/*
	 *  Build the input widget buttons.
	 */
	input_num = 0;
	vert_off = glyph->destroy;
	list = glyph->input_list;

	j = 0;
	xvl_set_color(input_args, &j, XtNforeground, wresource.input_fg);
	xvl_set_color(input_args, &j, XtNbackground, wresource.input_bg);
	xvl_set_color(input_args, &j, XtNborderColor, wresource.input_bd);
	while (list != NULL)
	{
	   /*
	    *  Make a unique input names for the i/o widgets.
	    */
	   sprintf(name, "input%d", input_num);

	   node = list->node;
	   if (node->selected)
	      widget = xvf_create_bitmap(back, name, io, NULL, vert_off, 2, y,
					 input_args, j);
	   else
	      widget = xvf_create_bitmap(back, name, io_opt, NULL, vert_off,2,y,
					 input_args, j);

	   node->widget = widget;
	   XtAddCallback(widget, XtNcallback, xvl_input_cb, node);
	   XtOverrideTranslations(widget, button_translation);

	   /*
	    *  Create the data available (dav) label widget
	    */
	   node->dav_widget = xvf_create_label(back, NULL, widget, vert_off,
				0, y+y_off/2, 0, NULL, args, i);
	   xvl_update_dav(node);

	   /*
	    *  Advance to the next input widget node.
	    */
	   list = list->next; input_num++;
	   vert_off = widget;
	   y = 1;
	}

	/*
	 *  Place the glyph label on the bottom of the widget
	 *  below the input and output widgets buttons.
	 */
	if (input_num > output_num)
	{
	   label_off = vert_off;
	   temp = input_num;
	}
	else
	{
	   temp = output_num;
	}

	/* Compute the vertical offset */
	y = (MAX(temp, 2) - temp) * (pixmap_height + 2) + 1;
	if (temp <= 1)
	   y = y - 3;

	/*
	 *  Create the glyph's label.
	 */
	xvl_query_widget(glyph->back, NULL, NULL, &width, NULL);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.label_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.label_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.label_bd);
	XtSetArg(args[i], XtNleft, XtChainLeft);                        i++;
	XtSetArg(args[i], XtNright, XtChainRight);                      i++;
	XtSetArg(args[i], XtNinternalHeight, 0);                        i++;
	XtSetArg(args[i], XtNinternalWidth, 0);                         i++;
	XtSetArg(args[i], XtNborderWidth, 0);                           i++;
	glyph->label = xvf_create_label(back, glyph->label_str, NULL,
			label_off, 0, y, (int) width-4, xvf_font, args, i);

	XRaiseWindow(XtDisplay(glyph->error), XtWindow(glyph->error));
}

static void create_comment(glyph)

Glyph		*glyph;		
{
	Workspace	*workspace, *attributes;

	Dimension  width;
	Widget     back;
	Arg	   args[25];
	int	   i, x, pixmap_height;

	workspace = glyph->workspace;
	attributes = xvl_get_attributes(workspace);

	display   = XtDisplay(workspace->back);
	if (attributes->small_glyphs == True)
	{
	   pixmap_height = kills_height;
	   x = 1;
	}
	else
	{
	   pixmap_height = kill_height;
	   x = 2;
	}

	/*
	 *  Create the back to the glyph.
	 */
	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.glyph_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.glyph_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.glyph_bd);
	glyph->toplevel =
	glyph->back     = xvf_create_back(workspace->back, glyph->toplevel_name,
				 NULL, NULL, glyph->xpos, glyph->ypos, args, i);

        /*
         *  Place the "destroy", & "form" buttons at the top of 
         *  the widget.
         */
	back = glyph->back;

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.destroy_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.destroy_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.destroy_bd);
	glyph->destroy = xvf_create_bitmap(back, "destroy", destroy, NULL,
				NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.form_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.form_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.form_bd);
	glyph->form = xvf_create_bitmap(back, "glyph_form", form,glyph->destroy,
				NULL, x, x, args, i);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.error_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.error_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.error_bd);
	XtSetArg(args[i], XtNmappedWhenManaged, False);		i++;
	XtSetArg(args[i], XtNshapeStyle, XmuShapeOval);		i++;
	glyph->error = xvf_create_bitmap(back, "error", error, glyph->destroy,
				glyph->form, x, x + 5, args, i);

	/*
	 *  Add the appropriate callback routines to the widgets
	 */
	XtOverrideTranslations(glyph->form, button_translation);
	XtAddCallback(glyph->form, XtNcallback, xvl_form_cb, (caddr_t) glyph);
	XtAddCallback(glyph->error, XtNcallback, xvl_error_cb, (caddr_t) glyph);
	XtAddCallback(glyph->destroy, XtNcallback, xvl_destroy_cb,
		      (caddr_t) glyph);

	/*
	 *  Create the glyph's label.
	 */
	xvl_query_widget(glyph->back, NULL, NULL, &width, NULL);

	i = 0;
	xvl_set_color(args, &i, XtNforeground, wresource.label_fg);
	xvl_set_color(args, &i, XtNbackground, wresource.label_bg);
	xvl_set_color(args, &i, XtNborderColor, wresource.label_bd);
	XtSetArg(args[i], XtNleft, XtChainLeft);                        i++;
	XtSetArg(args[i], XtNright, XtChainRight);                      i++;
	XtSetArg(args[i], XtNinternalHeight, 0);                        i++;
	XtSetArg(args[i], XtNinternalWidth, 0);                         i++;
	XtSetArg(args[i], XtNborderWidth, 0);                           i++;
	glyph->label = xvf_create_label(back, glyph->label_str, NULL,
			glyph->destroy, 0, pixmap_height, (int) width-4,
			xvf_font, args, i);

	XRaiseWindow(XtDisplay(glyph->error), XtWindow(glyph->error));
}
