/*
 *	$Source: /u1/Xr/src/Xrlib/Editor/RCS/SRaster.c,v $
 *	$Header: SRaster.c,v 1.1 86/12/17 09:04:33 swick Exp $
 */

#ifndef lint
static char *rcsid_SRaster_c = "$Header: SRaster.c,v 1.1 86/12/17 09:04:33 swick Exp $";
#endif	lint


#include <Xr/xr-copyright.h>

/* $Header: SRaster.c,v 1.1 86/12/17 09:04:33 swick Exp $ */
/* Copyright 1986, Hewlett-Packard Company */
/* Copyright 1986, Massachussetts Institute of Technology */

static char rcsid[] = "$Header: SRaster.c,v 1.1 86/12/17 09:04:33 swick Exp $";
/*************************************<+>*************************************
 *****************************************************************************
 **
 **   File:        SRaster.c
 **
 **   Project:     X-ray Toolbox
 **
 **   Description: 
 **         This file contains the source code for the static raster
 **         field editor.  This editor is capable of displaying an
 **         uneditable raster image.
 **
 **
 **   ------------------------ MODIFICATION RECORD   ------------------------
 *
 * $Log:	SRaster.c,v $
 * Revision 1.1  86/12/17  09:04:33  swick
 * Initial revision
 * 
 * Revision 7.0  86/11/13  08:26:55  08:26:55  fred ()
 * Final QA Release
 * 
 * Revision 6.0  86/11/10  15:35:24  15:35:24  fred ()
 * QA #2 release
 * 
 * Revision 5.1  86/11/07  14:22:30  14:22:30  fred ()
 * Added new copyright message.
 * 
 * Revision 5.0  86/10/28  08:32:36  08:32:36  fred ()
 * QA #1.1 release
 * 
 * Revision 4.0  86/10/20  12:13:13  12:13:13  fred ()
 * QA #1 release
 * 
 * Revision 3.1  86/10/09  07:53:08  07:53:08  fred ()
 * Added default color check to create routine.
 * 
 * Revision 3.0  86/10/02  16:01:00  16:01:00  fred ()
 * Alpha release set to 3.0
 * 
 * Revision 2.3  86/09/26  08:15:06  08:15:06  fred ()
 * Filled in the procedure headers.
 * 
 * Revision 2.2  86/09/22  13:11:44  13:11:44  fred ()
 * Added calls to XrEditorGroup().
 * 
 * Revision 2.1  86/09/19  12:17:45  12:17:45  fred ()
 * Modified names of the info and data structures.
 * 
 * Revision 2.0  86/09/16  08:09:38  08:09:38  fred ()
 * Updated input processing routine to use new SELECT strategy.
 * 
 * Revision 1.3  86/09/16  05:49:25  05:49:25  fred ()
 * Modified to swallow a select up event.
 * 
 * Revision 1.2  86/09/10  11:49:03  11:49:03  fred ()
 * Fixed bug in createSRaster(), where an invalid pixmap id
 * caused xrErrno to be set to the wrong value.
 * 
 * Revision 1.1  86/09/04  06:43:22  06:43:22  fred ()
 * Initial revision
 * 
 * 
 *
 *****************************************************************************
 *************************************<+>*************************************/



#include <X/Xlib.h>
#include <Xr/defs.h>
#include <Xr/types.h>
#include <Xr/in_types.h>

extern INT32 createSRaster();
extern INT32 drawSRaster();
extern INT32 processSRaster();




/*************************************<->*************************************
 *
 *  xrEditor *
 *  XrStaticRaster (staticRaster, message, data)
 *
 *     xrEditor * staticRaster;
 *     INT32      message;
 *     INT8     * data;
 *
 *   Description:
 *   -----------
 *     This routine is the message handler routine for the static raster
 *     field editor.  It will verify that the 'message' parameter
 *     specifies an action understood by this editor, and will then
 *     call the appropriate message handling routine, passing the 'data'
 *     parameter along.
 *
 *
 *   Inputs:
 *   ------
 *     staticRaster = For all messages issued to this editor, with the
 *                    exception of MSG_NEW and MSG_SIZE, this parameter
 *                    contains the instance pointer for the instance
 *                    which is to be operated upon.
 *
 *     message = This indicates which operation is to be performed by
 *               this editor handler.
 *
 *     data = This is interpreted as either a scalar value or a pointer,
 *            and its form is dependent upon the 'message' parameter.
 * 
 *   Outputs:
 *   -------
 *     Upon successful completion of handling any message, the instance
 *          pointer will be returned.  In addition, any given message
 *          may return additionaly information, by means of a structure
 *          pointed to by the 'data' parameter.
 *
 *     Upon failure, NULL is returned, and xrErrno is set.
 *
 *   Procedures Called
 *   -----------------
 *   _MsgNew()           [MsgCommon.c]
 *   _MsgFree()          [MsgCommon.c]
 *   _MsgSetState()      [MsgCommon.c]
 *   _MsgRedraw()        [MsgCommon.c]
 *   _MsgEdit()          [MsgCommon.c]
 *   XrCopyRect()        [calc.c]
 *   _XrMakeInvisible()  [editorUtil.c]
 *   sizeSRaster()
 *   createSRaster()
 *   drawSRaster()
 *
 *************************************<->***********************************/

xrEditor *
XrStaticRaster (staticRaster, message, data)

   register xrEditor * staticRaster;
            INT32      message;
            INT8     * data;

{
   /* Determine the action being requested */
   switch (message)
   {
      case MSG_NEW:
      {
           /* Create a new instance of this editor */
           return ((xrEditor *) _MsgNew (staticRaster, data,
                                         sizeof(xrStaticRasterData),
                                         createSRaster, drawSRaster,
                                         NULL, XrStaticRaster, NULL));
      }

      case MSG_FREE:
      {
           /* Destroy the specified editor instance */
           return ((xrEditor *) _MsgFree (staticRaster, NULL));
      }

      case MSG_GETSTATE:
      {
           /*
            * Return the current state flag settings for the
            * specified static raster editor instance.
            */
           return ((xrEditor *) _MsgGetState (staticRaster, data));
      }

      case MSG_SETSTATE:
      {
           /*
            * Change the state flags associated with the specified
            * static raster editor instance.
            */
           return ((xrEditor *) _MsgSetState (staticRaster, data,
                                              drawSRaster, NULL));
      }

      case MSG_SIZE:
      {
	   /*
            * Return the size of the rectangle needed to enclose
            * an instance of this editor, using the specifications
            * passed in by the application program.
	    */
           xrStaticRasterInfo *srInfoPtr;

           srInfoPtr = (xrStaticRasterInfo *)data;

           if (srInfoPtr == NULL)
           {
              xrErrno = XrINVALIDPTR;
              return ((xrEditor *)NULL);
           }
           else if (sizeSRaster (srInfoPtr, &srInfoPtr->editorRect) == FALSE)
           {
              /* Size request failed; xrErrno set by sizeSRaster() */
              return ((xrEditor *)NULL);
           }

           return ((xrEditor *) TRUE);
      }

      case MSG_REDRAW:
      {
         /* Redraw a particular static raster instance */
         return ((xrEditor *) _MsgRedraw (staticRaster, data,
                                          drawSRaster, NULL));
      }

      case MSG_MOVE:
      {
         /*
          * Reposition the origin of the editorRect to the absolute
          * position specified by the passed in point.
          */
         POINT     * ptPtr = (POINT *) data;
         RECTANGLE   workRect;

         if (staticRaster == NULL)
         {
            xrErrno = XrINVALIDID;
            return ((xrEditor *) NULL);
         }
         else if (data == NULL)
         {
            xrErrno = XrINVALIDPTR;
            return ((xrEditor *) NULL);
         }

         /* Reset the origin for the editorRect */
         XrCopyRect (&staticRaster->editorRect, &workRect);
         staticRaster->editorRect.x = ptPtr->x;
         staticRaster->editorRect.y = ptPtr->y;

         if (staticRaster->editorState & XrVISIBLE)
         {
            /* Remove the instance from the window */
            _XrMakeInvisible (staticRaster->editorWindowId, &workRect, TRUE);

            /* Redisplay the instance */
            drawSRaster (staticRaster, NULL);
         }

         /* Force the editor group rectangle to be recalculated */
         XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, staticRaster);
         return (staticRaster);
      }

      case MSG_EDIT:
      {
	 /*
          * Process the incoming event, and generate a return event,
          * indicating how the editor instance was modified.
	  */
         return ((xrEditor *) _MsgEdit (staticRaster, data,
                                         processSRaster, XrSTATICRASTER));
      }

      default:
         /* All other commands are invalid */
         xrErrno = XrINVALIDMSG;
         return ((xrEditor *)NULL);

   }  /* end of switch */
}  /* end of XrStaticRaster() */


/*************************************<->*************************************
 *
 *  INT32
 *  sizeSRaster (srInfoPtr, rectPtr)
 *
 *     xrStaticRasterInfo * srInfoPtr;
 *     RECTANGLE          * rectPtr;
 *
 *   Description:
 *   -----------
 *     Given the dimensions of the static raster image, this routine
 *     will fill in the RECTANGLE structure pointed to by the 'rectPtr'
 *     parameter, with the definition of the 0-based rectangle large
 *     enough to completely contain the raster image.
 *
 *
 *   Inputs:
 *   ------
 *     srInfoPtr = This points to an instance of the static raster 'info'
 *                 structure; it must contain the height and width of the
 *                 raster image being sized.
 *
 *     rectPtr = This points to a RECTANGLE structure, into which the 0-based
 *               rectangle definition is returned.
 * 
 *   Outputs:
 *   -------
 *     Upon successful completion, TRUE is returned, and the 0-based
 *          rectangle is returned, as described above.
 *
 *     Upon failure, FALSE is returned, and xrErrno is set.
 *
 *   Procedures Called
 *   -----------------
 *
 *************************************<->***********************************/

static
INT32
sizeSRaster (srInfoPtr, rectPtr)

   register xrStaticRasterInfo * srInfoPtr;
   register RECTANGLE     * rectPtr;

{
   INT16  width = srInfoPtr->rasterWidth;
   INT16  height = srInfoPtr->rasterHeight;

   /* Validate parameters */
   if (width <= 0 || height <= 0)
   {
      xrErrno = XrINVALIDPARM;
      return (FALSE);
   }

   /* Set the rectangle coordinates */
   rectPtr->x = 0;
   rectPtr->y = 0;
   rectPtr->height = height;
   rectPtr->width = width;

   return (TRUE);
}


/*************************************<->*************************************
 *
 *  INT32
 *  createSRaster (srDataPtr, srInfoPtr, message)
 *
 *     xrStaticRasterData * srDataPtr;
 *     xrStaticRasterInfo * srInfoPtr;
 *     INT32                message;
 *
 *   Description:
 *   -----------
 *     This routine takes the definition of a static raster instance,
 *     contained in the structure pointed to by 'srInfoPtr', and attempts
 *     to create a new static raster instance.  This involves verifying
 *     several parameters, and then filling in several fields of the
 *     structure pointed to by the 'srDataPtr' parameter.
 *
 *
 *   Inputs:
 *   ------
 *     srDataPtr = This points to the internal 'data' structure which is
 *                 to contain all of the information describing the new
 *                 instance, once it is created.
 *
 *     srInfoPtr = This points to the 'info' structure, containing the
 *                 definition of the new static raster instance.
 *
 *     message = This parameter is unused, but is provided so that _MsgNew()
 *               can invoke this routine.
 * 
 *   Outputs:
 *   -------
 *     Upon successful completion, TRUE is returned.
 *
 *     Upon failure, FALSE is returned, and xrErrno is set.
 *
 *   Procedures Called
 *   -----------------
 *   sizeSRaster()
 *
 *************************************<->***********************************/

static
INT32
createSRaster (srDataPtr, srInfoPtr, message)

            xrStaticRasterData * srDataPtr;
   register xrStaticRasterInfo * srInfoPtr;
            INT32           message;

{
   register RECTANGLE * editorRect = &(srInfoPtr->editorRect);
            RECTANGLE   workRect;

   /* Make sure the editorRect is large enough to hold the instance */
   if (sizeSRaster (srInfoPtr, &workRect) == FALSE)
      /* xrErrno is set by sizeSRaster */
      return (FALSE);

   if ((editorRect->width != workRect.width) ||
       (editorRect->height != workRect.height))
   {
      xrErrno = XrINVALIDRECT;
      return (FALSE);
   }
   else if (srInfoPtr->rasterId == 0)
   {
      xrErrno = XrINVALIDID;
      return (FALSE);
   }

   /* 
    * Now that we know all of the parameters are valid, we can start
    * filling in the structure pointed to by 'srDataPtr'.
    */
   srDataPtr->srRasterId = srInfoPtr->rasterId;

   return (TRUE);
}


/*************************************<->*************************************
 *
 *  INT32
 *  drawSRaster (staticRaster, drawOption)
 *
 *     xrEditor * staticRaster;
 *     INT32      drawOption;
 *
 *   Description:
 *   -----------
 *     This routine will display the static raster image, if the instance
 *     is visible, or it will fill the area occupied by the instance using
 *     the window's background tile, if the instance is not visible.
 *
 *
 *   Inputs:
 *   ------
 *     staticRaster = This points to the instance structure describing the
 *                    instance to be drawn.
 *
 *     drawOption = Not used; this parameter is included so that this
 *                  routine may be called by _MsgRedraw(), _MsgNew(),
 *                  _MsgFree() and _MsgSetState().
 * 
 *   Outputs:
 *   -------
 *
 *   Procedures Called
 *   -----------------
 *   _XrMakeInvisible()  [editorUtil.c]
 *   XPixmapPut()        [libX.a]
 *
 *************************************<->***********************************/

static
INT32
drawSRaster (staticRaster, drawOption)

   register xrEditor * staticRaster;
            INT32      drawOption;

{
            xrStaticRasterData * srDataPtr;
            Window          windowId;
   register RECTANGLE     * editorRect;

   /* Initialize variables we will be using */
   srDataPtr = (xrStaticRasterData *) staticRaster->editorData;
   windowId = staticRaster->editorWindowId;
   editorRect = &staticRaster->editorRect;

   /*
    * If the instance is not visible, then fill its area with the
    * background tile for the port, thus making the instance invisible.
    */
   if (!(staticRaster->editorState & XrVISIBLE))
   {
      _XrMakeInvisible (windowId, editorRect, TRUE);
      return;
   }

   /* Tell the server to display the appropriate pixmap */
   XPixmapPut (windowId, 0, 0, editorRect->x, editorRect->y,
               editorRect->width, editorRect->height,
               srDataPtr->srRasterId, GXcopy, AllPlanes);
}


/*************************************<->*************************************
 *
 *  INT32
 *  processSRaster (staticRaster, event, returnEvent)
 *
 *     xrEditor     * staticRaster;
 *     XButtonEvent * event;
 *     xrEvent      * returnEvent;
 *
 *   Description:
 *   -----------
 *     This routine handles all SELECT events which occur with a visible
 *     and sensitive static raster instance.  By the time this routine is
 *     called, we already know that the instance is visible and sensitive,
 *     and we also know that the SELECT occurred within the bounds of the
 *     instance's editor rectangle.  The static raster editor will simply
 *     set up a return event which indicates that the instance was selected.
 *
 *
 *   Inputs:
 *   ------
 *     staticRaster = This points to the instance structure describing the
 *                    editor instance which was selected.
 *
 *     event = This points to a copy of the SELECT input event.
 *
 *     returnEvent = This points to an event structure, which, upon
 *                   completion of this call, will be pushed onto the
 *                   front of the application's input queue; it will be
 *                   the means by which the editor tells the application
 *                   that an editor instance was processed.
 * 
 *   Outputs:
 *   -------
 *     The 'value1' field in the event structure pointed to by the
 *         'returnEvent' parameter will be filled in.
 *
 *   Procedures Called
 *   -----------------
 *
 *************************************<->***********************************/

static
INT32
processSRaster (staticRaster, event, returnEvent)

   xrEditor     * staticRaster;
   XButtonEvent * event;
   xrEvent      * returnEvent;

{
   returnEvent->value1 = XrSELECT;
}

