[comp.sys.amiga.tech] example program using the input.device / event handler

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (05/07/89)

	Somebody asked me to make this up and I figure other people might
be interested in a working example that modifies mouse events (reverses
their direction, in fact! :-))

	Compiles under Aztec C, is well commented, 16 or 32 bit ints, no
precompiled symbol table needed, etc...

					-Matt


/*
 *  MREVS.C
 *
 *  Example input event interceptor program
 *
 *  Takes mouse events and reverses their direction (x -> -x  y -> -y)
 *
 *  Matthew Dillon, public domain.
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/interrupts.h>
#include <devices/inputevent.h>
#include <devices/input.h>
#include <libraries/dos.h>

typedef struct InputEvent   IE;
typedef struct MsgPort	    PORT;
typedef struct IOStdReq     IOR;
typedef struct Interrupt    INT;

typedef void (*FPTR)();

IE  *handler();

extern int Enable_Abort;
extern PORT *CreatePort();
extern IOR  *CreateExtIO();
extern long  Wait();

main()
{
    IOR  *ior;
    PORT *port;
    INT  handnode;

    Enable_Abort = 0;

    port = CreatePort(NULL, 0);
    ior = CreateExtIO(port, (long)sizeof(IOR));

    handnode.is_Node.ln_Pri = 51;
    handnode.is_Code = (FPTR)handler;
    handnode.is_Data = NULL;

    if (OpenDevice("input.device", 0L, ior, 0L)) {
	puts("unable to open input.device!");
	goto failure;
    }
    puts("adding");
    ior->io_Command = IND_ADDHANDLER;
    ior->io_Data = (APTR)&handnode;
    ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
    DoIO(ior);

    for (;;) {
	long mask = Wait((long)SIGBREAKF_CTRL_C);
	if (mask & SIGBREAKF_CTRL_C)
	    break;
    }
    puts("removing");
    ior->io_Command = IND_REMHANDLER;
    ior->io_Data = (APTR)&handnode;
    ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
    DoIO(ior);
    CloseDevice(ior);
failure:
    DeletePort(port);
    DeleteExtIO(ior);
}


#asm
	    ;	A0 = pointer to event linked list
	    ;	A1 = pointer to data segment (not used)
	    ;
	    ;	return D0 = new event linked list
	    ;
	    ;	I don't know if A0/A1 need to be preserved.  I don't think so
	    ;	but why take the chance?
	    ;
	    ;	D2/D3/A4/A6 are preserved here because Aztec C does not
	    ;	preserve them.
	    ;
	    ;	NOTE:	position of A0 on the stack is assumed by CHandler()

	    public  _CHandler

_handler:
	    movem.l D2/D3/A0/A1/A4/A6,-(sp)
	    bsr     _CHandler
	    movem.l (sp)+,D2/D3/A0/A1/A4/A6
	    rts

#endasm

IE *
CHandler(scr0, scr1, Ev)
long scr0, scr1;
IE *Ev;
{
    register IE *ev;

    geta4();            /*  small data model support for Aztec C    */
			/*  the base register must be initialized   */
    for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
	if (ev->ie_Class == IECLASS_RAWMOUSE) {
	    ev->ie_X = -ev->ie_X;
	    ev->ie_Y = -ev->ie_Y;
	}
    }
    return(Ev);
}

kodiak@amiga.UUCP (Robert R. Burns) (05/12/89)

In article ... (Matt Dillon) writes:

)...

code for the input event handler in assembler...

)#asm
)	    ;	A0 = pointer to event linked list
)	    ;	A1 = pointer to data segment (not used)
)	    ;
)	    ;	return D0 = new event linked list
)	    ;
)	    ;	I don't know if A0/A1 need to be preserved.  I don't think so
)	    ;	but why take the chance?

They don't need to be preserved.  Guaranteed.
-- 
Bob Burns, {cbmvax,oliveb,well}!amiga!kodiak	   _
	| /_  _|. _ |	   Commodore __		  |_) _ |_  _ )'
	|<(_)(_)|(_\|<	    /\ |  ||| _` /\	  |_)(_\| )(_\ |
	| \ Software	___/..\|\/|||__|/..\___		   Faith