home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / yak.lha / Yak / src / handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-18  |  7.8 KB  |  328 lines

  1. /*
  2.  * handler.c
  3.  * 
  4.  * Routines to set up handler.
  5.  * Part of Yak.
  6.  * 
  7.  * Martin W. Scott, 9/92.
  8.  */
  9. #include <exec/types.h>
  10. #include <exec/exec.h>
  11. #include <hardware/custom.h>
  12. #include <hardware/dmabits.h>
  13. #include <devices/input.h>
  14. #include <devices/inputevent.h>
  15. #include <libraries/commodities.h>
  16. #include <graphics/gfxmacros.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/intuitionbase.h>
  19. #include <clib/alib_protos.h>
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22. #include <proto/layers.h>
  23. #include <proto/intuition.h>
  24.  
  25. #include "yak.h"
  26.  
  27. #define TIMERCOUNT    2    /* how long mouse must stop before autopoint */
  28.  
  29. CxObj *clickobj;
  30. ULONG clicksigflag;
  31. static BYTE clicksigbit;
  32. static struct Task *thistask;
  33. static mouseoff = FALSE;
  34.  
  35. #define INTERRUPT void __interrupt __saveds
  36.  
  37. /* modified from DMouse */
  38. struct Window *
  39. WindowUnderMouse()
  40. {
  41.     struct Layer *layer;
  42.     struct Screen *scr = IntuitionBase->FirstScreen;
  43.     WORD mousex, mousey;
  44.  
  45.     /* these wont change since this routine called inside Forbid()/Permit() */
  46.     mousey = IntuitionBase->MouseY;
  47.     mousex = IntuitionBase->MouseX;
  48.  
  49.     for (; scr; scr = scr->NextScreen)
  50.     {
  51.         if (!(scr->ViewPort.Modes & LACE))
  52.             mousey >>= 1;
  53.         if (!(scr->ViewPort.Modes & HIRES))
  54.             mousex >>= 1;
  55.  
  56.         if (layer = WhichLayer(&scr->LayerInfo, mousex - scr->ViewPort.DxOffset, mousey - scr->ViewPort.DyOffset))
  57.             break;
  58.         if (mousey >= scr->ViewPort.DyOffset)
  59.             break;
  60.     }
  61.  
  62.     return (layer ? layer->Window : NULL);
  63. }
  64.  
  65. /* does active window have an active string gadget? */
  66. BOOL
  67. StrGadgetActive(struct Window *w)
  68. {
  69.     struct Gadget *g = w->FirstGadget;
  70.  
  71.     for (; g; g = g->NextGadget)
  72.         if ((g->GadgetType & STRGADGET) && (g->Flags & GFLG_SELECTED))
  73.             return TRUE;
  74.     return FALSE;
  75. }
  76.  
  77. /* activate window under mouse */
  78. /* only if: no menus, no string gadgets active */
  79. /* that last one is a bit difficult, since IntuitionBase went REALLY private... */
  80. /* But hey! Works with SiliconMenus Iris option! (Unlike AutoPoint, DMouse) */
  81. void
  82. ActivateMouseWindow()
  83. {
  84.     struct Window *win;
  85.  
  86.     Forbid();
  87.  
  88.     if ((win = WindowUnderMouse()) &&
  89.         !(win->Flags & WFLG_WINDOWACTIVE) &&
  90.         !(IntuitionBase->ActiveWindow->Flags & (WFLG_INREQUEST|WFLG_MENUSTATE)) &&
  91.         !StrGadgetActive(IntuitionBase->ActiveWindow))
  92.     {
  93.         ActivateWindow(win);
  94.     }
  95.     Permit();
  96. }
  97.  
  98. #ifdef USE_SETPOINTER
  99.  
  100. /*
  101.  * Problem with these routines is that (e.g.) reqtools changes pointer to
  102.  * 'busy' clock when opening a file-requester. When it's finished, it restores
  103.  * blank pointer, but these routines have lost track of that window.
  104.  */
  105.  
  106. static UWORD __chip BlankPointer[] = {
  107.    0x0000, 0x0000,    /* position control */
  108.             /* zilcho data */
  109.    0x0000, 0x0000    /* next sprite field */
  110. };
  111.  
  112. static struct Window *blankedwin;
  113. static USHORT *Pointer;
  114. static BYTE PtrHeight;
  115. static BYTE PtrWidth;
  116. static BYTE XOffset, YOffset;
  117.  
  118. void
  119. TurnMouseOff()
  120. {
  121.     mouseoff = TRUE;
  122.  
  123.     Forbid();
  124.  
  125.     blankedwin = IntuitionBase->ActiveWindow;
  126.     Pointer = blankedwin->Pointer;
  127.     PtrHeight = blankedwin->PtrHeight;
  128.     PtrWidth = blankedwin->PtrWidth;
  129.     XOffset = blankedwin->XOffset;
  130.     YOffset = blankedwin->YOffset;
  131.  
  132.     SetPointer(blankedwin, BlankPointer, 0,0,0,0);
  133.  
  134.     Permit();
  135. }
  136.  
  137. void
  138. TurnMouseOn()
  139. {
  140.     struct Screen *scr = IntuitionBase->FirstScreen;
  141.     struct Window *win;
  142.  
  143.     mouseoff = FALSE;
  144.  
  145.     Forbid();
  146.     /* check that window still exists */
  147.     for (; scr; scr = scr->NextScreen)
  148.         for (win = scr->FirstWindow; win; win = win->NextWindow)
  149.             if (win && win == blankedwin)
  150.             {
  151.                 SetPointer(win, Pointer,
  152.                         PtrHeight, PtrWidth,
  153.                         XOffset, YOffset);
  154.                 Permit();
  155.                 return;
  156.             }
  157.     Permit();
  158.     return;
  159. }
  160.  
  161. #else    /* turn of sprites to blank mouse */
  162.  
  163. extern struct Custom __far custom;
  164.  
  165. /* the mouse-blank time is unadjustable at the moment. It's less crucial
  166.  * anyway -- you either want it or you don't.
  167.  */ 
  168.  
  169. #define TurnMouseOn() {WaitTOF(); ON_SPRITE; mouseoff = FALSE;}
  170. #define TurnMouseOff() {WaitTOF(); OFF_SPRITE; custom.spr[0].dataa = custom.spr[0].datab=0; mouseoff = TRUE;}
  171.  
  172. #endif /* USE_SETPOINTER */
  173.  
  174. static BOOL blanked;
  175. static struct Screen *blankscr;
  176. /* blank display, by putting up a black screen */
  177. void
  178. BlankScreen()
  179. {
  180.     if (blankscr)
  181.         ScreenToFront(blankscr);
  182.     else if (blankscr = OpenScreenTags(NULL,SA_Depth, 1,
  183.                         SA_Quiet, TRUE,
  184.                         TAG_DONE))
  185.     {
  186.         SetRGB4(&blankscr->ViewPort, 0, 0, 0, 0);
  187.         blanked = TRUE;
  188.     }
  189.     TurnMouseOff();
  190. }
  191.  
  192. /* unblank display, i.e. close our screen */
  193. void
  194. UnBlankScreen()
  195. {
  196.     if (blankscr)
  197.         CloseScreen(blankscr);
  198.     blankscr = NULL;
  199.     blanked = FALSE;
  200.     TurnMouseOn();        /* ooer! */
  201. }
  202.  
  203.  
  204. #define ALL_BUTTONS    (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
  205. #define KEY_QUAL    (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
  206.             |IEQUALIFIER_CONTROL \
  207.             |IEQUALIFIER_LALT|IEQUALIFIER_RALT \
  208.             |IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)
  209.  
  210. /* the input handler itself */
  211. INTERRUPT Handler(CxMsg *CxMsg, CxObj *CO)
  212. {
  213.     static struct timeval lastclick;/* last left-button click */
  214.     static UBYTE apcount;        /* timer events since last mousemove */
  215.     struct InputEvent *ev;
  216.  
  217.  
  218.     ev = (struct InputEvent *)CxMsgData(CxMsg);
  219.  
  220.     if (ev->ie_Class == IECLASS_TIMER)
  221.     {
  222.         if (autopoint && apcount && !--apcount)    /* auto-activate? */
  223.             ActivateMouseWindow();
  224.  
  225.         if (blanktimeout && !--blankcount)    /* blank screen? */
  226.         {
  227.             BlankScreen();
  228.             blankcount = blanktimeout;    /* reset counter */
  229.         }                    /* in case sceen opens on top */
  230.  
  231.         if (mouseblank && !mouseoff && !--mblankcount)    /* blank mouse? */
  232.             TurnMouseOff();
  233.     }
  234.     else if ((ev->ie_Class == IECLASS_RAWKEY) && !(ev->ie_Code & IECODE_UP_PREFIX))
  235.     {
  236.         blankcount = blanktimeout;    /* reset blanking countdown */
  237.         if (blanked)            /* turn off screen-blanking */
  238.              UnBlankScreen();
  239.         if (mouseblank && !mouseoff)    /* blank the mouse */
  240.             TurnMouseOff();
  241.         if (click_volume)        /* perform keyclick */
  242.             Signal(thistask, clicksigflag);
  243.         if (keyactivate)        /* perform key-activate */
  244.             ActivateMouseWindow();
  245.     }
  246.     else if (ev->ie_Class == IECLASS_RAWMOUSE)
  247.     {
  248.         /* restore screen/mouse pointer */
  249.         blankcount = blanktimeout;    /* reset blanking countdowns */
  250.         mblankcount = mblanktimeout;
  251.         if (blanked)            /* turn off screen-blanking */
  252.              UnBlankScreen();
  253.         if (mouseoff)            /* restore mouse pointer */
  254.             TurnMouseOn();
  255.  
  256.         /* window/screen cycling... */
  257.         Forbid();
  258.         if (clicktofront && ev->ie_Code == IECODE_LBUTTON && !(ev->ie_Qualifier & KEY_QUAL))
  259.         {
  260.             if (DoubleClick(lastclick.tv_secs,
  261.                     lastclick.tv_micro,
  262.                     ev->ie_TimeStamp.tv_secs,
  263.                     ev->ie_TimeStamp.tv_micro))
  264.             {
  265.                 struct Window *win = WindowUnderMouse();
  266.  
  267.                 if (win && !(win->Flags & WFLG_BACKDROP))
  268.                     WindowToFront(win);
  269.                 lastclick.tv_secs = 0;
  270.                 lastclick.tv_micro = 0;
  271.             }
  272.             else
  273.             {
  274.                 lastclick.tv_secs = ev->ie_TimeStamp.tv_secs;
  275.                 lastclick.tv_micro = ev->ie_TimeStamp.tv_micro;
  276.             }
  277.         }
  278.         else if ((ev->ie_Qualifier & IEQUALIFIER_LEFTBUTTON) && ev->ie_Code == IECODE_RBUTTON)
  279.         {
  280.             struct Window *win = WindowUnderMouse();
  281.             if (win && !(win->Flags & WFLG_BACKDROP) &&
  282.                (win->NextWindow || win->WScreen->FirstWindow != win))
  283.             {
  284.                 if (clicktoback)
  285.                 {
  286.                     WindowToBack(win);
  287.                 }
  288.             }
  289.             else if (screencycle && IntuitionBase->FirstScreen->MouseY > IntuitionBase->FirstScreen->BarHeight)
  290.             {
  291.                 ScreenToBack(IntuitionBase->FirstScreen);
  292.                 ActivateMouseWindow();
  293.             }
  294.         }
  295.         else if (ev->ie_Code == IECODE_NOBUTTON && !(ev->ie_Qualifier & ALL_BUTTONS))
  296.             apcount = TIMERCOUNT;    /* mouse-move */
  297.         Permit();
  298.     }
  299. }
  300.  
  301. /* close resources allocated for handler */
  302. void
  303. EndHandler()
  304. {
  305.     if (clickobj) DeleteCxObj(clickobj);
  306.     FreeAudio();
  307.     if (clicksigbit != -1) FreeSignal(clicksigbit);
  308.     UnBlankScreen();    /* restores mouse too */
  309. }
  310.  
  311. /* open resources needed for handler */
  312. BOOL
  313. InitHandler()
  314. {
  315.     if (((clicksigbit = AllocSignal(-1)) != -1) &&
  316.         (AllocAudio() == TRUE))
  317.     {
  318.         thistask = FindTask(NULL);      /* initialize liason structure */
  319.         clicksigflag = 1 << clicksigbit;
  320.  
  321.         clickobj = CxCustom(Handler, 0L);
  322.         AttachCxObj(broker, clickobj);
  323.         return TRUE;
  324.     }
  325.     EndHandler();
  326.     return FALSE;
  327. }
  328.