home *** CD-ROM | disk | FTP | other *** search
- /*
- * handler.c
- *
- * Routines to set up handler.
- * Part of Yak.
- *
- * Martin W. Scott, 9/92.
- */
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <hardware/custom.h>
- #include <hardware/dmabits.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
- #include <libraries/commodities.h>
- #include <graphics/gfxmacros.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <clib/alib_protos.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/layers.h>
- #include <proto/intuition.h>
-
- #include "yak.h"
-
- #define TIMERCOUNT 2 /* how long mouse must stop before autopoint */
-
- CxObj *clickobj;
- ULONG clicksigflag;
- static BYTE clicksigbit;
- static struct Task *thistask;
- static mouseoff = FALSE;
-
- #define INTERRUPT void __interrupt __saveds
-
- /* modified from DMouse */
- struct Window *
- WindowUnderMouse()
- {
- struct Layer *layer;
- struct Screen *scr = IntuitionBase->FirstScreen;
- WORD mousex, mousey;
-
- /* these wont change since this routine called inside Forbid()/Permit() */
- mousey = IntuitionBase->MouseY;
- mousex = IntuitionBase->MouseX;
-
- for (; scr; scr = scr->NextScreen)
- {
- if (!(scr->ViewPort.Modes & LACE))
- mousey >>= 1;
- if (!(scr->ViewPort.Modes & HIRES))
- mousex >>= 1;
-
- if (layer = WhichLayer(&scr->LayerInfo, mousex - scr->ViewPort.DxOffset, mousey - scr->ViewPort.DyOffset))
- break;
- if (mousey >= scr->ViewPort.DyOffset)
- break;
- }
-
- return (layer ? layer->Window : NULL);
- }
-
- /* does active window have an active string gadget? */
- BOOL
- StrGadgetActive(struct Window *w)
- {
- struct Gadget *g = w->FirstGadget;
-
- for (; g; g = g->NextGadget)
- if ((g->GadgetType & STRGADGET) && (g->Flags & GFLG_SELECTED))
- return TRUE;
- return FALSE;
- }
-
- /* activate window under mouse */
- /* only if: no menus, no string gadgets active */
- /* that last one is a bit difficult, since IntuitionBase went REALLY private... */
- /* But hey! Works with SiliconMenus Iris option! (Unlike AutoPoint, DMouse) */
- void
- ActivateMouseWindow()
- {
- struct Window *win;
-
- Forbid();
-
- if ((win = WindowUnderMouse()) &&
- !(win->Flags & WFLG_WINDOWACTIVE) &&
- !(IntuitionBase->ActiveWindow->Flags & (WFLG_INREQUEST|WFLG_MENUSTATE)) &&
- !StrGadgetActive(IntuitionBase->ActiveWindow))
- {
- ActivateWindow(win);
- }
- Permit();
- }
-
- #ifdef USE_SETPOINTER
-
- /*
- * Problem with these routines is that (e.g.) reqtools changes pointer to
- * 'busy' clock when opening a file-requester. When it's finished, it restores
- * blank pointer, but these routines have lost track of that window.
- */
-
- static UWORD __chip BlankPointer[] = {
- 0x0000, 0x0000, /* position control */
- /* zilcho data */
- 0x0000, 0x0000 /* next sprite field */
- };
-
- static struct Window *blankedwin;
- static USHORT *Pointer;
- static BYTE PtrHeight;
- static BYTE PtrWidth;
- static BYTE XOffset, YOffset;
-
- void
- TurnMouseOff()
- {
- mouseoff = TRUE;
-
- Forbid();
-
- blankedwin = IntuitionBase->ActiveWindow;
- Pointer = blankedwin->Pointer;
- PtrHeight = blankedwin->PtrHeight;
- PtrWidth = blankedwin->PtrWidth;
- XOffset = blankedwin->XOffset;
- YOffset = blankedwin->YOffset;
-
- SetPointer(blankedwin, BlankPointer, 0,0,0,0);
-
- Permit();
- }
-
- void
- TurnMouseOn()
- {
- struct Screen *scr = IntuitionBase->FirstScreen;
- struct Window *win;
-
- mouseoff = FALSE;
-
- Forbid();
- /* check that window still exists */
- for (; scr; scr = scr->NextScreen)
- for (win = scr->FirstWindow; win; win = win->NextWindow)
- if (win && win == blankedwin)
- {
- SetPointer(win, Pointer,
- PtrHeight, PtrWidth,
- XOffset, YOffset);
- Permit();
- return;
- }
- Permit();
- return;
- }
-
- #else /* turn of sprites to blank mouse */
-
- extern struct Custom __far custom;
-
- /* the mouse-blank time is unadjustable at the moment. It's less crucial
- * anyway -- you either want it or you don't.
- */
-
- #define TurnMouseOn() {WaitTOF(); ON_SPRITE; mouseoff = FALSE;}
- #define TurnMouseOff() {WaitTOF(); OFF_SPRITE; custom.spr[0].dataa = custom.spr[0].datab=0; mouseoff = TRUE;}
-
- #endif /* USE_SETPOINTER */
-
- static BOOL blanked;
- static struct Screen *blankscr;
- /* blank display, by putting up a black screen */
- void
- BlankScreen()
- {
- if (blankscr)
- ScreenToFront(blankscr);
- else if (blankscr = OpenScreenTags(NULL,SA_Depth, 1,
- SA_Quiet, TRUE,
- TAG_DONE))
- {
- SetRGB4(&blankscr->ViewPort, 0, 0, 0, 0);
- blanked = TRUE;
- }
- TurnMouseOff();
- }
-
- /* unblank display, i.e. close our screen */
- void
- UnBlankScreen()
- {
- if (blankscr)
- CloseScreen(blankscr);
- blankscr = NULL;
- blanked = FALSE;
- TurnMouseOn(); /* ooer! */
- }
-
-
- #define ALL_BUTTONS (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
- #define KEY_QUAL (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
- |IEQUALIFIER_CONTROL \
- |IEQUALIFIER_LALT|IEQUALIFIER_RALT \
- |IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)
-
- /* the input handler itself */
- INTERRUPT Handler(CxMsg *CxMsg, CxObj *CO)
- {
- static struct timeval lastclick;/* last left-button click */
- static UBYTE apcount; /* timer events since last mousemove */
- struct InputEvent *ev;
-
-
- ev = (struct InputEvent *)CxMsgData(CxMsg);
-
- if (ev->ie_Class == IECLASS_TIMER)
- {
- if (autopoint && apcount && !--apcount) /* auto-activate? */
- ActivateMouseWindow();
-
- if (blanktimeout && !--blankcount) /* blank screen? */
- {
- BlankScreen();
- blankcount = blanktimeout; /* reset counter */
- } /* in case sceen opens on top */
-
- if (mouseblank && !mouseoff && !--mblankcount) /* blank mouse? */
- TurnMouseOff();
- }
- else if ((ev->ie_Class == IECLASS_RAWKEY) && !(ev->ie_Code & IECODE_UP_PREFIX))
- {
- blankcount = blanktimeout; /* reset blanking countdown */
- if (blanked) /* turn off screen-blanking */
- UnBlankScreen();
- if (mouseblank && !mouseoff) /* blank the mouse */
- TurnMouseOff();
- if (click_volume) /* perform keyclick */
- Signal(thistask, clicksigflag);
- if (keyactivate) /* perform key-activate */
- ActivateMouseWindow();
- }
- else if (ev->ie_Class == IECLASS_RAWMOUSE)
- {
- /* restore screen/mouse pointer */
- blankcount = blanktimeout; /* reset blanking countdowns */
- mblankcount = mblanktimeout;
- if (blanked) /* turn off screen-blanking */
- UnBlankScreen();
- if (mouseoff) /* restore mouse pointer */
- TurnMouseOn();
-
- /* window/screen cycling... */
- Forbid();
- if (clicktofront && ev->ie_Code == IECODE_LBUTTON && !(ev->ie_Qualifier & KEY_QUAL))
- {
- if (DoubleClick(lastclick.tv_secs,
- lastclick.tv_micro,
- ev->ie_TimeStamp.tv_secs,
- ev->ie_TimeStamp.tv_micro))
- {
- struct Window *win = WindowUnderMouse();
-
- if (win && !(win->Flags & WFLG_BACKDROP))
- WindowToFront(win);
- lastclick.tv_secs = 0;
- lastclick.tv_micro = 0;
- }
- else
- {
- lastclick.tv_secs = ev->ie_TimeStamp.tv_secs;
- lastclick.tv_micro = ev->ie_TimeStamp.tv_micro;
- }
- }
- else if ((ev->ie_Qualifier & IEQUALIFIER_LEFTBUTTON) && ev->ie_Code == IECODE_RBUTTON)
- {
- struct Window *win = WindowUnderMouse();
- if (win && !(win->Flags & WFLG_BACKDROP) &&
- (win->NextWindow || win->WScreen->FirstWindow != win))
- {
- if (clicktoback)
- {
- WindowToBack(win);
- }
- }
- else if (screencycle && IntuitionBase->FirstScreen->MouseY > IntuitionBase->FirstScreen->BarHeight)
- {
- ScreenToBack(IntuitionBase->FirstScreen);
- ActivateMouseWindow();
- }
- }
- else if (ev->ie_Code == IECODE_NOBUTTON && !(ev->ie_Qualifier & ALL_BUTTONS))
- apcount = TIMERCOUNT; /* mouse-move */
- Permit();
- }
- }
-
- /* close resources allocated for handler */
- void
- EndHandler()
- {
- if (clickobj) DeleteCxObj(clickobj);
- FreeAudio();
- if (clicksigbit != -1) FreeSignal(clicksigbit);
- UnBlankScreen(); /* restores mouse too */
- }
-
- /* open resources needed for handler */
- BOOL
- InitHandler()
- {
- if (((clicksigbit = AllocSignal(-1)) != -1) &&
- (AllocAudio() == TRUE))
- {
- thistask = FindTask(NULL); /* initialize liason structure */
- clicksigflag = 1 << clicksigbit;
-
- clickobj = CxCustom(Handler, 0L);
- AttachCxObj(broker, clickobj);
- return TRUE;
- }
- EndHandler();
- return FALSE;
- }
-