gurgle@well.sf.ca.us (Pete Gontier) (09/22/90)
I need to monitor NewWindow. MultiFinder seems to be patching NewWindow and *replacing* it. Thus, a patch I install at INIT time never gets called. A patch to NewWindow I install at the time of the first GetNextEvent affects only the Finder (or the startup application) even if my patch code lives in the System Heap. I patched OpenResFile and waited for something other than MultiFinder to be opened. But by that time, MF has monkeyed with SetTrapAddress enough that the trap dispatcher gets confused and blows up. Anybody got any secrets about patching after MultiFinder? -- Pete Gontier, gurgle@well.sf.ca.us Software Imagineer, Kiwi Software, Inc.
jwhitnell@cup.portal.com (Jerry D Whitnell) (09/24/90)
Pete Gontier, gurgle@well.sf.ca.us writes... |A patch to NewWindow I install at the time of the first GetNextEvent affects |only the Finder (or the startup application) even if my patch code lives in |the System Heap. |Anybody got any secrets about patching after MultiFinder? I havn't tried it, so I'd like to know what you find. However I'd think OpenResFile may be too early in the process that MultiFinder goes through to launch tasks. Try looking for one of the Init* that everyone has to call at the beginning of their program (InitGraf, InitWindow, ad nasum) for one that is not patched by MF, and patch it to patch NewWindow. Since everyone has to call them, your patch code will get control early on in the application. Let me know what you find. Jerry Whitnell SuperMac Technology jwhitnell@cup.portal.com
ericsc@microsoft.UUCP (Eric SCHLEGEL) (09/24/90)
In article <20695@well.sf.ca.us> gurgle@well.sf.ca.us (Pete Gontier) writes: >I need to monitor NewWindow. > >MultiFinder seems to be patching NewWindow and *replacing* it. Thus, a patch I >install at INIT time never gets called. > >A patch to NewWindow I install at the time of the first GetNextEvent affects >only the Finder (or the startup application) even if my patch code lives in >the System Heap. > >I patched OpenResFile and waited for something other than MultiFinder to be >opened. But by that time, MF has monkeyed with SetTrapAddress enough that the >trap dispatcher gets confused and blows up. > >Anybody got any secrets about patching after MultiFinder? I had the same problem, except I needed to patch _MoveWindow. My solution was to patch _InitDialogs, which is not patched out by MF. My _InitDialogs patch then installs the _MoveWindow patch. I assume you know, also, that MultiFinder removes any traps that installed while an application is running when that application quits or is switched out. So you need to reinstall your _NewWindow patch whenever a new applicaton is launched. But wait, there's more! You'll need to keep around the original address of _NewWindow for each running application, so that your _NewWindow patch can jump to the real _NewWindow. The method I originally used to do this was to create a 0 height, 0 width invisible window in my _InitDialogs patch, and store the original _MoveWindow address in the refCon of that window. Then in my _MoveWindow patch I searched the windowList for a window with my special name and grabbed the refCon. I also set the windowKind of the window to 0, hoping that this would keep apps from getting confused. Finally, I named the window "MyWindow :/\-[.". The reason I used all the strange characters is because it's possible for the Finder to create a window named "MyWindow". When this happened, my _MoveWindow patch got confused. But the Finder can never create a window with the ":" character in its name because that character is used to separate directory names. I threw in the other strange characters because most of them are used by some operating system that the Macintosh does or might work with to separate directory names. Remember, though, that the user might not be running MultiFinder. In that case creating a dummy window is a bad idea, because the window will be destroyed after the first running application quits, but your patch will remain. So if MultiFinder is not running, my _InitDialogs patch doesn't create a dummy window. Instead it stuffs the address of _MoveWindow into a global variable in the same heap block as the _MoveWindow patch, so that the patch can access the address. I check for the existence of _OSDispatch (the temporary memory trap) to see if MultiFinder is running. I sent mail to DTS asking if they could recommend a way to check for the "specific functionality" of the trap table being reinitialized when an application quits, but they said "We don't know, and we're not going to spend lots of time trying to find out because you're not a certified developer, so if it works for you, do what you want." This scheme actually does work, too. Unfortunately, it breaks Disinfectant 2.1; as near as I can tell from looking at Disinfectant's code in MacsBug, it's looping through the windowlist and assuming that any window with a non-negative windowKind belongs to Disinfectant. My window's windowKind is 0, so Disinfectant breaks. I now have a new idea which I haven't yet implemented. I'm going to patch _ErrorSound, which is an obscure trap in the Dialog Manager used to set a procedure that's called by the Dialog Manager to produce a sound when the user clicks outside of a dialog. _ErrorSound takes a ProcPtr. My patch will check if the ProcPtr points at a special string identifying my INIT. If it does, my patch will stuff a handle to a block of globals into the memory pointed at by the ProcPtr and return immediately, without calling the real _ErrorSound. I think this will work and not break anyone. Finally, my _InitDialogs patch has to be careful about who is calling it. _InitDialogs can be called by INITs that need to put up a dialog. If that's the case, I don't want my _InitDialogs patch to install the _MoveWindow patch. So when my INIT runs, it clears the first word of the low-mem global CurApName. CurApName isn't changed until the first application runs. My _InitDialogs patch can therefore check to see if the first work of CurApName is still zero. If it is, _InitDialogs is being called by an INIT, and my patch proceeds directly to the real _InitDialogs. So there's my story. It's a mess, but it works. Anyone got any better ideas? -eric
mneerach@iiic.ethz.ch (Matthias Ulrich Neeracher) (09/27/90)
In article <34224@cup.portal.com> jwhitnell@cup.portal.com (Jerry D Whitnell) writes: > Pete Gontier, gurgle@well.sf.ca.us writes... >|A patch to NewWindow I install at the time of the first GetNextEvent affects >|only the Finder (or the startup application) even if my patch code lives in >|the System Heap. >|Anybody got any secrets about patching after MultiFinder? > > Try looking for one of the Init* that everyone has >to call at the beginning of their program (InitGraf, InitWindow, ad nasum) >for one that is not patched by MF, and patch it to patch NewWindow. In my experience, InitGraf works fine but you have to be *extremely* careful not to install your patch twice. This can be quite tricky, especially under Finder. You also have to think about removing your patch again. Matthias ----- Matthias Neeracher mneerach@iiic.ethz.ch "These days, though, you have to be pretty technical before you can even aspire to crudeness." -- William Gibson, _Johnny Mnemonic_
beard@ux5.lbl.gov (Patrick C Beard) (09/28/90)
In article <20695@well.sf.ca.us> gurgle@well.sf.ca.us (Pete Gontier) writes:
#I need to monitor NewWindow.
#
#MultiFinder seems to be patching NewWindow and *replacing* it. Thus, a patch I
#install at INIT time never gets called.
#
#A patch to NewWindow I install at the time of the first GetNextEvent affects
#only the Finder (or the startup application) even if my patch code lives in
#the System Heap.
#
#I patched OpenResFile and waited for something other than MultiFinder to be
#opened. But by that time, MF has monkeyed with SetTrapAddress enough that the
#trap dispatcher gets confused and blows up.
#
#Anybody got any secrets about patching after MultiFinder?
1. In your INIT, get the address of SetTrapAddress.
2. Patch InitGraf, or some other trap that all app's use.
3. When MF runs Finder, apply your other patches with the REAL SetTrapAddress
that you've saved. This will bypass the SetTrapAddress MF installs.
This works, I've tried it, although I can't guarantee that it is safe. I just
know I've tried it.
Good luck!
--
-------------------------------------------------------------------------------
- Patrick Beard, Macintosh Programmer (beard@lbl.gov) -
- Berkeley Systems, Inc. ".......<dead air>.......Good day!" - Paul Harvey -
-------------------------------------------------------------------------------