[comp.sys.mac.programmer] Need jGNEFilter help

essam@gagme.chi.il.us (Essam Khairullah) (11/28/90)

I'm writing an INIT that patches GetNextEvent to show the user an alert
at a specified time.  Unfortunately, it causes problems.  For instance, if
I'm in the Finder and I activate my screen saver and then deactivate it, my
patch doesn't notify the Finder to redraw its screen.

I called Symantec (I'm using THINK C 4.0) and they suggested I try using
the low-memory global jGNEFilter instead of actually patching GNE.

I must be doing something wrong, because now even worse problems occur
than when I just patched GNE itself.  In the original INIT, I patched
SystemTask and it worked just fine, but I allocate memory and SystemTask
is marked as not moving memory, so I figured it would be safer to patch
something that is allowed to move memory.

Here's a sample of the code I'm using:

void	main( void)
{
ProcPtr		oldJGNEFilter;
Handle		myHandle;

/* Get handle to my routine... */
asm
	{
	move.L A0, myPtr;
	}
RememberA0();
SetUpA4();	/* Allow use of global variables */
myHandle = RecoverHandle( myPtr);
DetachResource( myHandle);

.....	/* Allocate and initialize global data */

oldJGNEFilter = JGNEFilter;	/* Save original JGNEFilter value */
JGNEFilter = ( ProcPtr) newJGNEFilter;	/* Install my own filter  */
RestoreA4();
}

pascal	void	newJGNEFilter ( void)                                         
{
long	saveD0, saveD1, saveA1, saveA7;

asm		/* Save certain registers used by JGNEFilter */
	{
	move.L D0, saveD0;
	move.L D1, saveD1;
	move.L A1, saveA1;
	move.L A7, saveA7;
	}
SetUpA4();	/* Allow use of global variables */

.....	/* Check if it's time to call my routine, call it if neccessary */

asm		/* Restore saved registers */
	{
	move.L saveD0, D0;
	move.L saveD1, D1;
	move.L saveA1, A1;
	move.L saveA7, A7;
	}
oldJGNEFilter;	/* Call original JGNEFilter */
RestoreA4();	/* Clean things up and return */
}

And that's it!  I hope that I'm just doing something stupid and obvious
so it's easily fixed.  Like I said, it worked just fine when I was patching
SystemTask, but I wanted to be safe.  BTW, if I call NewDialog and give
it storage for the DialogRecord and also provide a handle of the itemList,
does it allocate memory, and if so, can I do something to avoid it?  If
it's not too much trouble, I may just keep on patching SystemTask if I can
do it without allocating memory.

Anyhow, thanks in advance for any help anyone can offer.


-- 

Essam Khairullah					essam@gagme.chi.il.us

I don't got no fancy signature.

sean_parent.snarkmail_l_z@gateway.qm.apple.com (Sean Parent) (11/30/90)

The problem with your patch is that it is a tail patch. (A tail patch is a 
patch that does work after calling the original routine instead of 
returning directly to the original caller.) This is breaking a come-from 
patch that MultiFinder has installed. (A come from patch is a patch that 
checks the return address to fix a routine in ROM.) There are a few 
possible options that you could use ->

1) Have your INIT install a driver to get time cleanly.
2) Patch SystemTask (I think it is a better place to patch then 
GetNextEvent and contrary to inside Mac it can move memory (because it can 
call drivers and desk accessories) using a head patch.
3) Patch GNE using a head patch.

When I patch traps I usually use asm code of the form ->

SUBQ.W   #4,SP           ; save space to chain
LINK     A6,#stackSpace  ; set up A6 frame
MOVEM.L  savedRegs,-(SP) ; save away ALL used registers (include scratch)

                         ; Do my work

MOVE.L   oldRoutineAddress,4(A6) ; put old address in chain space
UNLK     A6              ; restore A6 frame
MOVEM.L  (SP)+,savedRegs ; restore ALL registers
RTS                      ; chain to old routine

In this way, any come from patchs that depend on register values (yes, they 
do exist) are kept intact. Also, some ROM routines depend on some of the 
traps not messing with scratch registers. (For example, the Dialog Manager 
relies on the fact that SetPort only trashes A0 and non of the other 
scratch registers).

Sean Parent
"Quality unattainable in a reasonable amount of time."

ech@cbnewsk.att.com (ned.horvath) (11/30/90)

From article <917@gagme.chi.il.us>, by essam@gagme.chi.il.us (Essam Khairullah):
...
> I called Symantec (I'm using THINK C 4.0) and they suggested I try using
> the low-memory global jGNEFilter instead of actually patching GNE.

> I must be doing something wrong, because now even worse problems occur
> than when I just patched GNE itself...
> Here's a sample of the code I'm using:
...
> asm		/* Restore saved registers */
> 	{
> 	move.L saveD0, D0;
> 	move.L saveD1, D1;
> 	move.L saveA1, A1;
> 	move.L saveA7, A7;
> 	}
> oldJGNEFilter;	/* Call original JGNEFilter */
> RestoreA4();	/* Clean things up and return */
> }


Two problems: first, oldJGNEFilter may be nil or odd, in which case you
don't want to call it(!)  Second, TechNote 85 explicitly suggests that
you set the (boolean) return code at 4(a7), which is in your local
variable space.

Hope that helps...

=Ned Horvath=

carlton@aldebaran (Mike Carlton) (11/30/90)

In article <11380@goofy.Apple.COM> sean_parent.snarkmail_l_z@gateway.qm.apple.com (Sean Parent) writes:
>The problem with your patch is that it is a tail patch. (A tail patch is a 
>patch that does work after calling the original routine instead of 
>returning directly to the original caller.) This is breaking a come-from 
>patch that MultiFinder has installed. (A come from patch is a patch that 
>checks the return address to fix a routine in ROM.) There are a few 
>possible options that you could use ->
>
>1) Have your INIT install a driver to get time cleanly.
>2) Patch SystemTask (I think it is a better place to patch then 
>GetNextEvent and contrary to inside Mac it can move memory (because it can 
>call drivers and desk accessories) using a head patch.
>3) Patch GNE using a head patch.
...

Is option 2 correct?  I have a patch that needs to move memory and since
SystemTask isn't marked as moving memory, I felt I couldn't patch in there 
(altough SystemTask was the logical place for my patch).

Is this just an oversight in the documentation? -- the X-Ref book lists
SystemTask as not moving memory.  If I move memory on SystemTask, will
I get burnt on a future OS release?

thanks,
mike

Mike Carlton	carlton@cs.berkeley.edu

essam@gagme.chi.il.us (Essam Khairullah) (12/03/90)

Newsgroups: comp.sys.mac.programmer
Subject: Re: Need jGNEFilter help
Summary: 
Expires: 
References: <917@gagme.chi.il.us> <11380@goofy.Apple.COM> <9330@pasteur.Berkeley.EDU>
Sender: 
Followup-To: 
Distribution: na
Organization: GAGME - Public Access UNIX of Chicago, Illinois, USA, Earth
Keywords: 

In article <9330@pasteur.Berkeley.EDU> carlton@aldebaran (Mike Carlton) writes:
>In article <11380@goofy.Apple.COM> sean_parent.snarkmail_l_z@gateway.qm.apple.com (Sean Parent) writes:
>>...There are a few possible options that you could use ->
>>...
>>2) Patch SystemTask (I think it is a better place to patch then 
>>GetNextEvent and contrary to inside Mac it can move memory (because it can 
>>call drivers and desk accessories) using a head patch.
>...
>
>Is option 2 correct?  I have a patch that needs to move memory and since
>SystemTask isn't marked as moving memory, I felt I couldn't patch in there 
>(altough SystemTask was the logical place for my patch).
>
>...Can I get burnt on a future OS release?
>
>thanks,
>mike
>
>Mike Carlton	carlton@cs.berkeley.edu

I originally had my routine patch SystemTask and I rarely experienced any
trouble, however once I was using DesignStudio when my INIT's dialog
popped up (anouncing an appointment).  When I dismissed it and then pulled
down a menu, the menu's font was Eurostyle Bold.  After pulling down the
menu again it was fine, but it did seem odd.  Anyhow, it didn't seem to
be at all destructive, so I might just continue to use SystemTask.

BTW, if I call GetNewDialog and provide storage for the DialogRecord as
well as a handle to the item list, will it actually allocate memory,
thereby risking a memory move?

Thanks,

-- 

Essam Khairullah					essam@gagme.chi.il.us

I don't got no fancy signature.