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! */