 /*
  * Khoros: $Id: init.c,v 1.4 1992/03/20 22:38:34 dkhoros Exp $
  */

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

 /*
  * $Log: init.c,v $
 * Revision 1.4  1992/03/20  22:38:34  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"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>         	Editimage Utilities		      <<<<
   >>>>                                                       <<<<
   >>>>			init_image()			      <<<<
   >>>>			update_image()			      <<<<
   >>>>			init_annontation()		      <<<<
   >>>>			init_xresources()		      <<<<
   >>>>			init_gc()			      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



/************************************************************
*
*  Module Name: init_image
*
*      Purpose: This routine initializes an image to be used
*		by editimage.  The routine will take a file
*		name, read in and initialze the image to be
*		displayed by editimage.  We also will prepare
*
*
*        Input: infile -
*
*       Output: none
*
*   Written By: Mark Young
*
*************************************************************/


int init_image(img_infile, shape_infile, clip_infile, ov_infile,
	       cmap_infile, use_cmap)

char	*img_infile;
char	*shape_infile; 
char    *clip_infile;
char	*ov_infile;
char	*cmap_infile;
int	use_cmap;
{
	struct xvimage **xvd_seperate_images();
	struct xvimage *image, *shape, *clip, *cmap;

	/*
	 *  initialize global xvdisplay structure
	 */
	if (img_infile != NULL) images = readimage(img_infile);
	else images = NULL;

	if (shape_infile != NULL) shape = readimage(shape_infile);
	else shape = NULL;
	if (clip_infile != NULL) clip = readimage(clip_infile);
	else clip = NULL;
	if (cmap_infile != NULL) cmap = readimage(cmap_infile);
	else cmap = NULL;
	if (ov_infile != NULL) overlays = readimage(ov_infile);
	else overlays = NULL;

	/*
	 *  After reading in the display image, if use_cmap is False then
	 *  we should delete the maps associated with that image.
	 */
	if (use_cmap == False && images != NULL)
	{
	   if (images->maps != NULL) free(images->maps);
	   images->maps		     = NULL;
	   images->map_storage_type  = VFF_MAPTYP_NONE;
	   images->map_scheme 	     = VFF_MS_NONE;
	   images->map_enable 	     = VFF_MAP_OPTIONAL;
	   images->color_space_model = VFF_CM_NONE;
	   images->map_row_size    =
	   images->map_col_size    =
	   images->map_subrow_size = 0;
	}
	else if (cmap != NULL && images != NULL)
	{
	   transfer_colormap(cmap, images);
	   freeimage(cmap);
	}

	/*
	 *  Seperate out the image bands so that we can change bands later.
	 */
	if (images != NULL)
	{
	   if (!(band = xvd_seperate_images(images, &num_bands)))
	   {
	      xvf_error_wait("leditimage", "lvbandsprt failed!\n", NULL);
	      return(False);
	   }
	   image = band[0];
	}
	else
	{
	   band = NULL;
	   image = NULL;
	}

	/*
	 *  Seperate out the overlay bands so that we can change overlay
	 *  bands later.
	 */
	if (overlays != NULL)
	{
	   if (!(ovband = xvd_seperate_images(overlays, &num_ovbands)))
	   {
	      xvf_error_wait("leditimage", "lvbandsprt failed for seperating \
out overlay bands!\n", NULL);
	      overlays = NULL;
	      ovband = NULL;
	      ovactive = NULL;
	   }
	   else
	   {
	      ovactive = (int *) XtCalloc(1, sizeof(int) * num_ovbands);
	   }
	}
	else
	{
	   ovactive = NULL;
	   ovband = NULL;
	}

	/*
	 *  initialize the image bands
	 */
	if (!(xvdisplay = xvd_init_xvdisplay(display, image, shape, clip,
			NULL, True, False, False, NULL)))
	{
           return(False);  
	}
	init_xresources(xvdisplay);

	/*
	 *  Initialize the global indecies
	 */
	index1 = index2 = -1;
	return(True);
}



/************************************************************
*
*  Module Name: update_image
*
*      Purpose: This routine updates the xvdisplay structure
*		with the new "image".   update_image calls
*		xvd_update_image() with the global xvdisplay
*		structure and the new/updated image.  If the
*		image passed is NULL then xvd_update_image()
*		will use the one in the xvdisplay structure.
*
*		The next part is update the various parts of
*		editimage's display structures to reflect the
*		changes in the updated image.
*
*        Input: tmpimages - image to be updated
*
*       Output: none
*
*   Written By: Mark Young
*
*************************************************************/


int update_image(tmpimages)

struct xvimage *tmpimages;
{
	int    width, height, create_zoom, num_tmpbands;
	struct xvimage *image, **tmpband, **xvd_seperate_images();



	/*
	 *  If there is no current image or the image has changed then we
	 *  check the zoom structure and split the image bands.
	 */
	if (tmpimages != NULL && tmpimages != images)
	{
	   /*
	    *  Check to see if the zoom image needs to be re-created.
	    */
	   if (images == NULL)
	      create_zoom = True;
	   else if (tmpimages->data_storage_type != images->data_storage_type)
	      create_zoom = True;
	   else
	      create_zoom = False;

	   /*
	    *  Seperate out the image bands so that the user can change bands
	    *  later.
	    */
	   if (!(tmpband = xvd_seperate_images(tmpimages, &num_tmpbands)))
	   {
	      xvf_error_wait("leditimage", "lvbandsprt failed!\n", NULL);
	      return(False);
	   }
	   free_images();
	   band = tmpband;
	   num_bands = num_tmpbands;
	   images = tmpimages;
	   image = tmpband[0];

	   /*
	    *  call the xvdisplay update routine to update the associated
	    *  resources in the xvdisplay structure.
	    */
	   if (!xvd_update_image(xvdisplay, image))
	      return(False);

	   if (create_zoom)
	   {
	      if (zoom->ximage != NULL)
	      {
	         width  = zoom->ximage->width;
	         height = zoom->ximage->height;
	         XDestroyImage(zoom->ximage);
	      }
	      else
		 width = height = 210;

	      if ((zoom->ximage = xvd_shrink_ximage(xvdisplay->display,
			xvdisplay->ximage, width, height, NULL)) != NULL)
	      {
	         if (zoom->ximage->depth == 1)
		    zoom->ximage->format = XYBitmap;
	      }

	      if (xvd_check_visibility(zoom->image) == True)
		 update_zoom_mode();
	   }
	   else if (xvd_check_visibility(zoom->image) == True)
	      update_zoom_mode();
	}
	else
	{
	   if (!xvd_update_image(xvdisplay, tmpimages))
	      return(False);
	}

	/*
	 *  re-create the pseudo palette.  If new colors were added or deleted
	 *  it is necessary to destroy the old palette and create a new one.
	 */
	if (pseudo->palette != NULL)
	{
	   XtUnmapWidget(pseudo->palette);
	   pseudo->palette = create_color_palette(pseudo->pseudo,
				pseudo->color1, NULL);
	}

	/*
	 *  Set the new colormap for each of the display structures.
	 *  Then call the update threshold routine "update_thres" to
	 *  set the current threshold, then refresh all the visible
	 *  displays
	 */
	if (xvd_check_visibility(lut->palette) == True)
	{
	   XClearArea(XtDisplay(lut->palette), XtWindow(lut->palette),
				0, 0, 0, 0, True);
	}
	if (xvd_check_visibility(thres->palette) == True)
	{
	   XClearArea(XtDisplay(thres->palette), XtWindow(thres->palette),
				0, 0, 0, 0, True);
	}

	set_colormap();
	update_thres();
	refresh_displays(0, MAX_PIXELS);
	return(True);
}



/********************************************************
*
*  Routine Name:  init_annontation
*
*       Purpose:  Initialize the annontations by creating
*		  a graphics id and setting it to the X11
*		  resources.
*
*         Input:  workspace - workspace widget
*
*        Output:  none
*
*     Called By:  leditimage()
*
*    Written By:  Mark Young & Tom Sauer
*
********************************************************/


init_annontation(widget)

Widget widget;
{
	int	  id = 1;


	X3D_init_graphics(id, X2D);
	X3D_set_X11(id, XtDisplay(widget), NULL, widget);

	/*
	 *  Initialize the overlay object list.
	 */
	obj_list = NULL;
	init_overlays(id, widget);
}



/************************************************************
*
*  MODULE NAME: init_xresources
*
*      PURPOSE: initializes certain X resources for the different
*		display utilites.  Such as the red, green, blue pixels
*		used in displaying the lut ramps.
*
*        INPUT: none
*
*       OUTPUT: none
*
*   WRITTEN BY: Mark Young
*
*************************************************************/


init_xresources(xvdisplay)

DisplayStructure *xvdisplay;
{
	XColor	   color, exact;

	Display	   *display = xvdisplay->display;
	int	   screen   = XDefaultScreen(display);
        Colormap   colormap = XDefaultColormap(display, screen);


	/*
	 *  Get the black, white, & grey colors
	 */
	if (XAllocNamedColor(display, colormap, "black", &color, &exact))
	   black = color.pixel;
	else black = XBlackPixel(display, screen);

	if (XAllocNamedColor(display, colormap, "white", &color, &exact))
	   white = color.pixel;
	else white = XWhitePixel(display, screen);

	if (XAllocNamedColor(display, colormap, "grey", &color, &exact))
	   grey = color.pixel;
	else grey = white;

	/*
	 *  Get the RGB colors
	 */
	if (XAllocNamedColor(display, colormap, "red", &color, &exact))
	   red = color.pixel;
	else red = white;

	if (XAllocNamedColor(display, colormap, "green", &color, &exact))
	   green = color.pixel;
	else green = white;

	if (XAllocNamedColor(display, colormap, "blue", &color, &exact))
	   blue = color.pixel;
	else blue = white;

	/*
	 *  Get the CMY colors
	 */
	if (XAllocNamedColor(display, colormap, "cyan", &color, &exact))
	   cyan = color.pixel;
	else cyan = white;

	if (XAllocNamedColor(display, colormap, "magenta", &color, &exact))
	   magenta = color.pixel;
	else magenta = white;

	if (XAllocNamedColor(display, colormap, "yellow", &color, &exact))
	   yellow = color.pixel;
	else yellow = white;
}



/************************************************************
*
*  MODULE NAME: init_gc
*
*      PURPOSE: initializes certain X resources for the different
*		display utilites.  Specifically the GC.
*
*        INPUT: none
*
*       OUTPUT: none
*
*   WRITTEN BY: Mark Young
*
*************************************************************/


init_gc(widget)

Widget widget;
{
	XGCValues  values;
	unsigned   long mask;
	Display	   *display = XtDisplay(widget);
	Window	   display_window = XtWindow(widget);


	mask = GCLineWidth | GCFunction | GCForeground | GCBackground;
	values.line_width = 0;
	values.function = GXcopy;
	values.foreground = white;
	values.background = black;
	gc_zoom = XCreateGC(display, display_window, mask, &values);

	mask = GCLineWidth | GCFunction | GCForeground;
	values.line_width = 0;
	values.function = GXcopy;
	values.foreground = grey;
	gc = XCreateGC(display, display_window, mask, &values);

	mask = GCLineWidth | GCFunction | GCForeground;
	values.line_width = 0;
	values.function = GXcopy;
	values.foreground = white;
	gc_set = XCreateGC(display, display_window, mask, &values);

	mask = GCLineWidth | GCFunction | GCSubwindowMode;
	values.line_width = 0;
	values.function = GXinvert;
	values.subwindow_mode = IncludeInferiors;
	gc_invert = XCreateGC(display, display_window, mask, &values);

	mask = GCLineWidth | GCFunction | GCSubwindowMode | GCPlaneMask |
	       GCForeground;
	values.line_width = 0;
	values.function = GXxor;
	values.foreground = ~0;
	values.plane_mask = black ^ white;
	gc_xor = XCreateGC(display, display_window, mask, &values);
}

static int editimage_test()
{
	XSynchronize(display, True);
	return(1);
}
