 /*
  * Khoros: $Id: lputimage.c,v 1.3 1992/03/20 22:40:30 dkhoros Exp $
  */

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

 /*
  * $Log: lputimage.c,v $
 * Revision 1.3  1992/03/20  22:40:30  dkhoros
 * VirtualPatch5
 *
  */

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, 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 to 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 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: lputimage.c
 >>>>
 >>>>      Program Name: putimage
 >>>>
 >>>> Date Last Updated: Tue Feb 11 22:34:00 1992 
 >>>>
 >>>>          Routines: lputimage - the library call for putimage
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "xvinclude.h"


/* -library_includes */
#include        "putimage.h"

int    use_colormap;
struct xvimage *cmap;
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lputimage - library call for putimage
*
* Purpose:
*
* Input:
* Output:
*
* Written By: Stephanie Hallett and Mark Young
****************************************************************/


/* -library_def */
int lputimage(img_infile, ov_infile, shape_infile, clip_infile, 
              xoffset, yoffset, update, display_name, use_cmap, cmap_infile)

char    *img_infile, *ov_infile, *shape_infile, *clip_infile, *cmap_infile;
int      xoffset, yoffset, use_cmap;
float    update;
char    *display_name;

/* -library_def_end */

/* -library_code */
{
        unsigned long mask;
        void     putimage_exit();
        DisplayStructure *xvdisplay;
        int      update_file(), update_stdin();

        char     temp[MAXBUF], *name;
        Display  *display, *initialize();
        struct xvimage *image, *overlay, *shape, *clip, *readimage();

        /*
         *  Initialize image, widgets,  and file update
         *  mechanism.
         */
        if (display_name != NULL)
        {
           (void) sprintf(temp, "DISPLAY=%s", display_name);
           vputenv(xvf_strcpy(temp));
        }

        display = xvf_initialize(ac, av, program);
        if (display == NULL)
        {
             fprintf(stderr, "Could not open connection to server");
             exit(0);
        }

        /*
         *  initializes structures for use of xvdisplay library
         */
        xvd_initialize(display);

        /*
         *  Read in the different images
         */
        name = vbasename(img_infile);
        image = readimage(img_infile);
        if (image == NULL) return(false);

        if (shape_infile != NULL) shape = readimage(shape_infile);
        else shape = NULL;

        if (clip_infile != NULL) clip = readimage(clip_infile);
        else clip = NULL;

        if (ov_infile != NULL) overlay = readimage(ov_infile);
        else overlay = NULL;

        if (cmap_infile != NULL) cmap = readimage(cmap_infile);
        else cmap = NULL;

        /*
         *  After reading in the display image, if use_cmap is False then
         *  we should delete the maps associated with that image.
         */
        use_colormap = use_cmap;
        if (use_cmap == False)
        {
           remove_colormap(image);
        }
        else if (cmap != NULL && image != NULL)
        {
           if (cmap->imagedata != NULL)
           {
              free(cmap->imagedata);
              cmap->imagedata = NULL;
           }
           transfer_colormap(cmap, image);
        }

        /*
         * create the image widget
         */
        xvdisplay = xvd_create_xvdisplay(display, image, shape, clip, overlay,
                                True, True, name, xoffset, yoffset, True);
        if (xvdisplay == NULL) return(FALSE);

        /*
         *  add event handler that will call putimage_exit() when the
         *  user clicks on the image
         */
        mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask;
        XtInsertEventHandler(xvdisplay->raster, mask, False, putimage_exit,
                        NULL, XtListTail);

        /*
         *  Add detect code to update when the image updates or make sure
         *  that we aren't checking stdin.  If so then we really
         *  want to call xvf_detect_fid() with fid 0.
         */
        if (update != 0.0)
        {
           if (strcmp(img_infile, "-") == 0)
              (void) xvf_detect_fid(fileno(stdin), update_stdin, xvdisplay);
           else
              (void) xvf_detect_file(img_infile, update, update_file,xvdisplay);
        }


        PUTIMAGE_DONE = False;
        while (!PUTIMAGE_DONE)
           xvf_process_event();      /* this does XtNextEvent/DispatchEvent*/

        /*
         *  The user exits by clicking the mouse on the image widget
         */
        xvd_delete_xvdisplay(xvdisplay);
        XSync(display, 0); XCloseDisplay(display);
        return(TRUE);
}


void  putimage_exit(widget, clientData, event, dispatch)

Widget  widget;                /* unused */
caddr_t clientData;            /* unused */
XEvent  *event;
Boolean *dispatch;
{
        char   character;


        /*
         *  Add detect code to update when the image updates.
         */
        if (event->type == ButtonRelease)
        {
           PUTIMAGE_DONE = True;
        }
        else if (event->type == KeyPress)
        {
           if (XLookupString(&(event->xkey), &character, 1, NULL, NULL)  == 0)
              return;

           switch (character)
           {
                case   3:
                case 'q':
                case 'Q':
                        PUTIMAGE_DONE = True;
                        break;
           }
        }
}




remove_colormap(image)

struct xvimage *image;
{
        if (image->maps != NULL) free(image->maps);
        image->maps              = NULL;
        image->map_storage_type  = VFF_MAPTYP_NONE;
        image->map_scheme        = VFF_MS_NONE;
        image->map_enable        = VFF_MAP_OPTIONAL;
        image->color_space_model = VFF_CM_NONE;
        image->map_row_size    =
        image->map_col_size    =
        image->map_subrow_size = 0;
}


transfer_colormap(cmap, image)

struct xvimage *cmap, *image;
{
        if (image->maps != NULL && image->map_row_size > 0)
            free(image->maps);

        image->map_scheme        = cmap->map_scheme;
        image->map_storage_type  = cmap->map_storage_type;
        image->map_row_size      = cmap->map_row_size;
        image->map_col_size      = cmap->map_col_size;
        image->map_subrow_size   = cmap->map_subrow_size;
        image->map_enable        = cmap->map_enable;
        image->maps_per_cycle    = cmap->maps_per_cycle;
        image->color_space_model = cmap->color_space_model;
        copymapdata(cmap, &image, TRUE);
}




int update_file(id, filename, data)

int  id;
char *filename;
char *data;
{
        struct xvimage *image, *readimage();
        DisplayStructure *xvdisplay = (DisplayStructure *) data;


        if (!(image = readimage(filename)))
           return(False);

        if (use_colormap == False)
           remove_colormap(image);
        else if (cmap != NULL && image != NULL)
           transfer_colormap(cmap, image);

        if (!(xvd_update_image(xvdisplay, image))) return(False);

        xvd_set_colormap(xvdisplay->raster, xvdisplay->colormap);

        return(True);
}

int update_stdin(id, fid, data)

int  id, fid;
char *data;
{
        struct xvimage *image, *readimage();
        DisplayStructure *xvdisplay = (DisplayStructure *) data;


        if (!(image = readimage("-")))
           return(False);

        if (use_colormap == False)
           remove_colormap(image);
        else if (cmap != NULL && image != NULL)
           transfer_colormap(cmap, image);

        if (!(xvd_update_image(xvdisplay, image))) return(False);

        xvd_set_colormap(xvdisplay->raster, xvdisplay->colormap);

        return(True);
}

/* -library_code_end */
