[comp.sys.amiga] Example code that handles the input.device

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