[comp.sources.amiga] v02i022: Fix to heliosmouse

dpvc@s.cc.purdue.edu.UUCP (09/17/87)

This is a modified source for Helios-Handler.c (used by Helios-Mouse) which
corrects a problem with moving Workbench icons from window to window.

Davide P. Cervone
dpvc@tut.cc.rochester.EDU
dpvc@ur-tut.UUCP
DPVC@UORDBV.BITNET

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	helio-handler.c
# This archive created: Wed Sep 16 20:39:41 1987
# By:	Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > helio-handler.c
/*
 *  Helio-Handler.c     Input Handler for HeliosMouse.  Helios-handler
 *                      calls ActivateWindow() whenever the mouse moves
 *                      over a new window.
 *
 *              Copyright (c) 1987 by Davide P. Cervone
 *  You may use this code provided this copyright notice is left intact.
 */

#include <exec/types.h>
#include <devices/inputevent.h>
#include <intuition/intuitionbase.h>

static char *version = "Helios-Handler v1.1 (August 1987)";
static char *author  = "Copyright (c) 1987 by Davide P. Cervone";

extern struct Layer *WhichLayer();
extern void myHandlerStub();

/*
 *  The window associated with a given Layer structure.
 */
#define WINDOW(layer)   ((struct Window *)((layer)->Window))

/*
 *  The top line of a screen (in INTERLACED lines)
 */
#define SCREENTOP\
   (theScreen->TopEdge << ((theScreen->ViewPort.Modes & LACE)? 0: 1))

/*
 *  The mouse button qualifiers
 */
#define BUTTONSDOWN     (IEQUALIFIER_LEFTBUTTON | IEQUALIFIER_RBUTTON)


struct IntuitionBase *IntuitionBase = NULL;
struct LayersBase    *LayersBase    = NULL;
struct SysBase       *SysBase       = NULL;

/*
 *  Setup()
 *
 *  HeliosMouse calls LoadSeg() to get this handler into memory.  The segment
 *  that it gets points to this routine.  HeliosMouse calls Setup() and 
 *  passes the IntuitionBase, LayersBase and SysBase pointers that it
 *  has initialized (with OpenLibrary()).  Setup returns a pointer to
 *  the actual input handler, which HeliosMouse installs.
 */

long Setup(Ibase,Lbase,Sbase)
struct IntuitionBase *Ibase;
struct LayersBase *Lbase;
struct SysBase *Sbase;
{
   IntuitionBase = Ibase;
   LayersBase = Lbase;
   SysBase = Sbase;
   return((long) &myHandlerStub);
}


/*
 *  myHandler()
 *
 *  This is the input handler.  Whenever a mouse move or a keyboard event
 *  occurs, we check to see if the mouse is over an inactive window, and
 *  if so, we activate that window.
 *
 *  To do this, we get the current absolute Y position of the mouse and
 *  look through the Intuition screens for the first one that is closer
 *  to the top of the View than the mouse is (i.e., the first one that is
 *  high enough to be under the mouse).  Note that we must convert non-
 *  interlace screen coordinates to interlaces ones in order to be able
 *  to compare them to the mouse position (the SCREENTOP macro does this).
 *  If no screen is found (this should never happen, but just in case), then 
 *  just use the currently active one.
 *
 *  From the selected screen we get the mouse x and y position (if it's a 
 *  mouse move, we add the event offsets to find the new mouse position).  
 *  Using these, we call WhichLayer(), which tells us which Layer within 
 *  that screen the mouse was pointing at.  If that layer has a window and 
 *  that window is not currently the active window, we activate it.
 *
 *  When we're all through looking at events, we pass the list on, so that
 *  Intuition (and any other handlers) can do their thing.
 *
 *  Compile this section with -dKEY_ONLY to have windows activate only when 
 *  a key is pressed (not when the mouse moves over an inactive one).
 */

struct InputEvent *myHandler(EventList,data)
struct InputEvent *EventList;
APTR data;
{
   register struct InputEvent *theEvent = EventList;
   register struct Layer  *theLayer;
   register struct Window *theWindow;
   register struct Screen *theScreen;
   register long x,y;

   Forbid();
   while(theEvent)
   {
      if (
          #ifndef KEY_ONLY
            (theEvent->ie_Class == IECLASS_RAWMOUSE &&
            (theEvent->ie_X != 0 || theEvent->ie_Y != 0) &&
            (theEvent->ie_Qualifier & BUTTONSDOWN) == 0) ||
          #endif
            (theEvent->ie_Class == IECLASS_RAWKEY)
         )
      {
         y = IntuitionBase->MouseY;
         theScreen = IntuitionBase->FirstScreen;
         while (theScreen && y < SCREENTOP) theScreen = theScreen->NextScreen;
         if (theScreen == NULL) theScreen = IntuitionBase->ActiveScreen;

         x = theScreen->MouseX;
         y = theScreen->MouseY;
         #ifndef KEY_ONLY
            if (theEvent->ie_Class == IECLASS_RAWMOUSE)
            {
               x += theEvent->ie_X;
               y += theEvent->ie_Y;
            }
         #endif

         theLayer = WhichLayer(&(theScreen->LayerInfo),x,y);
         if (theLayer && (theWindow = WINDOW(theLayer)))
            if (theWindow != IntuitionBase->ActiveWindow)
               ActivateWindow(theWindow);
      }
      theEvent = theEvent->ie_NextEvent;
   }
   Permit();
   return(EventList);
}

SHAR_EOF
#	End of shell archive
exit 0