home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 092.lha / Click / Click-Handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-21  |  7.1 KB  |  185 lines

  1. /*
  2.  *  Click-Handler.c     Input Handler for ClickUpFront, which brings a
  3.  *                      window to the front when you double-click in it.
  4.  *
  5.  *              Copyright (c) 1987 by Davide P. Cervone
  6.  *  You may use this code provided this copyright notice is left intact.
  7.  */
  8.  
  9. #include <exec/types.h>
  10. #include <devices/inputevent.h>
  11. #include <intuition/intuitionbase.h>
  12.  
  13. static char *version = "Click-Handler v2.1 (October 1987)";
  14. static char *author  = "Copyright (c) 1987 by Davide P. Cervone";
  15.  
  16. extern struct Layer *WhichLayer();
  17. extern void myHandlerStub();
  18.  
  19. #define WINDOW(layer)       ((struct Window *)((layer)->Window))
  20. #define TOPLAYER(screen)    ((screen)->LayerInfo.top_layer)
  21.  
  22. #define ie_Secs         ie_TimeStamp.tv_secs
  23. #define ie_Mics         ie_TimeStamp.tv_micro
  24.  
  25. static UBYTE LastCode = 0;     /* the last ie_Code for a button event */
  26. static long LastSecs = 0;      /* seconds field from last mouse click */
  27. static long LastMics = 0;      /* micros  field from last mouse click */
  28. static long StayMask;          /* qualifier keys that allow you to click */
  29.                                /* a window without bringing it to the front */
  30.  
  31.  
  32. struct IntuitionBase *IntuitionBase = NULL;
  33. struct LayersBase    *LayersBase    = NULL;
  34. struct SysBase       *SysBase       = NULL;
  35.  
  36.  
  37. /*
  38.  *  Setup()
  39.  *
  40.  *  ClickUpFront calls LoadSeg() to get this handler into memory.  The segment
  41.  *  that it gets points to this routine.  ClickUpFront calls Setup() and 
  42.  *  passes the IntuitionBase, LayersBase and SysBase pointers that it
  43.  *  has initialized (with OpenLibrary()).  Setup returns a pointer to
  44.  *  the actual input handler, which ClickUpFront installs.
  45.  */
  46.  
  47. static long Setup(Ibase,Lbase,Sbase,flags)
  48. struct IntuitionBase *Ibase;
  49. struct LayersBase *Lbase;
  50. struct SysBase *Sbase;
  51. long flags;
  52. {
  53.    IntuitionBase = Ibase;
  54.    LayersBase = Lbase;
  55.    SysBase = Sbase;
  56.    StayMask = flags;
  57.    return((long) &myHandlerStub);
  58. }
  59.  
  60.  
  61. /*
  62.  *  myHandler()
  63.  *
  64.  *  This is the input handler.  For each event in the event list:
  65.  *  If it is a raw mouse event:
  66.  *    Ignore button-up events,
  67.  *    For button down events, if it is the same as the last button, and
  68.  *      the mouse has not moved, and the button was a double click, then
  69.  *      Find the active window and screen (where the button press occured)
  70.  *      for SELECTDOWN buttons:
  71.  *        If the screen is not the first one, then bring it to the front. 
  72.  *        If a window is selected, then find the top layer with a window.
  73.  *        If the window where the click ocurred is not the top, and
  74.  *          the stay-put qualifier key is not pressed, then 
  75.  *            bring the window to the front.
  76.  *      for MENUDOWN buttons:
  77.  *        If a window is selected, and the window is not the bottom window
  78.  *          already, and the window below it is not a backdrop window, then
  79.  *          if the selected window has no double-menu requester and 
  80.  *            the stay-put qualifier is not present (if there IS a 
  81.  *            DM request and the stay-put qualifier IS present), then 
  82.  *              send the window to the back.
  83.  *              change the event into a mouse move with zero offsets
  84.  *              (that is, remove one of the right button clicks).
  85.  *         otherwise (there is no window, or it is already at the bottom,
  86.  *          or the one below is a backdrop), then
  87.  *          find the first window on the next screen and activate it.
  88.  *          Send the active screen to the back.
  89.  *     Otherwise (the mouse was moved, or it was not a double click, etc.)
  90.  *       record this click and the time it ocurred.
  91.  *    For mouse moves, clear the last code (ie, don't match a double click)
  92.  *  If the event was a keyboard event, then set the times to zero.
  93.  *  Ignore all other event types (timer, disk).
  94.  *
  95.  *  Finally, return the event list so that Intuition can do its thing.
  96.  *
  97.  */
  98.  
  99. struct InputEvent *myHandler(EventList,data)
  100. struct InputEvent *EventList;
  101. APTR data;
  102. {
  103.    register struct InputEvent *theEvent = EventList;
  104.    register struct Window *theWindow;
  105.    register struct Screen *theScreen;
  106.    register struct Layer *topLayer;
  107.  
  108.    Forbid();
  109.    while(theEvent)
  110.    {
  111.       switch(theEvent->ie_Class)
  112.       {
  113.          case IECLASS_RAWMOUSE:
  114.             if ((theEvent->ie_Code & IECODE_UP_PREFIX) == 0)
  115.             {
  116.                if (theEvent->ie_Code == LastCode &&
  117.                    theEvent->ie_X == 0 && theEvent->ie_Y == 0 &&
  118.                    DoubleClick(LastSecs,LastMics,
  119.                               theEvent->ie_Secs,theEvent->ie_Mics))
  120.                {
  121.                   theWindow = IntuitionBase->ActiveWindow;
  122.                   theScreen = IntuitionBase->ActiveScreen;
  123.                   switch(LastCode)
  124.                   {
  125.                      case SELECTDOWN:
  126.                         if (theScreen != IntuitionBase->FirstScreen)
  127.                            ScreenToFront(theScreen);
  128.                         if (theWindow)
  129.                         {
  130.                            topLayer = TOPLAYER(theScreen);
  131.                            while (topLayer && WINDOW(topLayer) == NULL)
  132.                               topLayer = topLayer->back;
  133.                            if (theWindow != WINDOW(topLayer) &&
  134.                               (theEvent->ie_Qualifier & StayMask) == 0)
  135.                                  WindowToFront(theWindow);
  136.                         }
  137.                         break;
  138.  
  139.                      case MENUDOWN:
  140.                         if (theWindow && theWindow->WLayer->back &&
  141.                            (theWindow->Flags & BACKDROP) == 0 &&
  142.                            (theWindow->WLayer->back->Flags &
  143.                             LAYERBACKDROP) == 0)
  144.                         {
  145.                            if (theWindow && (theWindow->DMRequest == NULL) ==
  146.                               ((theEvent->ie_Qualifier & StayMask) == 0))
  147.                            {
  148.                               WindowToBack(theWindow);
  149.                               theEvent->ie_Code = IECODE_NOBUTTON;
  150.                               theEvent->ie_X = theEvent->ie_Y = 0;
  151.                            }
  152.                         } else {
  153.                            if (theScreen->NextScreen)
  154.                            {
  155.                               topLayer = TOPLAYER(theScreen->NextScreen);
  156.                               while (topLayer && WINDOW(topLayer) == NULL)
  157.                                  topLayer = topLayer->back;
  158.                               if (topLayer && WINDOW(topLayer))
  159.                                  ActivateWindow(WINDOW(topLayer));
  160.                               ScreenToBack(theScreen);
  161.                            }
  162.                         }
  163.                         break;
  164.                   }
  165.                   LastCode = 0;
  166.                } else {
  167.                   LastCode = theEvent->ie_Code;
  168.                   LastSecs = theEvent->ie_Secs;
  169.                   LastMics = theEvent->ie_Mics;
  170.                }
  171.             } else {
  172.                if (theEvent->ie_Code == IECODE_NOBUTTON) LastCode = 0;
  173.             }
  174.             break;
  175.  
  176.          case IECLASS_RAWKEY:
  177.             LastSecs = LastMics = 0;
  178.             break;
  179.       }
  180.       theEvent = theEvent->ie_NextEvent;
  181.    }
  182.    Permit();
  183.    return(EventList);
  184. }
  185.