 /*
  * Khoros: $Id: update.c,v 1.5 1992/03/20 22:49:12 dkhoros Exp $
  */

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

 /*
  * $Log: update.c,v $
 * Revision 1.5  1992/03/20  22:49:12  dkhoros
 * VirtualPatch5
 *
  */
 
/*
 *----------------------------------------------------------------------
 *
 *            Copyright 1990 University of New Mexico
 *  
 *  Permission to use, copy, modify, distribute, and sell this
 *  software and its documentation for any purpose is hereby
 *  granted without fee, provided that the above copyright
 *  notice appear in all copies and that both that copyright
 *  notice and this permission notice appear in supporting docu-
 *  mentation, and that the name of UNM not be used in advertis-
 *  ing or publicity pertaining to distribution of the software
 *  without specific, written prior permission.  UNM makes no
 *  representations about the suitability 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 DAMAGES WHATSOEVER
 *  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 PERFORMANCE
 *  OF THIS SOFTWARE.
 *  
 *----------------------------------------------------------------------
 */

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

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>            Update Display Utility Routines            <<<<
   >>>>                                                       <<<<
   >>>>		    xvd_update_image()			      <<<<
   >>>>		    xvd_update_shape()			      <<<<
   >>>>		    xvd_update_clip()			      <<<<
   >>>>		    xvd_update_overlay()		      <<<<
   >>>>		    xvd_update_all()			      <<<<
   >>>>		    xvd_update_xcolors()		      <<<<
   >>>>		    xvd_update_region()			      <<<<
   >>>>		    xvd_update_pixel()			      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/************************************************************
*
*  MODULE NAME: xvd_update_image
*
*      PURPOSE: Updates the display image associated with the
*		xvdisplay structure.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		image     - the image to be updated.  If NULL then
*			    update the current xvdisplay image.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_image(xvdisplay, image)

DisplayStructure *xvdisplay;
struct xvimage   *image;
{
	int	  i;
	Dimension width, height;
	Arg       args[MaxArgs];
	struct    xvimage *temp, *disp_temp;
	unsigned  long background, foreground;


	temp  = xvdisplay->image;
	disp_temp = xvdisplay->disp_image;
	if (image != NULL && image != temp)
	{
	   if (image->imagedata == NULL)
	   {
	      xvf_error_wait("Error!  No image data found.  The image is \
probably a colormap rather than an image, since no image data was found. \
Please re-run the program with an image that has column and row size of at \
least 1 ('vfileinfo' can be used to obtain information about the image).",
			"xvd_update_image", NULL);
	      xvdisplay->image = temp;
	      xvdisplay->disp_image = disp_temp;
	      return(False);
	   }
	   xvdisplay->image = image;
	}

	if (xvdisplay->image != NULL)
	{
	   /*
	    *  Check the image to make sure that it is still a proper image
	    */
	   if (!xvd_check_image(xvdisplay))
	   {
	      xvdisplay->image = temp;
	      xvdisplay->disp_image = disp_temp;
	      return(False);
	   }

	   /*
	    *  Build a histogram so that we know which colors to allocate
 	    */
	   if (!xvd_initialize_colormap(xvdisplay))
	   {
	      xvdisplay->image = temp;
	      xvdisplay->disp_image = disp_temp;
	      return(False);
	   }

	   /*
	    *  Load the xcolors according to the updated image
	    */
	   if (!xvd_load_xcolors(xvdisplay))
	   {
	      xvdisplay->image = temp;
	      xvdisplay->disp_image = disp_temp;
	      return(False);
	   }
	   xvd_update_colormap(xvdisplay);
	}

	if (!_xvd_update_ximage(xvdisplay, xvdisplay->disp_image,
		&xvdisplay->ximage, &xvdisplay->pixmap))
	{
	   xvdisplay->image = temp;
	   xvdisplay->disp_image = disp_temp;
	   return(False);
	}

	/*
	 *  Update the display image for the raster widget.
	 */
	if (xvdisplay->raster != NULL)
	{
	   i = 0;
	   foreground = xvd_white;
	   background = xvd_black;
	   if (xvdisplay->image != NULL)
	   {
	      if (xvdisplay->image->data_storage_type  == VFF_TYP_BIT)
	      {
	         background = xvdisplay->xcolors[0].pixel;
	         foreground = xvdisplay->xcolors[1].pixel;
	      }

              width = xvdisplay->image->row_size;
              height = xvdisplay->image->col_size;
	      if (width  > 800) width  = 800;
	      if (height > 750) height = 750;

	      XtSetArg(args[i], XtNwidth,  width);		i++;
	      XtSetArg(args[i], XtNheight, height);		i++;
	   }
	   XtSetArg(args[i], XtNimage, xvdisplay->ximage);	i++;
	   XtSetArg(args[i], XtNpixmap, xvdisplay->pixmap);	i++;
	   XtSetArg(args[i], XtNbackground, background);	i++;
	   XtSetArg(args[i], XtNforeground, foreground);	i++;
	   XtSetValues(xvdisplay->raster, args, i);
	}

	if (image != NULL && temp != NULL && image != temp)
	{
	   if (temp != disp_temp)
	      freeimage(disp_temp);

	   freeimage(temp);
	}

	if (xvdisplay->icon != NULL)
	   xvd_update_icon(xvdisplay);

	return(True);

}  /* end xvd_update_image */



/************************************************************
*
*  MODULE NAME: xvd_update_shape
*
*      PURPOSE: Updates the shape image associated with the
*		xvdisplay structure.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		shape     - the shape image to be updated.  If NULL then
*			    update the current xvdisplay shape.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_shape(xvdisplay, shape)

DisplayStructure *xvdisplay;
struct xvimage   *shape;
{
	int	i;
	Arg     args[MaxArgs];
	struct  xvimage *temp, *shape_image, *xvd_resize_shape();


	temp = xvdisplay->shape;
	if (shape != NULL && shape != temp)
	{
	   if (shape->imagedata == NULL)
	   {
	      xvf_error_wait("Error!  No 'shape' image data found.  The shape \
image is probably a colormap rather than an image, since no image data was \
found.  Please re-run the program with an image that has column and row size \
of at least 1 ('vfileinfo' can be used to obtain information about the image).",
			"xvd_update_shape", NULL);
	      xvdisplay->shape = temp;
	      return(False);
	   }
	   xvdisplay->shape = shape;
	}

	if (xvdisplay->shape != NULL)
	{
	   if (!xvd_check_shape(xvdisplay))
	   {
	      xvdisplay->shape = temp;
	      return(False);
	   }
	}

	/*
	 *  Resize shape if shape_parent is true.  This tells us that
	 *  the shape image should be used to clip out or not clip out
	 *  the parent.  If the ximage widget is placed inside of the
	 *  user interface then we wouldn't want the shaping of the image
	 *  window to make parent windows disappear.
	 */
	if (!xvdisplay->shape_parent && xvdisplay->shape != NULL)
	   shape_image = xvd_resize_shape(xvdisplay, xvdisplay->shape);
	else
	   shape_image = xvdisplay->shape;

	if (!_xvd_update_ximage(xvdisplay, shape_image, &xvdisplay->xshape,
				&xvdisplay->shape_mask))
	{
	   xvdisplay->shape = temp;
	   return(False);
	}

	if (shape_image != xvdisplay->shape)
	   freeimage(shape_image);

	/*
	 *  Update the overlay image for the raster widget.
	 */
	if (xvdisplay->raster != NULL)
	{
	   i = 0;
	   XtSetArg(args[i], XtNshape, xvdisplay->shape_mask);		i++;
	   XtSetArg(args[i], XtNshapeParent, xvdisplay->shape_parent);	i++;
	   XtSetValues(xvdisplay->raster, args, i);
	}

	if (shape != NULL && shape != temp)
	   freeimage(temp);
	return(True);

}  /* end xvd_update_shape */



/************************************************************
*
*  MODULE NAME: xvd_update_clip
*
*      PURPOSE: Updates the clip image associated with the
*		xvdisplay structure.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		clip      - the clip image to be updated.  If NULL then
*			    update the current xvdisplay clip image.
*
*    CALLED BY: the application program
*
*    CALLED BY: leditimage()
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_clip(xvdisplay, clip)

DisplayStructure *xvdisplay;
struct xvimage   *clip;
{
	int	i;
	Arg     args[MaxArgs];
	struct  xvimage *temp;


	temp = xvdisplay->clip;
	if (clip != NULL && clip != temp)
	{
	   if (clip->imagedata == NULL)
	   {
	      xvf_error_wait("Error!  No 'clip' image data found.  The clip \
image is probably a colormap rather than an image, since no image data was \
found.  Please re-run the program with an image that has column and row size \
of at least 1 ('vfileinfo' can be used to obtain information about the image).",
			"xvd_update_clip", NULL);
	      xvdisplay->clip = temp;
	      return(False);
	   }
	   xvdisplay->clip = clip;
	}

	if (xvdisplay->clip != NULL)
	{
	   if (!xvd_check_clip(xvdisplay))
	   {
	      xvdisplay->clip = temp;
	      return(False);
	   }
	}

	if (!_xvd_update_ximage(xvdisplay, xvdisplay->clip, &xvdisplay->xclip,
			  &xvdisplay->clip_mask))
	{
	   xvdisplay->clip = temp;
	   return(False);
	}

	/*
	 *  Update the overlay image for the raster widget.
	 */
	if (xvdisplay->raster != NULL)
	{
	   i = 0;
	   XtSetArg(args[i], XtNclip, xvdisplay->clip_mask);		i++;
	   XtSetValues(xvdisplay->raster, args, i);
	}

	if (clip != NULL && clip != temp)
	   freeimage(temp);
	return(True);

}  /* end xvd_update_clip */



/************************************************************
*
*  MODULE NAME: xvd_update_overlay
*
*      PURPOSE: Updates the overlay image associated with the
*		xvdisplay structure.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		overlay   - the overlay image to be updated.  If NULL then
*			    update the current xvdisplay overlay image.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_overlay(xvdisplay, overlay)

DisplayStructure *xvdisplay;
struct xvimage   *overlay;
{
	int	i;
	Arg     args[MaxArgs];
	struct  xvimage *temp, *ovmask;
	DisplayStructure *ovdisplay;


	temp = xvdisplay->overlay;
	ovmask = xvdisplay->ovmask;
	if (overlay != NULL && overlay != temp)
	{
	   if (overlay->imagedata == NULL)
	   {
	      xvf_error_wait("Error!  No 'overlay' image data found.  The \
overlay image is probably a colormap rather than an image, since no image data \
was found.  Please re-run the program with an image that has column and row \
size of at least 1 ('vfileinfo' can be used to obtain information about the \
image).", "xvd_update_overlay", NULL);
	      xvdisplay->overlay = temp;
	      xvdisplay->ovmask  = ovmask;
	      return(False);
	   }
	   xvdisplay->overlay = overlay;
	}

	if (xvdisplay->overlay != NULL)
	{
	   if (!xvd_check_overlay(xvdisplay))
	   {
	      xvdisplay->overlay = temp;
	      xvdisplay->ovmask  = ovmask;
	      return(False);
	   }
	   ovdisplay = xvd_init_image(xvdisplay->display, xvdisplay->overlay,
		   NULL, NULL, NULL, False, True, False, xvdisplay->colormap);
	   if (ovdisplay == NULL)
	   {
	      xvdisplay->overlay = temp;
	      xvdisplay->ovmask  = ovmask;
	      return(False);
	   }
	   xvdisplay->xoverlay = ovdisplay->ximage;
	   xvdisplay->overlay_pixmap = ovdisplay->pixmap;
	   if (!_xvd_update_ximage(ovdisplay, xvdisplay->ovmask, NULL,
			&xvdisplay->overlay_mask))
	   {
	      xvdisplay->overlay = temp;
	      xvdisplay->ovmask  = ovmask;
	      free(ovdisplay);
	      return(False);
	   }
	   free(ovdisplay);
	}
	else
	{
	   xvdisplay->ovmask = NULL;

	   if (!_xvd_update_ximage(xvdisplay, xvdisplay->overlay,
			&xvdisplay->xoverlay, &xvdisplay->overlay_pixmap))
	   {
	      xvdisplay->overlay = temp;
	      xvdisplay->ovmask  = ovmask;
	      return(False);
	   }

	   if (!_xvd_update_ximage(xvdisplay, xvdisplay->ovmask, NULL,
			&xvdisplay->overlay_mask))
	   {
	      xvdisplay->overlay = temp;
	      xvdisplay->ovmask  = ovmask;
	      return(False);
	   }
	}

	/*
	 *  Update the overlay image for the raster widget.
	 */
	if (xvdisplay->raster != NULL)
	{
	   i = 0;
	   XtSetArg(args[i], XtNoverlay, xvdisplay->overlay_pixmap);	i++;
	   XtSetArg(args[i], XtNoverlayMask, xvdisplay->overlay_mask);	i++;
	   XtSetValues(xvdisplay->raster, args, i);
	}

	if (overlay != NULL && overlay != temp)
	{
	   if (temp != ovmask && xvdisplay->ovmask != ovmask) freeimage(ovmask);
	   freeimage(temp);
	}
	return(True);

}  /* end xvd_update_overlay */



/************************************************************
*
*  MODULE NAME: xvd_update_all
*
*      PURPOSE: Updates the all the associated images with the
*		xvdisplay structure at once.  (Obsolete.  Please
*		use xvd_update_xvdisplay()).
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		image     - the display image to be updated.
*		shape     - the shape image to be updated.
*		clip      - the clip image to be updated.
*		overlay   - the overlay image to be updated.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program *
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_all(xvdisplay, image, shape, clip, overlay)

DisplayStructure *xvdisplay;
struct xvimage   *image, *shape, *clip, *overlay;
{
	return(xvd_update_xvdisplay(xvdisplay, image, shape, clip, overlay));
}



/************************************************************
*
*  MODULE NAME: xvd_update_xcolors
*
*      PURPOSE: Update the display colormap from the values
*		stored in the X color array.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_xcolors(xvdisplay)

DisplayStructure *xvdisplay;
{
	Arg	  args[MaxArgs];
	int	  i, j, ncolors;
	XColor	  temp[MAX_PIXELS], *xcolors = xvdisplay->xcolors;


	if (xvdisplay->read_only == False)
	{
	   /*
	    *  Store the changed color cells into the current colormap.
	    */
	   for (i = xvdisplay->pixelmin, j = 0; i <= xvdisplay->pixelmax; i++)
	   {
	       if (xvdisplay->active[i])
	          temp[j++] = xcolors[i];
	   }

	   /*
	    *  Store the X colors into the colormap
	    */
	   XStoreColors(xvdisplay->display, xvdisplay->colormap, temp, j);
	}
	else
	{
	   /*
	    *  Store the changed color cells into the current colormap.
	    *  This is done by calling xvd_update_colormap() which frees
	    *  and re-allocates the colors stored in the xcolor array.
	    */
	   xvd_update_colormap(xvdisplay);

	   if (!_xvd_update_ximage(xvdisplay, xvdisplay->disp_image,
		&xvdisplay->ximage, &xvdisplay->pixmap))
	   {
	      return(False);
	   }

	   i = 0;
	   XtSetArg(args[i], XtNimage, xvdisplay->ximage);	i++;
	   XtSetArg(args[i], XtNpixmap, xvdisplay->pixmap);	i++;
	   XtSetValues(xvdisplay->raster, args, i);
	}
	return(True);
}



/************************************************************
*
*  MODULE NAME: xvd_update_region
*
*      PURPOSE: Updates a region of the xvdisplay image, rather
*		than the entire image. 
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		x & y	  - the x & y position in the image to be
*			    updated.
*		w & h	  - the width & height of that region
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_region(xvdisplay, x, y, w, h)

DisplayStructure *xvdisplay;
int		 x, y, w, h;
{
	int	 i, j, k, index;
	int	 width, height;
	unsigned char *imagedata;
	Display  *display = xvdisplay->display;
	struct   xvimage *image = xvdisplay->image;

        Arg	    args[2];
	Dimension   xoffset, yoffset;


	if (image == NULL)
	   return(False);
	else if (x < 0 || x >= image->row_size || y < 0 || y >= image->col_size)
	   return(False);

	imagedata = (unsigned char *) xvdisplay->disp_image->imagedata;
	width  = image->row_size;
	height = image->col_size;
	for (j = y; j < y+h && j < height; j++)
	{
	   k = PIXEL(x, j, image->col_size, image->row_size);
	   for (i = x; i < x+w && i < width; i++, k++)
	   {
	      index = (int) imagedata[k];
	      if (xvdisplay->histogram[index] == 0)
	      {
	         xvdisplay->histogram[index]++;
	         (void) xvd_allocate_color(xvdisplay, index);
	      }
	      else
	         xvdisplay->histogram[index]++;

	      if (xvdisplay->ximage != NULL)
	      {
	         XPutPixel(xvdisplay->ximage, i, j,
				xvdisplay->xcolors[index].pixel);
	      }
	   }
	}

	if (xvdisplay->pixmap != None && xvdisplay->ximage != NULL)
	{
	   XPutImage(display, xvdisplay->pixmap, xvd_gc, xvdisplay->ximage,
			x, y, x, y, w, h);
	}

	if (xvdisplay->raster != NULL)
	{
	   i = 0;
	   XtSetArg(args[i], XtNxoffset, &xoffset);  i++;
	   XtSetArg(args[i], XtNyoffset, &yoffset);  i++;
	   XtGetValues(xvdisplay->raster, args, i);

	   x -= xoffset;
	   y -= yoffset;
	   XClearArea(display, XtWindow(xvdisplay->raster), x, y, w, h, True);
	}
	return(True);
}



/************************************************************
*
*  MODULE NAME: xvd_update_pixel
*
*      PURPOSE: Updates the all the associated images with the
*		xvdisplay structure at once.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*		x & y	  - the x & y position in the image to be
*			    updated.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: the application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/


int xvd_update_pixel(xvdisplay, x, y)

DisplayStructure *xvdisplay;
int		 x, y;
{
	int	i, index;
	Display *display = xvdisplay->display;
	struct  xvimage *image = xvdisplay->image;

	Arg	  args[2];
	Dimension xoffset, yoffset;


	if (image == NULL)
	   return(False);
	else if (x < 0 || x >= image->row_size || y < 0 || y >= image->col_size)
	   return(False);

	i = PIXEL(x, y, image->col_size, image->row_size);
	index = (int) xvdisplay->disp_image->imagedata[i];
	if (xvdisplay->histogram[index] == 0)
	{
	   xvdisplay->histogram[index]++;
	   (void) xvd_allocate_color(xvdisplay, index);
	}
	else
	   xvdisplay->histogram[index]++;

	if (xvdisplay->ximage != NULL)
	   XPutPixel(xvdisplay->ximage, x, y, (unsigned long) index);

	XSetForeground(display, xvd_gc, (unsigned long) index);
	if (xvdisplay->pixmap != None)
	   XDrawPoint(display, xvdisplay->pixmap, xvd_gc, x, y);

	if (xvdisplay->raster != NULL)
	{
	   i = 0;
	   XtSetArg(args[i], XtNxoffset, &xoffset);  i++;
	   XtSetArg(args[i], XtNyoffset, &yoffset);  i++;
	   XtGetValues(xvdisplay->raster, args, i);

	   x -= xoffset;
	   y -= yoffset;
	   XDrawPoint(display, XtWindow(xvdisplay->raster), xvd_gc, x, y);
	}
	return(True);
}



/************************************************************
*
*  MODULE NAME: xvd_update_icon
*
*      PURPOSE: Updates the display icon image associated with the
*		xvdisplay structure.
*
*        INPUT: xvdisplay - the xvdisplay structure to be updated.
*
*       OUTPUT: returns True if we are successful, otherwise False.
*
*    CALLED BY: internal routine
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/

int xvd_update_icon(xvdisplay)

DisplayStructure *xvdisplay;
{
	int    i;
	Arg    args[MaxArgs];

	XImage *icon_ximage = NULL;
	Pixmap icon_pixmap;
	int    desired_width = 64, desired_height = 64;


        /*
         *  Create a sub-sampled ximage from the xvdisplay ximage.
         */
	icon_pixmap = xvdisplay->icon_pixmap;
        if (xvdisplay->ximage != NULL)
        {
	   if (xvdisplay->icon_ximage != NULL)
	   {
	      icon_ximage = xvdisplay->icon_ximage;
	      desired_width = icon_ximage->width;
	      desired_height = icon_ximage->height;
	   }
	   icon_ximage = xvd_shrink_ximage(xvdisplay->display,xvdisplay->ximage,
				desired_width, desired_height, icon_ximage);

	   if (icon_ximage != NULL)
	   {
	      if (icon_ximage->depth > 1 || icon_ximage->depth ==
			xvdisplay->depth)
	      {
	         icon_pixmap = xvd_create_pixmap(xvdisplay, icon_ximage,
			icon_pixmap);
	      }
	      else
	      {
	         icon_pixmap = XCreatePixmapFromBitmapData(
			XtDisplay(xvdisplay->icon),
			XtWindow(xvdisplay->icon),
			icon_ximage->data, icon_ximage->width,
			icon_ximage->height, xvdisplay->xcolors[1].pixel,
			xvdisplay->xcolors[0].pixel, xvdisplay->depth);
	      }

	      desired_width = icon_ximage->width;
	      desired_height = icon_ximage->height;
	   }

	}

	i = 0;
	XtSetArg(args[i], XtNwidth, desired_width); i++;
	XtSetArg(args[i], XtNheight, desired_height); i++;
	XtSetArg(args[i], XtNcolormap, xvdisplay->colormap); i++;
	if (icon_pixmap != None)
	{
	   XtSetArg(args[i], XtNbackgroundPixmap, icon_pixmap); i++;
	}
	else
	{
	   XtSetArg(args[i], XtNbackgroundPixmap, None); i++;
	   XtSetArg(args[i], XtNbackground, xvd_black); i++;
	}
	XtSetValues(xvdisplay->icon, args, i);
	XClearWindow(XtDisplay(xvdisplay->icon), XtWindow(xvdisplay->icon));
}
