;/* divert.c - commodity to monitor user inactivity - compiled with SASC 5.10 LC -b0 -cfist -v -j73 divert.c Blink FROM LIB:c.o,divert.o TO divert LIBRARY LIB:LC.lib,LIB:Amiga.lib NODEBUG SC SD quit; */ #include <exec/libraries.h> #include <libraries/commodities.h> #include <dos/dos.h> #include <clib/exec_protos.h> #include <clib/alib_protos.h> #include <clib/alib_stdio_protos.h> #include <clib/commodities_protos.h> #include <devices/inputevent.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } #endif #define TIMER_CLICKS 100 void main(int, char **); void ProcessMsg(void); void CxFunction(CxMsg *, CxObj *); struct Library *CxBase, *IconBase; struct MsgPort *broker_mp; CxObj *broker, *cocustom, *cosignal; struct NewBroker newbroker = { NB_VERSION, "Divert", /* string to identify this broker */ "Divert", "show divert", NBU_UNIQUE | NBU_NOTIFY, /* Don't want any new commodities starting with this name. */ 0, 0, 0, 0 /* If someone tries it, let me know */ }; struct Task *task; ULONG cxsigflag, signal, cxobjsignal; void main(int argc, char **argv) { UBYTE **ttypes; CxMsg *msg; if (CxBase = OpenLibrary("commodities.library", 37L)) { /* open the icon.library for support library functions, ArgArrayInit() and ArgArrayDone() */ if (IconBase = OpenLibrary("icon.library", 36L)) { if (broker_mp = CreateMsgPort()) { newbroker.nb_Port = broker_mp; cxsigflag = 1L << broker_mp->mp_SigBit; /* ArgArrayInit() is a support library function (in the 2.0 version of amiga.lib) */ /* that makes it easy to read arguments from either a CLI or from Workbench's */ /* ToolTypes. Because it uses icon.library, the library has to be open before */ /* before calling this function. ArgArrayDone() cleans up after this function. */ ttypes = ArgArrayInit(argc, argv); /* ArgInt() (in amiga.lib) searches through the array set up by ArgArrayInit() */ /* for a specific ToolType. If it finds one, it returns the numeric value of the */ /* number that followed the ToolType (i.e., CX_PRIORITY=7). If it doesn't find */ /* the ToolType, it returns the default value (the third argument) */ newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0); if (broker = CxBroker(&newbroker, NULL)) { /* CxCustom() takes two arguments, a pointer to the custom function */ /* and an ID. Commodities Exchange will assign that ID to any CxMsg */ /* passed to the custom function. */ if (cocustom = CxCustom(CxFunction, 0L)) { AttachCxObj(broker, cocustom); /* Allocate a signal bit for the signal CxObj */ if ( (signal = (ULONG)AllocSignal(-1L)) != -1) { /* set up the signal mask */ cxobjsignal = 1L << signal; cxsigflag |= cxobjsignal; /* CxSignal takes two arguments, a pointer to the task to signal */ /* (normally the commodity) and the number of the signal bit the */ /* commodity acquired to signal with. */ task = FindTask(NULL); if (cosignal = CxSignal(task, signal)) { AttachCxObj(cocustom, cosignal); ActivateCxObj(broker, 1L); ProcessMsg(); } FreeSignal(signal); } } /* DeleteCxObjAll() is a commodities.library function that not only deletes */ /* the CxObject pointed to in its argument, but it deletes all of the */ /* CxObjects that are attached to it. */ DeleteCxObjAll(broker); /* Empty the port of all CxMsgs */ while(msg = (CxMsg *)GetMsg(broker_mp)) ReplyMsg((struct Message *)msg); } DeletePort(broker_mp); } ArgArrayDone(); /* this amiga.lib function cleans up after ArgArrayInit() */ CloseLibrary(IconBase); } CloseLibrary(CxBase); } } void ProcessMsg(void) { extern struct MsgPort *broker_mp; extern CxObj *broker; extern ULONG cxsigflag; CxMsg *msg; ULONG sigrcvd, msgid; LONG returnvalue = 1L; while (returnvalue) { sigrcvd = Wait(SIGBREAKF_CTRL_C | cxsigflag); while(msg = (CxMsg *)GetMsg(broker_mp)) { msgid = CxMsgID(msg); ReplyMsg((struct Message *)msg); switch(msgid) { case CXCMD_DISABLE: ActivateCxObj(broker, 0L); break; case CXCMD_ENABLE: ActivateCxObj(broker, 1L); break; case CXCMD_KILL: returnvalue = 0L; break; case CXCMD_UNIQUE: returnvalue = 0L; break; } } if (sigrcvd & SIGBREAKF_CTRL_C) returnvalue = 0L; /* Check to see if the signal CxObj signalled us. */ if (sigrcvd & cxobjsignal) printf("Got Signal\n"); } } /* The custom function for the custom CxObject. Any code for a custom CxObj must be short */ /* and sweet because it runs as part of the input.device task. */ void CxFunction(register CxMsg *cxm, CxObj *co) { struct InputEvent *ie; static ULONG time = 0L; /* Get the struct InputEvent associated with this CxMsg. Unlike the InputEvent */ /* extracted from a CxSender's CxMsg, this is a *REAL* input event, be careful with it. */ ie = (struct InputEvent *)CxMsgData(cxm); /* This custom function counts the number of timer events that go by while no other input */ /* events occur. If it counts more than a certain amount of timer events, it clears the */ /* count and diverts the timer event CxMsg to the custom object's personal */ /* list. If an event besides a timer event passes by, the timer event count is reset. */ if (ie->ie_Class == IECLASS_TIMER) { time++; if (time >= TIMER_CLICKS) { time = 0L; DivertCxMsg(cxm, co, co); } } else time = 0L; }