 /*
  * Khoros: $Id: create_util.c,v 1.3 1992/03/20 22:38:29 dkhoros Exp $
  */

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

 /*
  * $Log: create_util.c,v $
 * Revision 1.3  1992/03/20  22:38:29  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 "editimage.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>            Creation of Custom Widget 		      <<<<
   >>>>			Utility Routines             	      <<<<
   >>>>                                                       <<<<
   >>>>			create_pixel_back()                   <<<<
   >>>>			create_pseudo_back()                  <<<<
   >>>>			create_color_palette()		      <<<<
   >>>>			create_lut_back()		      <<<<
   >>>>                 create_lut_canvas()		      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/****************************************************************
*
* Routine Name:  create_pixel_back
*
*
*      Purpose:  creates each individual pixels back for each of the
*		 color spaces (ie RGB, HSV, YIQ, etc).
*
*        Input:  parent: the parent for the back plane to lie on
*		 label1: label for the first color widget
*		 label2: label for the second color widget
*		 label3: label for the third color widget
*		 (note: if any label is NULL then the widget won't be created).
*		 color1: color for the first widget
*		 color2: color for the second widget
*		 color3: color for the third widget
*		 vertical: widget from which to set vertical offset
*		 horizontal: widget from which to set horizontal offset
*
*       Output:  back:	the back plane where the pixel boxes will lie. 
*		 widgets: the color space widgets to be created (calls
*			  pixel_box to actually create each widget).
*
*   Written By:  Mark Young 
*
****************************************************************/

static  Widget pixel_box();
Widget create_pixel_back(parent, label1, label2, label3, color1, color2, color3,
			 widgets, vertical, horizontal)

Widget	  parent, vertical, horizontal;
char	  *label1, *label2, *label3;
unsigned  long color1, color2, color3;
Widget    *widgets;
{
	int	i;
	Arg	args[MaxArgs];
	Widget  back, widget = NULL;
	char    temp[MaxLength];
	static  int count = 0;

	/*
	 *  Create the pixels display back.
	 */
	i = 0;
	XtSetArg(args[i], XtNforeground, black);                i++;
	XtSetArg(args[i], XtNbackground, white);                i++;
	XtSetArg(args[i], XtNborderColor, black);               i++;
	XtSetArg(args[i], XtNwidth, (Dimension) 230);           i++;
	XtSetArg(args[i], XtNheight, (Dimension) 390);          i++;
	sprintf(temp, "pixelback%d", count++);
	back = XtCreateManagedWidget(temp, formWidgetClass, parent, args, i);

	if (label1 != NULL)
	   widget = pixel_box(&widgets[0], label1, color1, back, widget, NULL);
	if (label2 != NULL)
	   widget = pixel_box(&widgets[1], label2, color2, back, widget, NULL);
	if (label3 != NULL)
	   widget = pixel_box(&widgets[2], label3, color3, back, widget, NULL);

	return(back);
}

/****************************************************************
*
* Routine Name:  pixel_box
*
*
*      Purpose:  creates each individual pixels box (a set of three 
*		 are contained in each pixels display for rgb, hsv, and cym)
*
*        Input:  value: pointer to the value widget
*	   	 label: label for the color name
*		 pixel: the pixel value 
*		 parent: the parent widget
*		 vertical: widget from which to set vertical offset
*		 horizontal: widget from which to set horizontal offset
*
*       Output:  the created pixel box 
*
*   Written By:  Mark Young 
*
****************************************************************/

static Widget pixel_box(value, label, pixel, parent, vertical, horizontal)

Widget	*value;
char	*label;
unsigned long pixel;
Widget	parent, vertical, horizontal;
{
	int	i;
	Arg	args[15];
	Widget  back, colorname;
	char    temp[MaxLength];
	static  int count = 0;


	/*
	 *  Create the pixels display background.
	 */
	i = 0;
	XtSetArg(args[i], XtNfromVert, vertical);		i++;
	XtSetArg(args[i], XtNfromHoriz, horizontal);		i++;
	XtSetArg(args[i], XtNborderColor, pixel);		i++;
	XtSetArg(args[i], XtNforeground, black);		i++;
	XtSetArg(args[i], XtNbackground, white);		i++;
	XtSetArg(args[i], XtNwidth, (Dimension) 215);		i++;
	XtSetArg(args[i], XtNheight, (Dimension) 120);		i++;
	sprintf(temp, "pixelbox%d", count++);
	back = XtCreateManagedWidget(temp, formWidgetClass, parent, args, i);

	i = 0;
	XtSetArg(args[i], XtNlabel, VStrcpy(label));		i++;
	XtSetArg(args[i], XtNfromVert, NULL);			i++;
	XtSetArg(args[i], XtNfromHoriz, NULL);			i++;
	XtSetArg(args[i], XtNborderWidth, 0);			i++;
	XtSetArg(args[i], XtNforeground, pixel);  		i++;
	XtSetArg(args[i], XtNbackground, white);		i++;
	XtSetArg(args[i], XtNwidth, (Dimension) 215);		i++;
	colorname = XtCreateManagedWidget("label", labelWidgetClass, back,
					   args, i);

	i = 0;
	XtSetArg(args[i], XtNwidth, 7 * pixels->width +1);	i++;
	XtSetArg(args[i], XtNheight, 6 * pixels->height +1);	i++;
	XtSetArg(args[i], XtNfromVert, colorname);		i++;
	XtSetArg(args[i], XtNfromHoriz, NULL);			i++;
	XtSetArg(args[i], XtNinternalWidth, 0);			i++;
	XtSetArg(args[i], XtNinternalHeight, 0);		i++;
	XtSetArg(args[i], XtNborderWidth, 0);			i++;
	XtSetArg(args[i], XtNforeground, black);		i++;
	XtSetArg(args[i], XtNbackground, white);		i++;
	*value = XtCreateManagedWidget("pixels", simpleWidgetClass, back,
				      args, i);
	return(back);

} /* end pixel_box */


/****************************************************************
*
* Routine Name:  create_pseudo_back
*
*
*      Purpose:  creates each individual pseudo back for each of the
*		 color spaces (ie RGB, HSV, YIQ, etc).
*
*        Input:  parent: the parent for the back plane to lie on
*		 label1: label for the first color widget
*		 label2: label for the second color widget
*		 label3: label for the third color widget
*		 (note: if any label is NULL then the widget won't be created).
*                color1: color for the first widget label
*                color2: color for the second widget label
*                color3: color for the third widget label
*                pixel1: color for the first lut structure
*                pixel2: color for the second lut structure
*                pixel3: color for the third lut structure
*		 scrolls: the scroll structures to be filled with the scrollbars
*		 vertical:  the widget to vertically offset the back from
*		 horizontal: the widget to horizontally offset the back from
*
*       Output:  back:	the back plane where the pseudo scrollbars will lie. 
*		 scrolls: the color space widgets to be created (calls
*		 create_pseudo_scrollbar to actually create each widget).
*
*   Written By:  Mark Young 
*
****************************************************************/

Widget create_pseudo_back(parent,label1, label2, label3, color1, color2, color3,
			  pixel1, pixel2, pixel3, scrolls, vertical, horizontal)

Widget	  parent, vertical, horizontal;
char	  *label1, *label2, *label3;
unsigned  long color1, color2, color3,
	       pixel1, pixel2, pixel3;
ScrollStruct  *scrolls;
{
	int	i;
	Arg	args[MaxArgs];
	Widget  back, widget = NULL;
	Widget  create_pseudo_scrollbar();
	char    temp[MaxLength];
	static  int count = 0;


	/*
	 *  Create the pseudo display back.
	 */
	i = 0;
	XtSetArg(args[i], XtNforeground, black);                i++;
	XtSetArg(args[i], XtNbackground, white);                i++;
	XtSetArg(args[i], XtNborderColor, black);               i++;
	XtSetArg(args[i], XtNwidth, (Dimension) 230);           i++;
	XtSetArg(args[i], XtNheight, (Dimension) 120);          i++;
	XtSetArg(args[i], XtNfromVert, vertical);		i++;
	XtSetArg(args[i], XtNfromHoriz, horizontal);		i++;
	sprintf(temp, "pseudoback%d", count++);
	back = XtCreateManagedWidget(temp, formWidgetClass, parent, args, i);

	if (label1 != NULL)
	{
	   widget = create_pseudo_scrollbar(&scrolls[0], label1, color1, 
					    pixel1, back, widget, NULL);
	   scrolls[0].num = 0;
	   scrolls[0].pixel = color1;
	}
	if (label2 != NULL)
	{
	   widget = create_pseudo_scrollbar(&scrolls[1], label2, color2, 
					    pixel2, back, widget, NULL);
	   scrolls[1].num = 1;
	   scrolls[1].pixel = color2;
	}
	if (label3 != NULL)
	{
	   widget = create_pseudo_scrollbar(&scrolls[2], label3, color3, 
					    pixel3, back, widget, NULL);
	   scrolls[2].num = 2;
	   scrolls[2].pixel = color3;
	}

	return(back);
}



/****************************************************************
*
* Routine Name:  create_color_palette
*
*
*      Purpose:  creates the grid of color boxes which form the color
*		 palette on the pseudocolor display
*
*        Input:  parent     - parent of the color palette widget
*		 vertical   - widget from which to do vertical offset
*		 horizontal - widget from which to do horizontal offset
*		
*       Output:  returns the Widget backplane of the color palette
*
*   Written By:  Mark Young 
*
****************************************************************/

Widget create_color_palette(parent, vertical, horizontal)

Widget	parent, vertical, horizontal;
{
	char	 label[MAXBUF];
	int	 i, num, width, height, row, col, x, y, index;

	Window   root;
	Pixmap   stippled;
	unsigned int depth, dummy;
	Arg	args[10];
	Widget	palette, *boxes;
	XColor	*xcolors = xvdisplay->xcolors;
	char    temp[MaxLength];
	static  int count = 0;

	num = 0;
	for (i = 0; i < MAX_PIXELS; i++)
	{
	    if (xvdisplay->active[i] != 0)
	       num++;
	}


	/*
	 *  Get the depth of the parent.
	 */
	if (!XGetGeometry(XtDisplay(parent), XtWindow(parent), &root, 
			(int *) &dummy, (int *) &dummy, &dummy, &dummy, 
			&dummy, &depth))
	   depth = 1;

	/*
	 *  Create the palette form to hold the color boxes.
	 */
	width = ceil(sqrt((double) num));
	height = (int) (sqrt((double) num) + 0.5);
	stippled = XmuCreateStippledPixmap(XtScreen(parent),white,black,depth);

	i = 0;
	XtSetArg(args[i], XtNfromVert, vertical);		i++;
	XtSetArg(args[i], XtNfromHoriz, horizontal);		i++;
	XtSetArg(args[i], XtNwidth, 192);			i++;
	XtSetArg(args[i], XtNheight, 192);			i++;
	XtSetArg(args[i], XtNdepth, depth);			i++;
	XtSetArg(args[i], XtNbackgroundPixmap, stippled);	i++;
	sprintf(temp, "pallette%d", count++);
	palette = XtCreateManagedWidget(temp, formWidgetClass,
					 parent, args, i);

	if (width == 0) return(palette);
	if (height == 0) return(palette);

	x = MIN(192/width, 192/4) -3;
	y = MIN(192/height,192/4) -3;
	XtSetArg(args[0], XtNwidth, x);
	XtSetArg(args[1], XtNheight, y);
	XtSetArg(args[2], XtNborderWidth, 1);
	XtSetArg(args[3], XtNborderColor, black);
        XtSetArg(args[4], XtNhorizDistance, 1);
        XtSetArg(args[5], XtNvertDistance,  1);

	row = col = 0;

	/*
	 *  Create the color palette boxes.
	 */
	boxes = (Widget *) XtMalloc(sizeof(Widget) * num);

	for (i = 0; i < MAX_PIXELS; i++)
	{
	   if (xvdisplay->active[i] > 0)
	   {
	      XtSetArg(args[6], XtNforeground, xcolors[i].pixel);
	      XtSetArg(args[7], XtNbackground, xcolors[i].pixel);

	      if (col == 0)
	      {
	         XtSetArg(args[8], XtNfromHoriz, NULL);
	      }
	      else
	      {
		 index = (row*width) + col -1;
	         XtSetArg(args[8], XtNfromHoriz, boxes[index]);
	      }

	      if (row == 0)
	         XtSetArg(args[9], XtNfromVert, NULL);
	      else
	      {
		 index = (row -1)*width + col;
	         XtSetArg(args[9], XtNfromVert, boxes[index]);
	      }
	      index = (row * width) + col;

	      (void) sprintf(label,"colorbox%d",i);
	      boxes[index] = XtCreateManagedWidget(label, simpleWidgetClass,
						   palette, args, 10);
	      XtAddEventHandler(boxes[index], ButtonPressMask, False,
			        update_palette, (XtPointer) i);

	      col++;
	      if (col == width)
	      {
	         col = 0;
		 row++;
	      }
	   }
	}
	XtAddEventHandler(xvdisplay->raster, ButtonPressMask, False,
			  update_palette, (XtPointer) -1);
	return(palette);
}

/****************************************************************
*
* Routine Name:  create_lut_back
*
*      Purpose:  creates each individual lut back for each of the
*                color spaces (ie RGB, HSV, YIQ, etc).
*
*        Input:  parent: the parent for the back plane to lie on
*                label1: label for the first color widget
*                label2: label for the second color widget
*                label3: label for the third color widget
*                (note: if any label is NULL then the widget won't be created).
*                color1: color for the first widget label
*                color2: color for the second widget label
*                color3: color for the third widget label
*                pixel1: color for the first lut structure
*                pixel2: color for the second lut structure
*                pixel3: color for the third lut structure
*                canvases: the LutCanvas structures to be filled 
*                vertical:  the widget to vertically offset the back from
*                horizontal: the widget to horizontally offset the back from
*
*       Output:  back:  the back plane where the pseudo scrollbars will lie.
*                canvases: 
*
*   Written By:  Mark Young & Danielle Argiro
*
****************************************************************/

Widget create_lut_back(parent, label1, label2, label3, color1, color2, color3,
		       pixel1, pixel2, pixel3, canvases, vertical, horizontal)

Widget    parent, vertical, horizontal;
char      *label1, *label2, *label3;
unsigned  long color1, color2, color3,
	       pixel1, pixel2, pixel3;
LutCanvasStruct  *canvases;
{
        int     i;
        Arg     args[MaxArgs];
        Widget  back, widget = NULL;
	Widget create_lut_canvas();
	char    temp[MaxLength];
	static  int count = 0;


	/*
         *  Create the lut display back.
         */
        i = 0;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, black);               i++;
	XtSetArg(args[i], XtNfromVert, vertical);               i++;
        XtSetArg(args[i], XtNfromHoriz, horizontal);            i++;
	XtSetArg(args[i], XtNwidth,    lut_width+55);              i++;
	XtSetArg(args[i], XtNheight,   (lut_height+60)*3+20);	i++;
	sprintf(temp, "lutback%d", count++);
        back = XtCreateManagedWidget(temp, formWidgetClass, parent, args, i);


	if (label1 != NULL)
	{
	   canvases[0].num   = 0;
	   canvases[0].pixel = pixel1;
           widget = create_lut_canvas(back, label1, color1, 
				     &canvases[0], widget, NULL);
	}

	if (label2 != NULL)
	{
	   canvases[1].num   = 1;
	   canvases[1].pixel = pixel2;
           widget = create_lut_canvas(back, label2, color2, 
				     &canvases[1], widget, NULL);
	}

	if (label3 != NULL)
	{
	   canvases[2].num   = 2;
	   canvases[2].pixel = pixel3;
           widget = create_lut_canvas(back, label3, color3, 
				     &canvases[2], widget, NULL);
	}
	return(back);
}



/****************************************************************
*
* Routine Name:  create_lut_canvas
*
*
*      Purpose:  creates an individual lut canvas for one of the
*		 color domains (ie, red or green or blue).
*
*        Input:  parent: the parent for the back plane to lie on
*		 label:  label with the color name
*		 color:  color for the label
*		 vertical:  the widget to vertically offset the back from
*		 horizontal: the widget to horizontally offset the back from
*
*       Output:  back:	the back plane where the pseudo scrollbars will lie. 
*
*   Written By:  Mark Young 
*
****************************************************************/

Widget 
create_lut_canvas(parent, label, color, canvas, vertical, horizontal)
Widget parent;
char   *label;
unsigned long color;
LutCanvasStruct *canvas;
Widget vertical, horizontal;
{
	int    i;
	unsigned long mask;
	Arg    args[MaxArgs];
	char   temp[MaxLength];
	Widget back, ybeg, yend, label_wid;
	static int count = 0;

	/*
         *  Create the canvas backplane.
         */
        i = 0;
        XtSetArg(args[i], XtNfromVert, vertical);		i++;
        XtSetArg(args[i], XtNfromHoriz, horizontal);		i++;
        XtSetArg(args[i], XtNwidth, lut_width+40);		i++;
        XtSetArg(args[i], XtNheight, lut_height+60);		i++;
        sprintf(temp, "lutcanvas%d", count++);
        back = XtCreateManagedWidget(temp, formWidgetClass, parent, args, i);


	/*
	 *  label widget for color
	 */
	i = 0;
        XtSetArg(args[i], XtNlabel, label);            		i++;
        XtSetArg(args[i], XtNborderWidth, 0);                   i++;
        XtSetArg(args[i], XtNfromVert, NULL);                   i++;
        XtSetArg(args[i], XtNfromHoriz, NULL);                  i++;
	XtSetArg(args[i], XtNhorizDistance, lut_width/2);	i++;
        XtSetArg(args[i], XtNforeground, color);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        label_wid = XtCreateManagedWidget("label", labelWidgetClass, 
				      back, args, i);
	/*
	 *  label widget showing where y ends
	 */
	i = 0;
        XtSetArg(args[i], XtNlabel, VStrcpy("255"));            i++;
        XtSetArg(args[i], XtNborderWidth, 0);                   i++;
        XtSetArg(args[i], XtNfromVert, label_wid);              i++;
        XtSetArg(args[i], XtNfromHoriz, NULL);                  i++;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, black);               i++;
        yend = XtCreateManagedWidget("yend", labelWidgetClass, 
				      back, args, i);

	/*
         *  canvas widget on which we will draw the look up table display
         */
	i = 0;
        XtSetArg(args[i], XtNfromVert, label_wid);              i++;
        XtSetArg(args[i], XtNfromHoriz, yend);             	i++;
        XtSetArg(args[i], XtNwidth, lut_width);                 i++;
        XtSetArg(args[i], XtNheight, lut_height);               i++;
        XtSetArg(args[i], XtNcursor, display_cursor);           i++;
        XtSetArg(args[i], XtNforeground, white);                i++;
        XtSetArg(args[i], XtNbackground, black);                i++;
        XtSetArg(args[i], XtNborderColor, black);               i++;
        XtSetArg(args[i], XtNborderWidth, 3); 	                i++;
	sprintf(temp, "%s_canvas", label);
        canvas->canvas = XtCreateManagedWidget(temp, simpleWidgetClass,
                                            back, args, i);


	/*
	 *  label widget showing where y begins
	 */
	i = 0;
        XtSetArg(args[i], XtNlabel, VStrcpy("  0"));    i++;
        XtSetArg(args[i], XtNborderWidth, 0);                   i++;
        XtSetArg(args[i], XtNfromHoriz, NULL);                  i++;
        XtSetArg(args[i], XtNvertDistance, lut_height);         i++;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, white);               i++;
        ybeg = XtCreateManagedWidget("ybeg", labelWidgetClass, 
				      back, args, i);

	/*
 	 * label widget showing current value of y
	 */
	i = 0;
        XtSetArg(args[i], XtNlabel, VStrcpy("   "));            i++;
        XtSetArg(args[i], XtNborderWidth, 1);                   i++;
        XtSetArg(args[i], XtNfromHoriz, NULL);                  i++;
        XtSetArg(args[i], XtNvertDistance, lut_height/2);       i++;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, black);               i++;
        canvas->ypos = XtCreateManagedWidget("ypos", labelWidgetClass, 
					   back, args, i);

	/*
	 *  label widget showing where x begins
	 */
	i = 0;
	(void) sprintf(temp,"%d", xvdisplay->pixelmin);
        XtSetArg(args[i], XtNlabel, VStrcpy(temp));		i++;
        XtSetArg(args[i], XtNborderWidth, 0);                   i++;
        XtSetArg(args[i], XtNfromVert, canvas->canvas);         i++;
        XtSetArg(args[i], XtNfromHoriz, ybeg);                  i++;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, white);               i++;
        canvas->xbeg = XtCreateManagedWidget("xbeg", labelWidgetClass, 
                                     back, args, i);

	i = 0;
	(void) sprintf(temp," %3d", xvdisplay->pixelmax);
        XtSetArg(args[i], XtNlabel, VStrcpy(temp));		i++;
        XtSetArg(args[i], XtNborderWidth, 0);                   i++;
        XtSetArg(args[i], XtNhorizDistance, lut_width);         i++;
        XtSetArg(args[i], XtNfromVert, canvas->canvas);         i++;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, white);               i++;
        canvas->xend = XtCreateManagedWidget("xend", labelWidgetClass, 
					   back, args, i);

        i = 0;
        XtSetArg(args[i], XtNlabel, VStrcpy("   "));            i++;
        XtSetArg(args[i], XtNborderWidth, 1);                   i++;
        XtSetArg(args[i], XtNhorizDistance, lut_width/2);       i++;
        XtSetArg(args[i], XtNfromVert, canvas->canvas);         i++;
        XtSetArg(args[i], XtNforeground, black);                i++;
        XtSetArg(args[i], XtNbackground, white);                i++;
        XtSetArg(args[i], XtNborderColor, black);               i++;
        canvas->xpos = XtCreateManagedWidget("xpos", labelWidgetClass, 
					   back, args, i);
	/*
         *  Add the event handler to update the lut window.  The types of
         *  events we are concerened with are button press, since we use
         *  this to start updating the colormap.  We are also interested
         *  in a resize or expose event.  We need to take care of updating
         *  the screen.
         */
        mask = LeaveWindowMask | PointerMotionMask;
        XtAddEventHandler(canvas->canvas, mask, False, update_canvas, canvas);

        mask = ButtonPressMask | ButtonMotionMask;
        XtAddEventHandler(canvas->canvas, mask, False, update_lut, canvas);

        mask = ExposureMask | StructureNotifyMask;
        XtAddEventHandler(canvas->canvas, mask, False, redisplay_lut, canvas);
	return(back);
}
