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;
}
}