;/* onekey.c - Execute me to compile me with Lattice 5.04 LC -b0 -cfistq -v -y -j73 onekey.c Blink FROM LIB:Astartup.obj,handint.o,onekey.o TO onekey LIBRARY LIB:Amiga.lib,LIB:LC.lib SMALLCODE BATCH ND quit NOTE - if you use c.o startup, link with LC.lib first, and include stdio.h */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LATTICE #include #include #include #include #include #include #include #include int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif #define MINARGS 1 UBYTE *vers = "\0$VER: onekey 36.11"; UBYTE *Copyright = "onekey v36.11\nFreely Redistributable, by Carolyn Scheppner - CATS"; UBYTE *usage = "Usage: [run >NIL:] onekey (toggles on/off)\nInput handler for one-key-at-a-time typists\n"; /**********************************************************************/ /* Debug control */ /* */ /* The first define converts any printfs that got in by mistake into */ /* kprintfs. If you are debuging to the console you can change */ /* kprintfs into printfs. */ /* The D1(x) define controls debugging in the standard modules. Use */ /* The D(x) macro for debugging in the app.c module. */ /**********************************************************************/ void kprintf(char *,...); /* #define DEBUG */ #ifdef DEBUG #define bug kprintf #define D1(x) x #define D(x) x #else #define D1(x) ; #define D(x) ; #endif /* NO DEBUG */ BOOL FromWb; #define KCNT 7 #define CODE_LSHIFT 0x60 #define CODE_RSHIFT 0x61 #define CODE_CONTROL 0x63 #define CODE_LALT 0x64 #define CODE_RALT 0x65 #define CODE_LAMIGA 0x66 #define CODE_RAMIGA 0x67 UWORD kcodes[] = { CODE_LSHIFT, CODE_RSHIFT, CODE_LALT, CODE_RALT, CODE_LAMIGA, CODE_RAMIGA, CODE_CONTROL }; UWORD kquals[] = { IEQUALIFIER_LSHIFT, IEQUALIFIER_RSHIFT, IEQUALIFIER_LALT, IEQUALIFIER_RALT, IEQUALIFIER_LCOMMAND, IEQUALIFIER_RCOMMAND, IEQUALIFIER_CONTROL }; UWORD kqual = 0; void bye(UBYTE *s, int e); void cleanup(void); void unInstall(void); extern void HandlerInterface(); /* assembler interface */ struct InputEvent far *myhandler(struct InputEvent *ie1, APTR data); int openedID = NULL; struct MsgPort *inputPort = NULL; struct IOStdReq *inputReq = NULL; #define MAXIE 16 int ii = 0; struct InputEvent ups[MAXIE] = {NULL}; UBYTE *progname = "OneKey"; UBYTE *oldname = NULL; struct Interrupt handlerStuff = {0}; /* C handler routine */ struct InputEvent *myhandler(struct InputEvent *ie1, APTR data) { struct InputEvent *ie, *myie, *lastie; extern struct Library *SysBase; UWORD kcode; int k; BOOL IsDown, IsUp, SendEm; SendEm = FALSE; for (ie=ie1; ie; lastie=ie, ie=ie->ie_NextEvent) { if (ie->ie_Class==IECLASS_RAWKEY) { kcode = ie->ie_Code & (~IECODE_UP_PREFIX); for(k=0,IsUp=FALSE,IsDown=FALSE; kie_Code & IECODE_UP_PREFIX) IsUp = TRUE; else IsDown = TRUE; break; } } D(bug("got code $%lx, IsUp=%ld, IsDown=%ld\n",kcode,IsUp,IsDown)); if(IsDown) /* is a gathered key - gather the quals */ { D(bug("got down k=%ld\n",k)); kqual |= kquals[k]; } else if(IsUp) /* release of a gathered key - we'll eat it */ { D(bug("got up k=%ld\n",k)); myie = &ups[ii]; /* use my next empty event */ *myie = *ie; /* clone this key up event */ if(ii < (MAXIE-1)) ii++; /* set up for next */ ie->ie_Class = IECLASS_NULL; /* null out the real event */ } else if(kqual) /* got a non-qualifier key and we have gathered */ { D(bug("got key code=%lx, gathered=$%lx\n",kcode,kqual)); ie->ie_Qualifier |= kqual; /* apply the qualifiers */ /* if key release, set up fake saved keyups now too, clear gather */ if(ie->ie_Code & IECODE_UP_PREFIX) { /* update time stamps and link our list */ for(k=0; kie_TimeStamp.tv_secs; ups[k].ie_TimeStamp.tv_micro = ie->ie_TimeStamp.tv_micro+k; if(k<(ii-1)) ups[k].ie_NextEvent = &ups[k+1]; else ups[k].ie_NextEvent = NULL; } SendEm = TRUE; kqual = 0; } } } } if(SendEm) { lastie->ie_NextEvent = &ups[0]; ii = 0; } return(ie1); } #define MYNAME "cas_cbm_onekey" void main(int argc, char **argv) { struct Task *task; int error; FromWb = argc ? FALSE : TRUE; if(((argc)&&(argctc_Node.ln_Name; task->tc_Node.ln_Name = MYNAME; /* Get ready to add our handler */ if(!(inputPort=(struct MsgPort *)CreatePort(0,0))) bye("Can't create port\n",RETURN_FAIL); if(!(inputReq=(struct IOStdReq *)CreateStdIO(inputPort))) bye("Can't create IORequest\n",RETURN_FAIL); handlerStuff.is_Data = NULL; /* no passed data pointer */ handlerStuff.is_Code = HandlerInterface; /* assem entry */ handlerStuff.is_Node.ln_Pri = 51; /* above Intuition */ if(error = OpenDevice("input.device",0,inputReq,0)) bye("Can't open input device\n",RETURN_FAIL); openedID = 1; inputReq->io_Command = IND_ADDHANDLER; inputReq->io_Data = (APTR)&handlerStuff; DoIO(inputReq); if(argc) printf("%s installed\n",progname); Wait(SIGBREAKF_CTRL_C); bye("",0L); } void bye(UBYTE *s, int e) { if(!FromWb) printf(s); unInstall(); exit(e); } void unInstall() { if (openedID) { /* remove the handler from the chain */ inputReq->io_Command = IND_REMHANDLER; inputReq->io_Data = (APTR)&handlerStuff; DoIO(inputReq); /* close the input device */ CloseDevice(inputReq); } /* delete the IO request, port, FreeSignal */ if(inputReq) DeleteStdIO(inputReq); if(inputPort) DeletePort(inputPort); if(oldname) FindTask(NULL)->tc_Node.ln_Name = oldname; if((openedID)&&(!FromWb)) printf("%s removed\n",progname); }