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/console.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
- #include <libraries/commodities.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/displayinfo.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/layers.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <proto/commodities.h>
- #include <string.h>
- #include <stdio.h>
-
- #include "code.h"
- #include "yak.h"
- #include "beep.h"
-
- void TurnMouseOn (void);
- static void TurnMouseOff (void);
- static __regargs void IntuiOp (void (*routine) (APTR), APTR parameter);
- static __regargs void PopToFront (struct Window *win);
- static struct Window *WindowUnderMouse (void);
- static __regargs BOOL StrGadgetActive (struct Window *w);
-
- extern __far struct Custom custom;
-
- #define REBLANKCOUNT 10 /* how long to wait to reblank mouse */
-
- void (*intui_routine) (APTR); /* for intui_op's */
- APTR intui_parameter;
- CxObj *clickobj;
- ULONG clicksigflag, intuiopsigflag;
- static BYTE clicksigbit, intuiopsigbit = -1;
- static struct Task *thistask;
- static BOOL misspop;
-
-
- /* for screen click-to-back */
- STACKARGS void
- MyScreenToBack (struct Screen *scr)
- {
- RememberActiveWindow();
- ScreenToBack (scr);
- ActivateMouseWindow (SCREEN);
- }
-
-
- /* Stub for Intuition routines - passes request on to main task.
- * DO NOT CALL WHILE FORBID()ING!
-
- * Thanks to Eddy Carroll for this.
- */
-
- #define WTB(win) IntuiOp(WindowToBack, win)
- #define WTF(win) IntuiOp(WindowToFront, win)
- #define WACT(win) IntuiOp((void (*)(APTR))ActivateWindow, win)
- #define STB(scr) IntuiOp(MyScreenToBack, scr)
- #define STF(scr) IntuiOp(ScreenToFront, scr)
-
- static __regargs void
- IntuiOp (void (*routine) (APTR), APTR parameter)
- {
- BYTE oldpri = SetTaskPri (thistask, 21);
-
- intui_routine = routine;
- intui_parameter = parameter;
- Signal (thistask, intuiopsigflag);
- SetTaskPri (thistask, oldpri);
- }
-
- /* pattern-matching on screen/window titles */
- #define IsXXXScreen(scr, pat) (scr && (!scr->DefaultTitle || MatchPattern(pat, scr->DefaultTitle)))
- #define IsClickScreen(scr) IsXXXScreen(scr, clickscrpat)
- #define IsAutoScreen(scr) IsXXXScreen(scr, autoscrpat)
- #define IsXXXWindow(win, pat) (!win->Title || MatchPattern(pat, win->Title))
- #define IsPopWindow(win) IsXXXWindow(win,popwinpat)
- #define IsClickWindow(win) IsXXXWindow(win,clickwinpat)
-
-
- /* when is a window safe to bring to front and not already at front? */
- #define OkayToPop(win) (!win->ReqCount && !(win->Flags & (WFLG_MENUSTATE|WFLG_BACKDROP)) \
- && win->WLayer->ClipRect && win->WLayer->ClipRect->Next)
-
-
- /* WindowToFront only if no requester, not backdrop, not already front... */
- static __regargs void
- PopToFront (struct Window *win)
- {
- /* want to avoid popping immediately after mousebutton/keyboard */
- if (misspop)
- misspop = FALSE;
- else if (OkayToPop (win))
- {
- /* Does it pass pattern? */
- if (IsPopWindow (win))
- WTF (win);
- }
- }
-
- /* modified from DMouse */
- /* expects multitasking to be Forbid()en */
-
- static struct Screen *mousescr; /* the screen under the mouse */
-
-
- struct Screen
- *ScreenUnderMouse( void )
- {
- struct Screen *scr;
- ULONG lock;
-
- lock = LockIBase(0);
-
- for (scr = FS;
- scr && scr->TopEdge > 0 && scr->MouseY < 0;
- scr = scr->NextScreen);
-
- UnlockIBase(lock);
-
- return(scr);
- }
-
-
- static struct Window
- *WindowUnderMouse( void )
- {
- struct Layer *layer = NULL;
- ULONG lock;
-
- lock = LockIBase(0);
-
- for (mousescr = FS;
- mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0;
- mousescr = mousescr->NextScreen);
-
- UnlockIBase(lock);
-
- if (mousescr)
- layer = WhichLayer(&mousescr->LayerInfo, mousescr->MouseX, mousescr->MouseY);
-
- return (layer ? (struct Window *) layer->Window : NULL);
- }
-
-
- /* does active window have an active string gadget? */
- static __regargs 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 */
- /* context sensitive; why tells routine how to behave */
- /* can be AUTO, KEY, SCREEN, RMBACT */
- __regargs void
- ActivateMouseWindow (BYTE why)
- {
- struct Window *win = NULL, *IB_ActiveWindow;
- ULONG lock;
-
- if ((why != SCREEN) || scractivate)
- {
- if (why == SCREEN)
- win = LastActiveWindow(ScreenUnderMouse());
-
- if (!win)
- win = WindowUnderMouse ();
-
-
- if (win) /* window exists to activate */
- {
- /* either window is not active or auto-activating - need to pop? */
-
- if (win->Flags & WFLG_WINDOWACTIVE) /* already active - needs popped? */
- {
- if (why == AUTO && autopop && IsAutoScreen (win->WScreen))
- {
- PopToFront (win);
- }
- }
- else if (why != AUTO || IsAutoScreen (win->WScreen))
- {
- /* window is not active, should we try to activate it? */
-
- lock = LockIBase(0);
- IB_ActiveWindow = AW; /* AW is IntuitionBase->ActiveWindow */
- UnlockIBase(lock);
-
- if (!IB_ActiveWindow ||
- !(IB_ActiveWindow->Flags & WFLG_MENUSTATE) && /* not showing menus */
- !(why == KEY && StrGadgetActive (IB_ActiveWindow))) /* no str gad active */
- {
-
- /* do autopop? */
- if (why == AUTO && autopop)
- PopToFront (win);
-
- if (why == KEY)
- ActivateWindow (win); /* need this to avoid losing keys */
- else
- WACT (win); /* ...activate window */
- }
- }
- }
- else
- {
- lock = LockIBase(0);
- IB_ActiveWindow = AW; /* AW is IntuitionBase->ActiveWindow */
- UnlockIBase(lock);
-
- if (scractivate && mousescr && mousescr->FirstWindow &&
- ((why == SCREEN) ||
- (why == RMBACT && IB_ActiveWindow && IB_ActiveWindow->WScreen != mousescr)))
- {
- WACT (mousescr->FirstWindow); /* ...activate window */
- }
- }
- }
- }
-
- static __chip UWORD posctldata[4];
- static struct SimpleSprite simplesprite =
- {posctldata, 0, 0, 0, 0};
- static BOOL mouseoff; /* is mouse off? (MB_SPRITES only) */
-
- void
- TurnMouseOn () /* restore mouse-pointer */
- {
- if (mouseblank == MB_SPRITES) /* really dirty blanking */
- { /* but guaranteed to work... */
- if (mouseoff)
- {
- Forbid ();
- WaitTOF ();
- ON_SPRITE;
- Permit ();
- }
- }
- /* else using FreeSprite solution - unblanks when needed */
- mouseoff = FALSE;
- }
-
- static void
- TurnMouseOff () /* blank mouse-pointer */
- {
- if (!mouseoff) /* no point in turning it off twice... */
- {
- Forbid ();
-
- if (mouseblank == MB_SPRITES)
- {
- WaitTOF ();
- OFF_SPRITE;
- custom.spr[0].dataa = custom.spr[0].datab = 0; }
- else
- {
- FreeSprite (0);
- GetSprite (&simplesprite, 0);
- }
-
- Permit ();
-
- mouseoff = TRUE;
- }
- }
-
- static BOOL blanked;
- static struct Screen *blankscr;
-
- /* blank display, by putting up a black screen */
- /* this screen's displaymode is cloned from front screen */
- void
- BlankScreen ()
- {
- ULONG modeid = INVALID_ID;
-
- if (blankscr)
- ScreenToFront (blankscr);
- else
- {
- Forbid ();
- if (FS)
- modeid = GetVPModeID (&(FS->ViewPort));
- Permit ();
- if (modeid == INVALID_ID)
- modeid = LORES_KEY;
-
- if (blankscr = OpenScreenTags (NULL, SA_Depth, 1,
- SA_Quiet, TRUE,
- SA_Behind, TRUE,
- SA_DisplayID, modeid,
- TAG_DONE))
- {
- SetRGB4 (&blankscr->ViewPort, 0, 0, 0, 0);
- ScreenToFront (blankscr);
- blanked = TRUE;
- }
- }
- OFF_SPRITE;
- custom.spr[0].dataa = custom.spr[0].datab = 0;
- }
-
- /* unblank display, i.e. close our screen */
- void
- UnBlankScreen ()
- {
- if (blankscr)
- CloseScreen (blankscr);
- blankscr = NULL;
- blanked = FALSE;
- ON_SPRITE;
- }
-
- #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)
- #define ALL_QUALS (ALL_BUTTONS|KEY_QUAL)
-
- /* the input handler itself */
- SAVEDS void
- Handler (CxMsg * CxMsg, CxObj * CO)
- {
- static struct timeval lastclick; /* last left-button click */
- static WORD apcount; /* timer events since last mousemove */
- struct InputEvent *ev;
- struct Window *win;
-
- ev = (struct InputEvent *) CxMsgData (CxMsg);
-
- if (ev->ie_Class == IECLASS_TIMER)
- {
- /*** AUTO-ACTIVATE/POP, SCREENBLANK, MOUSEBLANK ***/
- if (!(ev->ie_Qualifier & ALL_QUALS) && autopoint && !apcount--)
- {
- ActivateMouseWindow (AUTO);
- }
-
- if (blanktimeout && !--blankcount) /* blank screen? */
- {
- BlankScreen ();
- blankcount = blanktimeout; /* reset counter */
- } /* in case sceen opens on top */
-
- if (mouseblank && !--mblankcount) /* blank mouse? */
- {
- mouseoff = FALSE; /* force reblank */
- TurnMouseOff ();
- /* in case someone else turns it on, reset counter */
- mblankcount = REBLANKCOUNT;
- }
- }
- else
- if ((ev->ie_Class == IECLASS_RAWKEY) && !(ev->ie_Code & IECODE_UP_PREFIX))
- {
- /*** MOUSEBLANK, KEYACTIVATE, KEYCLICK ***/
-
- blankcount = blanktimeout; /* reset blanking countdown */
- if (blanked) /* turn off screen-blanking */
- UnBlankScreen ();
-
- if (mouseblank)
- if (ev->ie_Qualifier & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND))
- {
- /* this allows use of keyboard to move mouse and to access menus */
- mblankcount = mblanktimeout;
- TurnMouseOn ();
- }
- else
- {
- if (blankmouseonkey)
- {
- TurnMouseOff (); /* blank the mouse */
- }
- }
- if (click_volume)
- Signal (thistask, clicksigflag);
-
- if (keyactivate) /* perform key-activate */
- ActivateMouseWindow (KEY);
- }
- else if (ev->ie_Class == IECLASS_RAWMOUSE)
- {
- /*** CLICKTOFRONT/BACK, AUTOACTIVATE ***/
-
- /* restore screen/mouse pointer */
- blankcount = blanktimeout; /* reset blanking countdowns */
- mblankcount = mblanktimeout;
- if (blanked) /* turn off screen-blanking */
- UnBlankScreen ();
- if (mouseoff)
- TurnMouseOn (); /* not needed for MB_COPPER */
-
- /* window/screen cycling... */
- /* maybe should check for depth gadgets? nah... */
- if (!(ev->ie_Qualifier & KEY_QUAL))
- {
- if (!(ev->ie_Qualifier & ALL_BUTTONS))
- {
- apcount = autopoint_delay; /* reset auto-activate count */
- }
- else
- /* a button - check out clicktofront etc. */
- {
- misspop = TRUE;
- apcount = -1; /* button - wait for move */
-
- if (clicktofront && ev->ie_Code == IECODE_LBUTTON)
- {
- if (DoubleClick (lastclick.tv_secs,
- lastclick.tv_micro,
- ev->ie_TimeStamp.tv_secs,
- ev->ie_TimeStamp.tv_micro))
- {
- win = WindowUnderMouse ();
-
- if (win)
- {
- mousescr = win->WScreen;
-
- if (IsClickScreen ( mousescr ))
- {
- if (!(win->Flags & WFLG_BACKDROP)
- && IsClickWindow (win) && OkayToPop (win))
- {
- WTF (win);
- }
- else
- if (screencycle)
- {
- RememberActiveWindow();
- STF (mousescr);
- }
- }
- }
- else
- {
- mousescr = ScreenUnderMouse();
- if (IsClickScreen ( mousescr ) && screencycle)
- {
- RememberActiveWindow();
- STF (mousescr);
- }
- }
- 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_Code == IECODE_RBUTTON &&
- (ev->ie_Qualifier & IEQUALIFIER_LEFTBUTTON) &&
- clicktoback)
- {
- win = WindowUnderMouse ();
-
- if (win)
- {
- mousescr = win->WScreen;
- if (IsClickScreen ( mousescr ))
- {
- if (!(win->Flags & WFLG_BACKDROP)
- && (win->NextWindow || win->WScreen->FirstWindow != win))
- {
- WTB(win);
- }
- else
- if (screencycle)
- {
- STB (mousescr);
- }
- }
- }
- else
- {
- mousescr = ScreenUnderMouse();
- if (IsClickScreen ( mousescr ) && screencycle)
- {
- ev->ie_Class = IECLASS_NULL;
- STB (mousescr);
- }
- }
- }
- else
- {
- if ((rmbactivate && (ev->ie_Code == IECODE_RBUTTON)) ||
- (mmbactivate && (ev->ie_Code == IECODE_MBUTTON)))
- {
- ActivateMouseWindow (RMBACT);
- }
- }
- }
- }
- }
- }
- else
- {
- if (ev->ie_Class == IECLASS_DISKINSERTED)
- {
- blankcount = blanktimeout; /* reset blanking countdown */
- if (blanked) /* turn off screen-blanking */
- UnBlankScreen ();
- }
- }
- }
-
- /* close resources allocated for handler */
- void
- EndHandler ()
- {
- if (clickobj)
- DeleteCxObj (clickobj);
- FreeAudio ();
- if (intuiopsigbit != -1)
- FreeSignal (intuiopsigbit);
- if (clicksigbit != -1)
- FreeSignal (clicksigbit);
- UnBlankScreen ();
- }
-
- /* open resources needed for handler */
- BOOL
- InitHandler ()
- {
- if (((clicksigbit = AllocSignal (-1)) != -1) &&
- ((intuiopsigbit = AllocSignal (-1)) != -1) &&
- AllocAudio ())
- {
- thistask = FindTask (NULL); /* initialize liason structure */
- clicksigflag = 1 << clicksigbit;
- intuiopsigflag = 1 << intuiopsigbit;
-
- clickobj = CxCustom (Handler, 0L);
- AttachCxObj (broker, clickobj);
- return TRUE;
- }
- EndHandler ();
- return FALSE;
- }
-
-