home *** CD-ROM | disk | FTP | other *** search
- /*
- * DMOUSE-HANDLER.C compile 32 bit integers (+L)
- * AZTEC COMPILATION
- * 18 May 1988
- */
- #include "dmouse.h"
- #define IBASE IntuitionBase
- DMS *Dms;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- long *LayersBase;
- NS Ns = { 0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
- IE *handler();
- _main()
- {
- register DMS *dms;
- IOR *ior;
- INT addhand;
- {
- register PROC *proc = (PROC *)FindTask(NULL);
- proc->pr_ConsoleTask = NULL;
- }
- dms = Dms = FindPort(PORTNAME);
- if (!dms)
- _exit(0);
- dms->Port.mp_Flags = PA_SIGNAL;
- dms->Port.mp_SigBit = AllocSignal(-1);
- dms->Port.mp_SigTask = FindTask(NULL);
- dms->HandTask = dms->Port.mp_SigTask;
- ior = CreateStdIO(&dms->Port);
- IntuitionBase = OpenLibrary("intuition.library", 0);
- GfxBase = OpenLibrary("graphics.library", 0);
- LayersBase = OpenLibrary("layers.library", 0);
- if (!IntuitionBase || !GfxBase || !LayersBase)
- goto startupfail;
- addhand.is_Node.ln_Pri = 51;
- addhand.is_Code = (FPTR)handler;
- addhand.is_Data = NULL;
- if (OpenDevice("input.device", 0, ior, 0)) {
- goto startupfail;
- } else {
- SCR *scr = NULL;
- uword *SprSavePtr = NULL;
- Signal(dms->ShakeTask, 1 << dms->ShakeSig);
- ior->io_Command = IND_ADDHANDLER;
- ior->io_Data = (APTR)&addhand;
- DoIO(ior);
- for (;;) {
- register long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit));
- if (sigs & (1 << dms->Port.mp_SigBit)) {
- register MSG *msg;
- while (msg = GetMsg(&dms->Port)) {
- switch((long)msg->mn_Node.ln_Name) {
- case REQ_SCREENON:
- if (scr)
- CloseScreen(scr);
- scr = NULL;
- break;
- case REQ_SCREENOFF:
- if (scr) {
- ScreenToFront(scr);
- } else {
- if (scr = OpenScreen(&Ns))
- SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
- }
- break;
- case REQ_MOUSEON:
- if (SprSavePtr) {
- register COPINIT *ci = GfxBase->copinit;
- ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
- ci->sprstrtup[3] = (uword)(long)SprSavePtr;
- SprSavePtr = NULL;
- }
- break;
- case REQ_MOUSEOFF:
- {
- register COPINIT *ci = GfxBase->copinit;
- if (!SprSavePtr)
- SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
- ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
- ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
- }
- break;
- case REQ_DOCMD:
- {
- long fh = Open("nil:", 1006);
- Execute(dms->Cmd, NULL, fh);
- if (fh)
- Close(fh);
- }
- break;
- }
- FreeMem(msg, msg->mn_Length);
- }
- }
- if (sigs & SBF_C)
- break;
- }
- Forbid();
- ior->io_Command = IND_REMHANDLER;
- ior->io_Data = (APTR)&addhand;
- DoIO(ior);
- Permit();
- CloseDevice(ior);
- {
- register MSG *msg;
- while (msg = GetMsg(&dms->Port))
- FreeMem(msg, msg->mn_Length);
- }
- if (scr)
- CloseScreen(scr);
- if (SprSavePtr) {
- register COPINIT *ci = GfxBase->copinit;
- ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
- ci->sprstrtup[3] = (uword)(long)SprSavePtr;
- SprSavePtr = NULL;
- }
- }
- goto closedown;
- startupfail:
- dms->StartupError = 1;
- Signal(dms->ShakeTask, 1 << dms->ShakeSig);
- Wait(SBF_C);
- closedown:
- DeleteStdIO(ior);
- fail:
- if (IntuitionBase)
- CloseLibrary(IntuitionBase);
- if (GfxBase)
- CloseLibrary(GfxBase);
- if (LayersBase)
- CloseLibrary(LayersBase);
- Forbid();
- Signal(dms->ShakeTask, 1 << dms->ShakeSig);
- }
- #asm
- ; A0 = pointer to event linked list
- ; A1 = pointer to my data segment
- ; return new event linked list in D0
- public _CHandler
- _handler:
- movem.l D2/D3/A0/A1/A4/A6,-(sp)
- jsr _CHandler
- movem.l (sp)+,D2/D3/A0/A1/A4/A6
- rts
- #endasm
- /*
- * (1) Accellerate mouse movements.
- * (2) Auto-Select window
- */
- IE *
- CHandler(scr0, scr1, Ev)
- IE *Ev;
- {
- register IE *ev;
- register DMS *dms;
- static char STimedout;
- static char MTimedout;
- static long STime, MTime;
- geta4();
- dms = Dms;
- for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
- switch(ev->ie_Class) {
- case IECLASS_RAWMOUSE:
- /*
- * Mouse events restore both the screen and mouse pointer.
- */
- STime = ev->ie_TimeStamp.tv_secs + dms->STo;
- MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
- if (STimedout)
- sendrequest(REQ_SCREENON);
- if (MTimedout)
- sendrequest(REQ_MOUSEON);
- STimedout = MTimedout = 0;
- /*
- * Mouse Acceleration
- */
- {
- register short n;
- register short s;
- if (dms->Acc != 1) {
- n = ev->ie_X;
- s = 1;
- if (n < 0) {
- n = -n;
- s = -1;
- }
- if (n > dms->AThresh)
- ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
- n = ev->ie_Y;
- s = 1;
- if (n < 0) {
- n = -n;
- s = -1;
- }
- if (n > dms->AThresh)
- ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
- }
- }
- /*
- * Auto Activate and LMB (win/scrn front/bak)
- */
- if (dms->AAEnable | dms->LMBEnable) {
- register LAYER *layer;
- Forbid();
- layer = WhichMouseLayer();
- if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual)) {
- register WIN *win;
- if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win))
- WindowToBack(layer->Window);
- else if (IBASE->FirstScreen)
- ScreenToBack(IBASE->FirstScreen);
- ev->ie_Class = IECLASS_NULL; /* remove event */
- }
- if (layer && layer->Window) {
- if (dms->LMBEnable && ev->ie_Code == IECODE_LBUTTON && layer->ClipRect && layer->ClipRect->Next) {
- /*
- * Note: Case where it is the 'first' click in a series, where dms->CTime is
- * garbage, works properly no matter what DoubleClick returns.
- */
- if ((APTR)dms->CWin == layer->Window && DoubleClick(dms->CTime.tv_secs, dms->CTime.tv_micro, ev->ie_TimeStamp.tv_secs, ev->ie_TimeStamp.tv_micro))
- --dms->CLeft;
- else
- dms->CLeft = dms->Clicks - 1;
- dms->CTime = ev->ie_TimeStamp;
- dms->CWin = (WIN *)layer->Window;
- if (dms->CLeft == 0) {
- dms->CLeft = dms->Clicks;
- WindowToFront(layer->Window);
- }
- }
- if (dms->AAEnable && ev->ie_Code == IECODE_NOBUTTON && !(ev->ie_Qualifier & 0x7000) && layer->Window != IBASE->ActiveWindow)
- ActivateWindow(layer->Window);
- }
- Permit();
- }
- break;
- case IECLASS_RAWKEY:
- /*
- * Keyboard events will kill the screen timeout but not
- * the mouse timeout.
- */
- {
- register LAYER *layer;
- Forbid();
- layer = WhichMouseLayer();
- if (layer && layer->Window) {
- if (dms->AAEnable && layer->Window != IBASE->ActiveWindow)
- ActivateWindow(layer->Window);
- }
- Permit();
- }
- STime = ev->ie_TimeStamp.tv_secs + dms->STo;
- if (STimedout)
- sendrequest(REQ_SCREENON);
- STimedout = 0;
- if (ev->ie_Code == dms->Code && ev->ie_Qualifier == dms->Qual) {
- sendrequest(REQ_DOCMD);
- ev->ie_Class = IECLASS_NULL; /* remove event */
- }
- break;
- case IECLASS_TIMER:
- /*
- * On a timer event, if timeout has occured execute the operation
- * and reset the timeout. Note that this will cause continuous
- * timeouts every STo and MTo seconds... required because at any
- * time Intuition might turn the mouse back on or open a screen or
- * something and I want the blanker's to work in the long run.
- */
- {
- register long old;
- if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
- STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
- STimedout = 1;
- if (old > -10)
- sendrequest(REQ_SCREENOFF);
- }
- if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
- MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
- MTimedout = 1;
- if (old > -10)
- sendrequest(REQ_MOUSEOFF);
- }
- }
- break;
- }
- }
- return(Ev);
- }
- sendrequest(req)
- long req;
- {
- register MSG *msg = AllocMem(sizeof(MSG), MEMF_PUBLIC);
- if (msg) {
- msg->mn_Node.ln_Name = (char *)req;
- msg->mn_ReplyPort = NULL;
- msg->mn_Length = sizeof(MSG);
- PutMsg(&Dms->Port, msg);
- }
- }
- LAYER *
- WhichMouseLayer()
- {
- register struct IntuitionBase *ib = IBASE;
- register LAYER *layer = NULL;
- register SCR *scr = ib->FirstScreen;
- for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
- register short mousey = ib->MouseY;
- if (!(scr->ViewPort.Modes & LACE))
- mousey >>= 1;
- if (layer = WhichLayer(&scr->LayerInfo, ib->MouseX, mousey - scr->ViewPort.DyOffset))
- break;
- if (mousey >= scr->ViewPort.DyOffset)
- break;
- }
- return(layer);
- }
-