/*
 *	$Source: /u1/Xr/src/Xrlib/Intrinsic/RCS/utilities.c,v $
 *	$Header: utilities.c,v 1.1 86/12/17 09:09:46 swick Exp $
 */

#ifndef lint
static char *rcsid_utilities_c = "$Header: utilities.c,v 1.1 86/12/17 09:09:46 swick Exp $";
#endif	lint

#include <Xr/xr-copyright.h>

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

static char rcsid[] = "$Header: utilities.c,v 1.1 86/12/17 09:09:46 swick Exp $";
/*************************************<+>*************************************
 *****************************************************************************
 **
 **   File:        utilities.c
 **
 **   Project:     X-ray Toolbox
 **
 **   Description: This file contains a set of utility routines needed
 **                by both X-ray and applications.
 **
 **
 **   ------------------------ MODIFICATION RECORD   ------------------------
 *
 * $Log:	utilities.c,v $
 * Revision 1.1  86/12/17  09:09:46  swick
 * Initial revision
 * 
 * Revision 7.0  86/11/13  08:22:05  08:22:05  rick ()
 * Final QA release
 * 
 * Revision 6.0  86/11/10  15:23:05  15:23:05  rick ()
 * QA #2 release
 * 
 * Revision 5.4  86/11/10  14:56:56  14:56:56  rick ()
 * Added an internal memcpy routine.
 * 
 * Revision 5.3  86/11/07  14:02:47  14:02:47  rick ()
 * Added the copyright message.
 * 
 * Revision 5.2  86/11/07  11:11:41  11:11:41  rick ()
 * Changed the version string to 6.0.
 * 
 * Revision 5.1  86/11/03  13:14:19  13:14:19  rick ()
 * Added the XrVersion function.
 * 
 * Revision 5.0  86/10/28  08:23:45  08:23:45  rick ()
 * QA #1.1 release
 * 
 * Revision 4.0  86/10/20  12:09:44  12:09:44  rick ()
 * QA 1 release
 * 
 * Revision 3.4  86/10/17  12:24:20  12:24:20  rick ()
 * Linted
 * 
 * Revision 3.3  86/10/16  11:21:24  11:21:24  rick ()
 * Added register variables.
 * 
 * Revision 3.2  86/10/10  13:14:15  13:14:15  rick ()
 * Changed both GetWindowEvent and MapButton to handle the button modifiers.
 * 
 * Revision 3.1  86/10/07  09:48:37  09:48:37  rick ()
 * Modified XrMapButton to accept an eventCode to be matched against
 * the event.  TRUE is now returned if a match is found, FALSE otherwise.
 * 
 * Revision 3.0  86/10/02  15:59:31  15:59:31  rick ()
 *  Alpha release set to 3.0
 * 
 * Revision 2.0  86/09/16  08:04:22  08:04:22  rick ()
 * Added the XrMapButton and XrGetWindowEvent functions.
 * 
 * Revision 1.1  86/09/03  13:35:22  13:35:22  rick ()
 * Initial revision
 * 
 *
 *****************************************************************************
 *************************************<+>*************************************/


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



/*************************************<->*************************************
 *
 *  XrStringWidth (fontInfo, str, charWidth, charPad, spacePad)
 *  FontInfo * fontInfo;
 *  STRING8    str;
 *  INT32      charWidth;
 *  INT32      charPad;
 *  INT32      spacePad;
 *
 *
 *   Description:
 *   -----------
 *     XrStringWidth() calculates the width, in pixels, of a string
 *     and returns the length as a return value for the function.
 *
 *
 *   Inputs:
 *   ------
 *     fontInfo  -  Contains a pointer to the X FontInfo structure
 *                  used in the width calculation.
 *
 *     str       -  A pointer to the string.
 *
 *     charWidth -  The width of the string in characters or 
 *                  XrNULLTERMINATED.
 *
 *     charPad   -  The amount of extra space (pixels) to be added
 *                  to each character in the string.
 *
 *     spacePad  -  The amount of extra space (pixels) to be added
 *                  to each space character in the string.
 *
 *
 * 
 *   Outputs:
 *   -------
 *     The width of the string (in pixels) is returned as the value
 *     of the function.
 *
 *
 *   Procedures Called
 *   -----------------
 *     XStringWidth()  -  Xlib
 *
 *
 *************************************<->***********************************/


XrStringWidth (fontInfo, str, charWidth, charPad, spacePad)
FontInfo * fontInfo;
STRING8    str;
INT32      charWidth;
INT32      charPad;
INT32      spacePad;

{
   INT8    saveChar;
   STRING8 inputString;
   INT32   pixelWidth;

   saveChar = NULL;
   inputString = str;

   if (charWidth != XrNULLTERMINATED)
   {
      saveChar = *(inputString + charWidth);
      *(inputString + charWidth) = NULL;
   }         

   pixelWidth = XStringWidth (inputString, fontInfo, charPad, spacePad);

   if (saveChar != NULL)
      *(inputString + charWidth) = saveChar;

   return (pixelWidth);
}



/*************************************<->*************************************
 *
 *  XrMapButton (event)
 *  XButtonEvent * event;
 *
 *
 *   Description:
 *   -----------
 *     The function checks the input event and returns a code telling
 *     if it is an X-ray Select or Menu press or release.
 *
 *
 *   Inputs:
 *   ------
 *     event = Contains the button event to be checked.
 *     eventCode = Contains one of the defines XrSELECT, XrSELECTUP,
 *                 XrMENUPOST, or XrMENUITEMSELECT.
 *
 * 
 *   Outputs:
 *   -------
 *     FALSE = returned if the event is not a ButtonPressed,
 *             ButtonReleased or the requested event.
 *
 *     TRUE = returned if the event is the requested event.
 *
 *
 *   Procedures Called
 *   -----------------
 *     None.
 *
 *************************************<->***********************************/


INT8
XrMapButton (eventCode, event)
register INT8 eventCode;
register XButtonEvent * event;

{
   register INT8 type;
   register UINT16 modifier;


   /*
    *  First calculate which type of event it was and set the
    *  variable type appropriately.
    */

   if (event -> type & ButtonPressed)
   {
      if ((event -> detail & 0x00FF) == LeftButton)
      {
         type = XrLEFTBUTTONDOWN;
         modifier = xrLBDMod;
      }
      else if ((event -> detail & 0x00FF) == RightButton)
      {
         type = XrRIGHTBUTTONDOWN;
         modifier = xrRBDMod;
      }
      else
      {
         type = XrMIDDLEBUTTONDOWN;
         modifier = xrMBDMod;
      }
   }

   else if (event -> type & ButtonReleased)
   {
      if ((event -> detail & 0x00FF) == LeftButton)
      {
         type = XrLEFTBUTTONUP;
         modifier = xrLBUMod;
      }
      else if ((event -> detail & 0x00FF) == RightButton)
      {
         type = XrRIGHTBUTTONUP;
         modifier = xrRBUMod;
      }
      else
      {
         type = XrMIDDLEBUTTONUP;
         modifier = xrMBUMod;
      }
   }
   else
   {
      xrErrno = XrINVALIDPARM;
      return (FALSE);
   }


   /*
    *  Check the detail with the modifier to see if there is a
    *  match.
    */

   if (modifier == 0)
   {
      if ((event -> detail & (ControlMask|MetaMask|ShiftMask)) != 0)
         return (FALSE);
   }
   else if (!(modifier & (event->detail & (ControlMask|MetaMask|ShiftMask))))
      return (FALSE);


   /*
    *  Compare the variable type with all of the default button 
    *  conditions and return the one that matches.
    */

   if (type == xrSelect && eventCode == XrSELECT)
      return (TRUE);

   if (type == xrSelectUp && eventCode == XrSELECTUP)
      return (TRUE);

   if (type == xrMenuPost && eventCode == XrMENUPOST)
      return (TRUE);

   if (type == xrMenuItemSelect && eventCode == XrMENUITEMSELECT)
      return (TRUE);

   return (FALSE);
}




/*************************************<->*************************************
 *
 *  XrGetWindowEvent (eventCode, windowEvent)
 *  INT8 eventCode;
 *  xrWindowEvent * windowEvent;
 *
 *
 *   Description:
 *   -----------
 *     This function takes an event code of XrSELECT, XrSELECTUP, XrMENUPOST
 *     or XrMENUITEMSELECT and fills out the windowEvent structure so that it
 *     can be used to add into a window as an event to invoke a function.
 *
 *
 *   Inputs:
 *   ------
 *     eventCode    =  Contains the code used to generate the window event.
 *                     It must be set to XrSELECT, XrSELECTUP, XrMENUPOST,
 *                     or XrMENUITEMSELECT or the function will fail.
 *
 *
 *   Outputs:
 *   -------
 *     windowEvent  =  Will contain the information necessary for the
 *                     code.
 *
 *
 *   Procedures Called
 *   -----------------
 *     None.
 *
 *
 *************************************<->***********************************/


XrGetWindowEvent (eventCode, windowEvent)
register INT8 eventCode;
register xrWindowEvent * windowEvent;

{
   register INT8 type;


   /*
    *  Generate a type variable which contains the condition 
    *  for the event code.
    */

   if (eventCode == XrSELECT)
      type = xrSelect;
   else if (eventCode == XrSELECTUP)
      type = xrSelectUp;
   else if (eventCode == XrMENUPOST)
      type = xrMenuPost;
   else if (eventCode == XrMENUITEMSELECT)
      type = xrMenuItemSelect;
   else 
   {
      xrErrno = XrINVALIDPARM;
      return (FALSE);
   }


   /*
    *  Set up a switch for the code type to build a window event
    *  for each of the possibilities.
    */

   switch (type)
   {
      case XrLEFTBUTTONDOWN:
         windowEvent -> inputType = ButtonPressed;
         windowEvent -> inputCode = LeftButton | xrLBDMod;
      break;

      case XrLEFTBUTTONUP:
         windowEvent -> inputType = ButtonReleased;
         windowEvent -> inputCode = LeftButton | xrLBUMod;
      break;

      case XrRIGHTBUTTONDOWN:
         windowEvent -> inputType = ButtonPressed;
         windowEvent -> inputCode = RightButton | xrRBDMod;
      break;

      case XrRIGHTBUTTONUP:
         windowEvent -> inputType = ButtonReleased;
         windowEvent -> inputCode = RightButton | xrRBUMod;
      break;

      case XrMIDDLEBUTTONDOWN:
         windowEvent -> inputType = ButtonPressed;
         windowEvent -> inputCode = MiddleButton | xrMBDMod;
      break;

      case XrMIDDLEBUTTONUP:
         windowEvent -> inputType = ButtonReleased;
         windowEvent -> inputCode = MiddleButton | xrMBUMod;
      break;
   }

   return (TRUE);
}




/*************************************<->*************************************
 *
 *  INT8 *
 *  XrVersion()
 *
 *
 *   Description:
 *   -----------
 *     This function returns the version of the X-ray library being used.
 *
 *
 *   Outputs:
 *   -------
 *     The returned value will be a pointer to a static string containing
 *     the version information.
 *
 *
 *   Procedures Called
 *   -----------------
 *     None.
 *
 *
 *************************************<->***********************************/


INT8 *
XrVersion ()
{
   static INT8 version[] = "X-ray Version 10  -  07.00";

   return ((INT8 *) version);
}





_Xrmemcpy (dstPtr, srcPtr, count)
register INT8 * dstPtr;
register INT8 * srcPtr;
INT32           count;
{
   register INT8 * endPtr;

   endPtr = srcPtr + count;

   while(srcPtr != endPtr)
      *dstPtr++ = *srcPtr++;
}
