[comp.sources.amiga] v02i010: Windowutil.c

dpvc@tut.cc.rochester.edu (Davide P. Cervone) (07/26/87)

    Here is some interesting routines from Davide Cervone that he uses
to do some of his neat intuition stuff...  Allows you to get info on
current windows on the screen...
    -Doc

#	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:
#	README
#	windowutil.c
# This archive created: Sat Jul 25 19:03:07 1987
# By:	Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > README
OK, gang, here are a few interesting routines that use the Layers library to
look up information about windows and screens.  LockLayers() and
LockLayerInfo() are not explained very well in the RKM, but I think I've used
them OK here.

These routines prompted me to write HeliosMouse and ClickUpFront (SunMouse 
and ClickToFront-type programs) that suit my tastes a bit better than their 
models (I have sent HeliosMouse and ClickUpFront to Doc for posting to
comp.sources.amiga and comp.binaries.amiga).  I also will be using these 
techniques in my window manipulation hot-keys example (coming soon to a
bulletin-board near you).  The NextWindow() and PreviousWindow() routines are
particularly important in this, because they find the windows that are actually
below or above the specified window, not the one that is next in the linked
list of windows, so activating the next window will really activiate the next
window on the screen (regardless of its position in the linked list).

Don't call these routine directly from an input handler!  LockLayers() can call
Wait(), which would cause the input device to "freeze" until the layers were
locked.  But the layers might not become unlocked until the user provided some
cinput (like letting go of the mouse button when he is sizing a window).  This
could cause the system to hang.  I hope that WhichWindow() doesn't call 
lockLayers() itself, because I have used it in the HeliosMouse and
ClickUpFront input handlers.

Hope someone finds these routines useful, or at least educational.

Davide P. Cervone
dpvc@tut.cc.rochester.EDU
dpvc@ur-tut.UUCP
DPVC@UORDBV.BITNET
SHAR_EOF
cat << \SHAR_EOF > windowutil.c
/*
 *  WindowUtil.c    A set of Window and Screen utilities.
 *
 *  Written by Davide P. Cervone
 *  You may use these however you like.
 */

/*
 *  WindowAt(x,y,screen)    returns a pointer to the window that is at
 *                          the specified location on the specified screen,
 *                          or NULL if there isn't one.
 *                          (use WhichScfreen() to find the screen, if you
 *                          have to).
 *
 *  TopWindow(screen)       returns a pointer to the top-most window on
 *                          the screen (different from Screen->FirstWindow,
 *                          which is the first window created in the screen)
 *                          or NULL if there isn't one.
 *
 *  BottomWindow(screen)    returns a pointer the be bottom-most window on
 *                          the specified screen, or NULL if there isn't one.
 *
 *  NextWindow(window)      returns a pointer to the window that is below
 *                          the specified screen (different from 
 *                          Window->NextWindow, Window->Parent, and
 *                          Window->Descendent, which I don't find very useful)
 *                          or NULL if the specified window is the bottom one.
 *
 *  PreviousWindow(window)  returns a pointer to the window that is above
 *                          the specified screen (different from 
 *                          Window->NextWindow, Window->Parent, and
 *                          Window->Descendent, which I don't find very useful)
 *                          or NULL if the specified window the top one.
 *
 *  WhichScreen()           returns a pointer to the screen where the mouse
 *                          currently is pointing, or NULL if there isn't one.
 *
 *  WhichWindow()           returns a pointer the window where the mouse
 *                          currently is pointing, or NULL if there isn't one.
 */

#include <intuition/intuitionbase.h>

extern struct IntuitionBase *IntuitionBase;
extern struct Layer *WhichLayer();

#define WINDOW(layer)   ((struct Window *)((layer)->Window))
#define SCREENTOP\
   (theScreen->TopEdge << ((theScreen->ViewPort.Modes & LACE)? 0: 1))


struct Window *WindowAt(x,y,theScreen)
long x,y;
struct Screen *theScreen;
{
   struct Window *theWindow = NULL;
   struct Layer_Info *theLayerInfo = &(theScreen->LayerInfo);
   struct Layer *theLayer;
   
   LockLayers(theLayerInfo);
   theLayer = WhichLayer(theLayerInfo,x,y);
   if (theLayer) theWindow = WINDOW(theLayer);
   UnlockLayers(theLayerInfo);
   return(theWindow);
}

struct Window *TopWindow(theScreen)
struct Screen *theScreen;
{
   struct Window *theWindow = NULL;
   struct Layer_Info *theLayerInfo = &(theScreen->LayerInfo);
   struct Layer *theLayer;
   
   LockLayers(theLayerInfo);
   theLayer = theLayerInfo->top_layer;
   while (theLayer && WINDOW(theLayer) == NULL) theLayer = theLayer->back;
   if (theLayer) theWindow = WINDOW(theLayer);
   UnlockLayers(theLayerInfo);
   return(theWindow);
}

struct Window *BottomWindow(theScreen)
struct Screen *theScreen;
{
   struct Window *theWindow = NULL;
   struct Layer_Info *theLayerInfo = &(theScreen->LayerInfo);
   struct Layer *theLayer;
   
   LockLayers(theLayerInfo);
   for (theLayer = theLayerInfo->top_layer; theLayer; theLayer = theLayer->back)
      if (WINDOW(theLayer)) theWindow = WINDOW(theLayer);
   UnlockLayers(theLayerInfo);
   return(theWindow);
}

struct Window *NextWindow(theWindow)
struct Window *theWindow;
{
   struct Layer *theLayer = theWindow->WLayer;
   struct Layer_Info *theLayerInfo = theLayer->LayerInfo;
   
   LockLayers(theLayerInfo);
   do
      theLayer = theLayer->back;
   while (theLayer && WINDOW(theLayer) == NULL);
   if (theLayer) theWindow = WINDOW(theLayer); else theWindow = NULL;
   UnlockLayers(theLayerInfo);
   return(theWindow);
}

struct Window *PreviousWindow(theWindow)
struct Window *theWindow;
{
   struct Layer *theLayer = theWindow->WLayer;
   struct Layer_Info *theLayerInfo = theLayer->LayerInfo;
   
   LockLayers(theLayerInfo);
   do
      theLayer = theLayer->front;
   while (theLayer && (WINDOW(theLayer) == NULL ||
                       WINDOW(theLayer) == theWindow));
   if (theLayer) theWindow = WINDOW(theLayer); else theWindow = NULL;
   UnlockLayers(theLayerInfo);
   return(theWindow);
}

struct Screen *WhichScreen()
{
   struct Screen *theScreen;
   int y;
   
   Forbid();
   y = IntuitionBase->MouseY;
   theScreen = IntuitionBase->FirstScreen;
   while (theScreen && y < SCREENTOP) theScreen = theScreen->NextScreen;
   if (theScreen == NULL) theScreen = IntuitionBase->FirstScreen;
   Permit();
   return(theScreen);
}

struct Window *WhichWindow()
{
   struct Window *theWindow = NULL;
   struct Screen *theScreen;
   
   if ((theScreen = WhichScreen()) != NULL)
      theWindow = WindowAt(theScreen->MouseX,theScreen->MouseY,theScreen);
   return(theWindow);
}
SHAR_EOF
#	End of shell archive
exit 0