jmunkki@santra.UUCP (Juri Munkki) (04/22/88)
/*
SampleInit.c
April 22, 1988
Written by Juri Munkki
This source code is in the public domain.
The author makes no guarantees.
Instructions
I wrote this INIT as a sample to one of my clients.
They wished to monitor what the user does and generate
statistics on frequently used actions.
This INIT does nothing useful. It modifies GetNextEvent
so that instead of returning autoKey events with the
spacebar, the # character is returned. It should be
quite a surprise to people who are used to using spaces
instead of tabs. :-) The INIT has no effect on DAs.
You should have Lightspeed C to use this INIT. The
structure of an INIT depends highly on the development
system being used. Lightspeed C places global data
storage after the program code. This means that you
can't have more than 32K of code AND static variables.
The INIT resource itself should have the "System Heap"
flag set or it will bomb sooner or later. (usually soon)
Please remember to put a 'sysz' resource into your
INIT, if you're going to need a lot of space. Also
remember that any dynamic storage that should live
through launches should be in the system heap.
I hope this helps those who are desperately trying to
patch the system.
Juri Munkki
jmunkki@santra.hut.fi
jmunkki@fingate.bitnet
*/
#include <MacTypes.h>
#include <OSUtil.h>
#include <EventMgr.h>
#define NextEventNum 0x970
long OldNextEvent;
long ticker;
EventRecord *theEvent;
void DoEvent(doIt)
int doIt;
{
if(doIt)
if(theEvent->what==autoKey)
if((theEvent->message & 0xFF) == ' ')
theEvent->message+='#'-' ';
}
void NewGetEvent()
{
asm {
move.l (sp)+,A0 /* Return address */
move.l (sp)+,A1 /* Pointer to an EventRecord */
move.w (sp)+,D0 /* EventMask */
move.l A0,-(sp) /* Push return address for RTS */
move.l A4,-(sp) /* Save A4. */
move.l @1,A4 /* Set A4 (static base reg) */
move.l A1,theEvent /* Save the ER pointer */
clr.w -(sp) /* Space for returned value */
move.w D0,-(sp) /* Push EventMask */
move.l A1,-(sp) /* Push ER pointer */
move.l OldNextEvent,A0 /* Get ready to jsr */
jsr (A0) /* Do the old GetNextEvent */
move.w (sp),10(sp) /* Result to REAL result.
Leave the result in the stack
as a parameter for DoEvent */
jsr DoEvent /* Do our stuff */
addq.l #2,sp /* Remove parameter */
move.l (sp)+,A4 /* Restore A4 */
rts
@1 nop /* "Variable" space */
}
}
/* Save base reg at the end of the previous routine.
** This is clearly a kludge...
*/
void sa0()
{
asm {
@0 lea @0-4,A1
move.l A0,(A1)
}
}
/* Would you like to close a file before the system
** goes down? Would you like to play a sound before
** rebooting? This is where you place the code.
*/
void MyShutDown()
{
SysBeep(10);
SysBeep(10);
}
/* This part gets called once. It saves the pointer
** to us (our static storage), installs the patch and
** puts us in the shutdown queue.
*/
void main()
{
Handle myhandle;
sa0();
asm { movem.l A0-A4,-(A7)
move.l A0,A4
_RecoverHandle
move.l A0,myhandle
}
if(Button())
SysBeep(10); /* Beep, if install was cancelled */
else
{ DetachResource(myhandle);
HLock(myhandle);
OldNextEvent=NGetTrapAddress(NextEventNum,ToolTrap);
NSetTrapAddress(NewGetEvent,NextEventNum,ToolTrap);
ShutDwnInstall(MyShutDown,8);
}
asm { movem.l (A7)+,A0-A4 }
}
/* File ends here! */