[comp.sys.amiga] FixReq -- a FIX for NAUGHTY PROGRAMS that don't set pr_WindowPtr

billk@pnet01.cts.com (Bill W. Kelly) (01/24/89)

I've gotten lots of requests for this program via email, so I'm going to post
this to the net.  It's so small that I don't want to bother with
comp.amiga.sources and comp.amiga.binaries.  (If this bothers you then let me
know why...)

What FixReq is for:

There are many programs that open custom screens; there are few programs that
set pr_WindowPtr to point to their window.  The result of this is that when
this program makes an AmigaDOS call, and something goes wrong, AmigaDOS puts
up a "System Request" on the *Workbench Screen*, not on the program's custom
screen.  Even worse, when you respond to the "System Request" the Workbench
Screen, which has been brought to the front, does not go back where it came
from, but remains in front -- hiding the screen of the program that caused the
"System Request" to appear. 

FixReq solves this problem by patching AutoRequest() to substitute
IntuitionBase->ib_ActiveWindow in place of whatever window pointer was passed
to AutoRequest().

It works nicely.  

What I could have done diferently:

I had a few requests for source code as well, so I'm including that, too. 
However, when I glanced at the source I noticed two things that could be
changed for the better.

        1) I'm never closing intuition.library.  Since Intuition is a
           ROM-based library this realy doesn't matter...  Still,
           I had intended to close it.

        2) I could have substituted the ib_ActiveWindow pointer only if
           the Window argument in the call to AutoRequest() was NULL.  
       
Oh well. Neither of these things is the least bit harmful, nor do either of
these things ever cause FixReq to behave oddly.  They are simply harmless
omissions/oversights, but I thought I'd mention them before someone else does.

BTW, Once FixReq is installed, there is no way to remove it (except by
rebooting).  On the other hand, in all the time I've been using FixReq I've
never WANTED to remove it.  (The patch it installs is only about 20 bytes.)

OK, here's the source:
--
****************************************************************************
* FixReq.asm -- makes all "System Request" requesters       Bill Kelly
* appear in the current active window.                      08/24/87
*
* This code is placed into the public domain without any
* guarantees or support of any kind.
*
* To the best of my knowledge, this program follows all of
* the "rules" for hacking at library vectors and is perfectly
* safe.  However, when you execute it, you are doing so at
* your own risk -- please don't try to sue me if it malfunctions!
*
* With that said, here's what it's doing:
* Every time the Intuition library AutoRequest() function is
* called, FixReq replaces the Window pointer supplied to
* AutoRequest() with a pointer to the currently active window.
*
* The result: All of the "System Request" requesters will conveniently
* pop up right in front of you instead of bringing the WorkBench
* Screen to front and not putting it back.  I find it kinda handy... :-)
****************************************************************************

LibVersion          equ     31              ; 1.1 should work fine.
_LVOOpenLibrary     equ     -($228)
_LVOCloseLibrary    equ     -($19e)
_LVOAllocMem        equ     -($0c6)
_LVOSetFunction     equ     -($1a4)
_LVOAutoRequest     equ     -($15c)
ib_ActiveWindow     equ     52              ; from intuition/intuiBase.i

            lea     newreq(pc),a0
            lea     newreqEnd(pc),a1
            suba.l  a0,a1                   ; find size of newreq routine
            move.l  a1,_newreqSize          ; save for later

            move.l  $4,a6                   ; get execbase

            move.l  _newreqSize,d0          ; bytesize
            moveq   #0,d1                   ; requirements
            jsr     _LVOAllocMem(a6)
            move.l  d0,_newreqAddr          ; save address
            beq.s   error                   ; wow, you are **low** on RAM!

            lea     _IntuiName(pc),a1       ; need to get intuiBase
            move.l  #LibVersion,d0
            jsr     _LVOOpenLibrary(a6)
            move.l  d0,_IntuiBase           ; save intuibase for newreq
            beq.s   error                   ; ..huh? where's intuition???

            move.l  _IntuiBase,a0
            adda.l  #_LVOAutoRequest+2,a0   ; ptr to addr of prev. AutoReq
            move.l  (a0),_oldreq            ; save addr of previous AutoReq

            lea     newreq(pc),a0
            move.l  _newreqAddr,a1
            move.l  _newreqSize,d0
            subq.l  #1,d0
newreqCopy: move.b  (a0)+,(a1)+             ; copy the code
            dbf     d0,newreqCopy

            move.l  _IntuiBase,a1           ; library
            move.l  #_LVOAutoRequest,a0     ; funcOffset
            move.l  _newreqAddr,d0          ; funcEntry
            jsr     _LVOSetFunction(a6)

            moveq   #0,d0                   ; no errors
            rts                             ; exit without error

error:      moveq   #20,d0                  ; no RAM or no intuiBase
            rts                             ; exit with FAIL errorcode

newreq:     move.l  _IntuiBase(pc),a0
            move.l  ib_ActiveWindow(a0),a0  ; get addr of active window
            move.l  _oldreq(pc),-(sp)       ; push prev AutoReq addr
            rts                             ; and return to it
_IntuiBase: ds.l    1                       ; space for intuibase
_oldreq:    ds.l    1                       ; space for addr of oldreq
newreqEnd:                                  ; used to find newreq size

    CNOP    0,4

_newreqSize ds.l    1
_newreqAddr ds.l    1

    CNOP    0,4

_IntuiName  dc.b    'intuition.library',0,0

    END


--

...And here's the uuencoded binary:
--
begin 777 FixReq
M```#\P`````````!```````````````N```#Z0```"Y!^@"$0_H`EI/((\D`8
M``"<+'@`!"`Y````G'(`3J[_.B/`````H&=:0_H`>B`\````'TZN_=@CP```*
M`)1G1"!Y````E-'\___^IB/0````F$'Z`#0B>0```*`@.0```)Q3@!+84<C_:
M_")Y````E"!\___^I"`Y````H$ZN_EQP`$YU<!1.=2!Z``P@:``T+SH`"$YU&
M`````````````````````&EN='5I=&EO;BYL:6)R87)Y```````#[`````H`_
M````````=@```&H```!<````5@```$P```!`````.````"(````6````#```:
&``````/RU
``
end

--

There...

                                Enjoy.
--
Bill W. Kelly                                         billk@pnet01.cts.com
{nosc ucsd hplabs!hp-sdd}!crash!pnet01!billk   crash!pnet01!billk@nosc.mil

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (01/26/89)

In article <3747@crash.cts.com> billk@pnet01.cts.com (Bill W. Kelly) writes:
>There are many programs that open custom screens; there are few programs that
>set pr_WindowPtr to point to their window.  [ ... ]
>
>FixReq solves this problem by patching AutoRequest() to substitute
>IntuitionBase->ib_ActiveWindow in place of whatever window pointer was passed
>to AutoRequest().
>
	JimM will probably toast you for this.

	What happens if the Window pointed to by ib_ActiveWindow goes away
while you're still busy putting up the requester?  Your task could switch
out just long enough for the active Window's owner to CloseWindow() it out
from under your feet.  This is Very Bad.

	Also, LockIBase() won't help you here.  In order to keep the Window
from going away, you have to hold on to the IntuitionBase lock long enough
to get your AutoRequester up.  However, in order to get the AutoRequester
up, Intuition needs to lock IntuitionBase.  Deadlock.  Also Very Bad.

>It works nicely.  
>
	I'll bet it will break in a big way if you stress-test it.

	Caveat Emptor.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

billk@pnet01.cts.com (Bill W. Kelly) (01/28/89)

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>In article <3747@crash.cts.com> billk@pnet01.cts.com (Bill W. Kelly) writes:
>>There are many programs that open custom screens; there are few programs that
>>set pr_WindowPtr to point to their window.  [ ... ]
>>
>>FixReq solves this problem by patching AutoRequest() to substitute
>>IntuitionBase->ib_ActiveWindow in place of whatever window pointer was passed
>>to AutoRequest().
>>
>	JimM will probably toast you for this.
>
>	What happens if the Window pointed to by ib_ActiveWindow goes away
>while you're still busy putting up the requester?  Your task could switch
>out just long enough for the active Window's owner to CloseWindow() it out
>from under your feet.  This is Very Bad.
>
>	Also, LockIBase() won't help you here.  In order to keep the Window
>from going away, you have to hold on to the IntuitionBase lock long enough
>to get your AutoRequester up.  However, in order to get the AutoRequester
>up, Intuition needs to lock IntuitionBase.  Deadlock.  Also Very Bad.
>
>>It works nicely.  
>>
>	I'll bet it will break in a big way if you stress-test it.
>
>	Caveat Emptor.
>

Oh, come on.  First of all, AutoRequest() (or: BuildSysRequest()) doesn't
put up a requester in the _window_ you give it, but in the windows' screen!
Now, the screen could be closed while the AutoRequest() is being displayed
on it, but it hasn't happened in the eighteen months I've been using it.

I don't feel that it's as bad as you make it sound.  As to "stress-testing,"
I suppose I could actually try closing the screen thatthe AutoRequest() is on,
but...   I don't know.  Look, it really does work. 

Try it, you'll like it!

Share and enjoy.
--
Bill W. Kelly                                         billk@pnet01.cts.com
{nosc ucsd hplabs!hp-sdd}!crash!pnet01!billk   crash!pnet01!billk@nosc.mil

jimm@amiga.UUCP (Jim Mackraz) (01/30/89)

In article <3770@crash.cts.com> billk@pnet01.cts.com (Bill W. Kelly) writes:
)ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:

)>>FixReq solves this problem by patching AutoRequest() to substitute
)>>IntuitionBase->ib_ActiveWindow in place of whatever window pointer was passed
)>>to AutoRequest().

)>	JimM will probably toast you for this.

)Oh, come on.  First of all, AutoRequest() (or: BuildSysRequest()) doesn't
)put up a requester in the _window_ you give it, but in the windows' screen!
)Now, the screen could be closed while the AutoRequest() is being displayed
)on it, but it hasn't happened in the eighteen months I've been using it.

A Toast:
    Here's to all Empirical Programmers; may their work never inhabit my disks.

Eighteen whole months.  That proves it, eh?  Where did you say you worked?

Note that if the window is closed, window->WScreen is a technique we
call "Indirection through Free Memory."  Bryce has a little program, memmung,
that you ought to try.

)Share and enjoy.

I'll drink to that ...  ACk!  Poison! ...

)Bill W. Kelly                                         billk@pnet01.cts.com

	jimm
-- 
Jim Mackraz, I and I Computing	   	"Like you said when we crawled down
{cbmvax,well,oliveb}!amiga!jimm          from the trees: We're in transition."
							- Gang of Four
Opinions are my own.  Comments are not to be taken as Commodore official policy.

billk@pnet01.cts.com (Bill W. Kelly) (01/30/89)

jimm@amiga.UUCP (Jim Mackraz) writes:
>In article <3770@crash.cts.com> billk@pnet01.cts.com (Bill W. Kelly) writes:
>)ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>
>)>>FixReq solves this problem by patching AutoRequest() to substitute
>)>>IntuitionBase->ib_ActiveWindow in place of whatever window pointer was passed
>)>>to AutoRequest().
>
>)>	JimM will probably toast you for this.
>
>)Oh, come on.  First of all, AutoRequest() (or: BuildSysRequest()) doesn't
>)put up a requester in the _window_ you give it, but in the windows' screen!
>)Now, the screen could be closed while the AutoRequest() is being displayed
>)on it, but it hasn't happened in the eighteen months I've been using it.
>
>A Toast:
>    Here's to all Empirical Programmers; may their work never inhabit my disks.

Oh, clr.l $4.
 
>Eighteen whole months.  That proves it, eh?  Where did you say you worked?

I work at Bonehead Research.  Why do you ask?
 
>Note that if the window is closed, window->WScreen is a technique we
>call "Indirection through Free Memory."  Bryce has a little program, memmung,
>that you ought to try.

Yes I know that, I know that.  

I don't suppose I'm allowed to put Forbid()/Permit() around the section of
code that gets ib_ActiveWindow and calls AutoRequest(), am I?   

Is there a "proper" way to do what I'm doing?  

(If there is, I'll change FixReq.  If not, I will continue to use the current
version of FixReq.  You may continue to be pestered by programs that don't 
bother to set pr_WindowPtr.  Have a nice day.)

--
Bill W. Kelly                                         billk@pnet01.cts.com
{nosc ucsd hplabs!hp-sdd}!crash!pnet01!billk   crash!pnet01!billk@nosc.mil