[comp.sys.mac.programmer] jGNEFilter

schorsch@oxy.edu (Brent William Schorsch) (03/31/91)

I am implementing a "tail patch" of GetNextEvent via the jGNEFilter
mechanism.  While the relevant tech note discusses how to implement this,
it does not mention if or how I need to call any previously installed
filter...  Currently, I am simply comparing the value I saved prior to
installing my routine in jGNEFilter to #0x00000000.  If the value
differs, I jump to it via   Jsr  (A0)	(where of course A0 is the
previous value).

If this is incorrect, please drop a quick e-mail to inform me.
If this is correct, then why does it fail (ie cause crashes/freezes) on
7.0b4?	(My fault, Apple's fault?)

Thanks.   schorsch@tiger.oxy.edu

nerm@Apple.COM (Dean Yu) (03/31/91)

In article <156750@tiger.oxy.edu> schorsch@oxy.edu (Brent William Schorsch) writes:
>I am implementing a "tail patch" of GetNextEvent via the jGNEFilter
>mechanism.  While the relevant tech note discusses how to implement this,
>it does not mention if or how I need to call any previously installed
>filter...  Currently, I am simply comparing the value I saved prior to
>installing my routine in jGNEFilter to #0x00000000.  If the value
>differs, I jump to it via   Jsr  (A0)	(where of course A0 is the
>previous value).

  Most bad...  jGNEFilter procs expect the event record to be in A0.  Since
you used A0 to call the next procedure, you're effectively passing the
beginning of the next procedure to itself as the event.  Now if that
procedure modifies the event....
  I know you put tail patch in quotes, but just for the record, _GetNextEvent
calls the procedure in jGNEFilter near the beginning of the code.  If you're
trying to catch _GetNextEvent after it's done all it's processing, this
won't work...

  -- Dean Yu
     Blue Meanie, Negative Ethnic Role Model, etc.
     Apple Computer, Inc.
     My opinions and so on and so forth...

jwwalker@opusc.csd.scarolina.edu (Jim Walker) (04/02/91)

In article <50988@apple.Apple.COM> nerm@Apple.COM (Dean Yu) writes:
|  Most bad...  jGNEFilter procs expect the event record to be in A0.  Since
|you used A0 to call the next procedure, you're effectively passing the
|beginning of the next procedure to itself as the event.  Now if that
|procedure modifies the event....

Wrong, the pointer to the event record is in A1.
-- 
  -- Jim Walker 76367.2271@compuserve.com  walker@math.scarolina.edu

stevec@Apple.COM (Steve Christensen) (04/02/91)

nerm@Apple.COM (Dean Yu) writes:
>schorsch@oxy.edu (Brent William Schorsch) writes:
>>I am implementing a "tail patch" of GetNextEvent via the jGNEFilter
>>mechanism.  While the relevant tech note discusses how to implement this,
>>it does not mention if or how I need to call any previously installed
>>filter...  Currently, I am simply comparing the value I saved prior to
>>installing my routine in jGNEFilter to #0x00000000.  If the value
>>differs, I jump to it via   Jsr  (A0)	(where of course A0 is the
>>previous value).
>
>  Most bad...  jGNEFilter procs expect the event record to be in A0.  Since
>you used A0 to call the next procedure, you're effectively passing the
>beginning of the next procedure to itself as the event.  Now if that
>procedure modifies the event....
>  I know you put tail patch in quotes, but just for the record, _GetNextEvent
>calls the procedure in jGNEFilter near the beginning of the code.  If you're
>trying to catch _GetNextEvent after it's done all it's processing, this
>won't work...

Unfortunately that info is wrong.  GetNextEvent calls the filterProc(s) as
the very last thing it does so that they may modify the EventRecord and/or
the result returned by GetNextEvent.  Each filterProc will have the following
setup on entry:

	A1    = pointer to EventRecord
	D0    = GetNextEvent's boolean result
	0(SP) = GetNextEvent caller's return address
	4(SP) = GetNextEvent's boolean result

You can use A0 to jump to any previously-installed filterProcs, but you should
do that: JMP *not* JSR to them.  You also need to follow the toolbox register
saving convention of not trashing any registers other than D1, D2 and A0 since
you should preserve A1 and D0.  So your filterProc should look something like
this:

MyFilter    MOVEM.L D0/D3-D7/A1-A6	; your register use may vary

            ...                         ; do whatever

            MOVE.L  previousProc(Ax),D1 ; get the address of the previous proc
            MOVEM.L (SP)+,D0/D3-D7/A1-A6
            BEQ.S   @NoMore             ; -> no filterProcs after this one
            MOVE.L  D1,-(SP)            ; push the previous filterProc's addr
@NoMore     RTS                         ;  and call it


You need to preserve both the register values and the stack position across
the call to your filterProc so that others down the chain will see the same
thing as yours.  Then when the last filter in the chain is done, it will RTS
back to the caller of GetNextEvent...

steve

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Steve Christensen			Never hit a man with glasses.
  stevec@apple.com			Hit him with a baseball bat.

tj@kona.cs.ucla.edu (Tom Johnson) (04/03/91)

In article <50988@apple.Apple.COM> nerm@Apple.COM (Dean Yu) writes:
>  Most bad...  jGNEFilter procs expect the event record to be in A0.  Since
>you used A0 to call the next procedure, you're effectively passing the
>beginning of the next procedure to itself as the event.  Now if that
>procedure modifies the event....


Actually, according to TN 85:
	"After all other GNE processing is complete the routine
	will be called with A1 pointing to the event record and d0
	containing the boolean result....."

So doing a jsr(a0) to jump into the previous jGNEFilter routine
should work just fine.
>  -- Dean Yu
>     Blue Meanie, Negative Ethnic Role Model, etc.
>     Apple Computer, Inc.
>     My opinions and so on and so forth...

Tom
-- 
Tom Johnson             "I put this moment.............................here
tj@cs.ucla.edu           I put this moment......................here
                         I put this moment--
                                              Over here!"        (Kate)

nerm@Apple.COM (Dean Yu) (04/03/91)

In article <1991Apr2.192534.7628@cs.ucla.edu> tj@kona.cs.ucla.edu (Tom Johnson) writes:
>In article <50988@apple.Apple.COM> nerm@Apple.COM (Dean Yu) writes:
>>  Most bad...  jGNEFilter procs expect the event record to be in A0.  Since
>>you used A0 to call the next procedure, you're effectively passing the
>>beginning of the next procedure to itself as the event.  Now if that
>>procedure modifies the event....
>
>
>Actually, according to TN 85:
>	"After all other GNE processing is complete the routine
>	will be called with A1 pointing to the event record and d0
>	containing the boolean result....."
>
>So doing a jsr(a0) to jump into the previous jGNEFilter routine
>should work just fine.

  For the record, and so that people will stop sending me mail, I was wrong,
I was on drugs, I didn't know what I was talking about, and I shouldn't have
been posting at 5 in the morning.  I realised the info I gave was bogus shortly
after I sent it out, but I was too pooped to make a followup.  Please stop
sending me hate mail...

  -- Dean