dillon@CORY.BERKELEY.EDU (Matt Dillon) (04/22/88)
WARNING WARNING WARNING WARNING DO NOT USE THIS PROGRAM. I'm posting this just to give those interested an example of how to use the input.device ... the actual functional of the program has bugs. I intend to post this baby officially after I fix the bugs and add some keyboard mappings. -Matt /* * DMOUSE.C INCOMPLETE, LESS THAN ALPHA, BUT THE INPUT.DEVICE HANLDER * WORKS. */ #asm FAR DATA FAR CODE #endasm #include <xmisc.h> #define SBF_C SIGBREAKF_CTRL_C #define SBF_D SIGBREAKF_CTRL_D #define SBF_E SIGBREAKF_CTRL_E #define SBF_F SIGBREAKF_CTRL_F typedef unsigned short uword; typedef struct Custom CUST; typedef struct Preferences PREFS; typedef struct InputEvent IE; typedef struct Port PORT; typedef struct IOStdReq IOR; typedef struct Interrupt INT; typedef struct Screen SCR; typedef struct Window WIN; typedef struct Layer LAYER; typedef struct NewScreen NS; typedef void (*FPTR)(); extern IOR *CreateStdIO(); extern SCR *OpenScreen(); extern void *AllocMem(); extern SCR *OpenWorkBench(); extern LAYER *WhichLayer(); extern struct IntuitionBase *IntuitionBase; #define IBASE IntuitionBase int Enable_Abort; long KSecs = 0x7FFFFFFF; /* Timestamp from most recent keyboard or mouse event */ long MSecs = 0x7FFFFFFF; /* Timestamp from most recent keyboard or mouse event */ short MTrigger; /* Enable rawmouse events -> CHandler() */ short MLayer = 1; /* Enable all rawmouse events */ short KTrigger; /* Enable rawkey events -> CHandler() */ short CDown = 1; /* timer event countdown -> CHandler() 1/sec */ long MTimeout = 5; /* Mouse Timeout */ long KTimeout = 5*60;/* Screen Timeout */ long Task; WIN *LastWin; NS Ns = { 0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET }; IE *handler(); _main() { IOR *ior = CreateStdIO(CreatePort(NULL,0)); INT addhand; PREFS prefs; uword Pm[POINTERSIZE]; uword mtimedout = 0; SCR *sscreen = NULL; register long sigs; register short i; Task = FindTask(NULL); openlibs(INTUITION_LIB|GRAPHICS_LIB|LAYERS_LIB); Enable_Abort = 0; addhand.is_Node.ln_Pri = 51; addhand.is_Code = (FPTR)handler; addhand.is_Data = NULL; if (!OpenDevice("input.device", 0, ior, 0)) { ior->io_Command = IND_ADDHANDLER; ior->io_Data = (APTR)&addhand; DoIO(ior); for (;;) { sigs = Wait(SBF_C|SBF_D|SBF_E|SBF_F); if (sigs & SBF_C) /* kill */ break; if (sigs & SBF_D) { /* mouse to*/ GetPrefs(&prefs, sizeof(PREFS)); if (MTrigger && !mtimedout) { bmov(prefs.PointerMatrix, Pm, sizeof(Pm)); bzero(prefs.PointerMatrix, sizeof(Pm)); mtimedout = 1; } if (!MTrigger && mtimedout) { bmov(Pm, prefs.PointerMatrix, sizeof(Pm)); mtimedout = 0; } SetPrefs(&prefs, sizeof(PREFS)); } if (sigs & SBF_E) { /* scr to */ if (KTrigger && !sscreen) { if (sscreen = OpenScreen(&Ns)) SetRGB4(&sscreen->ViewPort, 0, 0, 0, 0); } if (!KTrigger && sscreen) { CloseScreen(sscreen); sscreen = NULL; } } if ((sigs & SBF_F) && LastWin) { LAYER *layer = WhichLayer(&OpenWorkBench()->LayerInfo, IBASE->MouseX, IBASE->MouseY/2); if (layer && (LastWin = layer->Window)) { ActivateWindow(LastWin); /*WindowToFront(LastWin);*/ } } } ior->io_Command = IND_REMHANDLER; ior->io_Data = (APTR)&addhand; DoIO(ior); CloseDevice(ior); } DeletePort(ior->io_Message.mn_ReplyPort); DeleteStdIO(ior); closelibs(-1); } #asm public _CDown public _KSecs public _MSecs public _MTrigger public _MLayer public _KTrigger public _CHandler IE_CLASS equ 4 IE_SECS equ 14 IE_MICRO equ 18 IECLASS_RAWKEY equ 1 IECLASS_RAWMOUSE equ 2 IECLASS_TIMER equ 6 ; A0 = pointer to event linked list ; A1 = pointer to my data segment ; return new event linked list in D0 ; ; This code calls the handler every ; 10 timer events, on a mouse event ; if MouseTrig set, and on a keyboard ; event if KeyTrig set. _handler: move.l A0,A1 ;A1 = event seq base. .hloop move.b IE_CLASS(A0),D0 cmp.b #IECLASS_RAWKEY,D0 beq .hrawkey cmp.b #IECLASS_RAWMOUSE,D0 beq .hrawmouse cmp.b #IECLASS_TIMER,D0 bne .h3 subq.w #1,_CDown beq .htrig .h3 move.l (A0),A0 move.l A0,D0 bne .hloop move.l A1,D0 rts .hrawkey move.l IE_SECS(A0),_KSecs tst.w _KTrigger beq .h3 bra .htrig .hrawmouse move.l IE_SECS(A0),_MSecs move.l IE_SECS(A0),_KSecs tst.w _MTrigger bne .htrig tst.w _MLayer beq .h3 .htrig ; NOTE!! This code is called at most ; once a second! movem.l D2/D3/A1/A4/A6,-(sp) move.l A0,-(sp) bsr _CHandler move.l (sp)+,A0 movem.l (sp)+,D2/D3/A1/A4/A6 bra .h3 #endasm /* * Called: * -Every x * 1/10 second with a timer event, x usually 10 (1 second) * -On the first mouse or keyboard event after a timeout has occured */ void CHandler(ev) register IE *ev; { geta4(); CDown = 10; switch(ev->ie_Class) { case IECLASS_RAWMOUSE: /* Timein */ if (MTrigger) { MTrigger = 0; Signal(Task, SBF_D); } if (MLayer) { /* Handle Layers */ LAYER *layer = WhichLayer(&OpenWorkBench()->LayerInfo, IBASE->MouseX, IBASE->MouseY/2); if (layer && layer->Window && (APTR)LastWin != layer->Window) { LastWin = (WIN *)layer->Window; Signal(Task, SBF_F); } } /* fallthrough */ case IECLASS_RAWKEY: /* Timein */ if (KTrigger) { KTrigger = 0; Signal(Task, SBF_E); } break; case IECLASS_TIMER: /* Timeout */ if (ev->ie_TimeStamp.tv_secs - MSecs > MTimeout && !MTrigger) { MTrigger = 1; Signal(Task, SBF_D); } if (ev->ie_TimeStamp.tv_secs - KSecs > KTimeout && !KTrigger) { KTrigger = 1; Signal(Task, SBF_E); } break; } }