[comp.sys.amiga] How does SCRIPIT work?

Lee_Robert_Willis@cup.portal.com (09/08/90)

I have a Amiga Guru question:  I want to intercept the 'IntuiMessages' that
are passed from Intuition to an application (where the "application" is    
any old pre-compiled Amiga program).                                       
                            
TECHNICAL BACKGROUND:                                                     
                                                                          
Normally, Intuition communicates to applications via to 'MessagePorts'    
contained in the 'Window' structure.  Messages from Intuition are sent to
the application via 'Window->UserPort', and those messages are replied to 
via 'Window->WindowPort'.  (See Ugly Text diagram:) 
-----------------------------------------------------------------------

                                [Input.Device]
      Mouse and keyboard events       |
      are fed to Intuition from       |
      the Input device.               v

Intuition sends msgs   +--------[Intuition]<--------+   Intuition reads
to the Message Port    |                            |   reply from 
'UserPort' in the      v                            |   'WindowPort'. 
App's window.
                    Window->UserPort      window->WindowPort                 

Application reads msgs |                            ^   Application          
from 'UserPort'        |                            |   replies to msgs.     
                       +---->[Application program]--+                        

--------------------------------------------------------------------------
What I want to do is insert a 'middleman' process into this loop.  I want
to be able to patch a process in that will intercept the messages sent to
the application, process them as needed, then pass them on to the
application.  The 'middleman' should also intercept the replies as well.
(See next ugly text diagram)
--------------------------------------------------------------------------
      Mouse and keyboard events       |
      are fed to Intuition from       |                                      
      the Input device.               v

Intuition thinks its   +--------[Intuition]<--------+   Intuition reads
sending to the App.,   |                            |   reply from
but is really sending  v                            |   'WindowPort'.
to middleman.
               [middleman->UserPort]        [middleman->WindowPort]

Middleman processes    |                            ^   middleman forwards
events, then passes    v                            |   reply to Intuition.
them on to App.
                   [window->UserPort]     [window->WindowPort]               

Application reads msgs |                            ^   Application thinks
from 'UserPort'        |                            |   its replying to
                       +---->[Application program]--+   Intuition, but is
                                                        really replying
                                                        to middleman.
--------------------------------------------------------------------------
(NOTE: It is not necessary that the 'middleman' process be structured
exactly as this diagram, as long as it is:
   * Capable of monitoring IntuiMessages.
   * Capable of feeding 'false' IntuiMessages to application.                
   * Capable of monitoring replies to IntuiMessages.                         

I know its possible, because the program "ScripIt" by Khalid Aldoseri
does it, but for the life of my, I can't figure out how.  (Unfortunately,
there is no source included with SCRIPIT.)

WHY DO I WANT TO DO THIS?

I'm trying to create a 'tear-off' menu facility similar to that on the
Macintosh.  (For those who've never seen it, 'tearing-off' a menu creates a
new window which contains all the menu items converted into gadgets.  This
is very handy for menus that are used all the time.  Fr'instance, if a
graphic  program put its palette on a menu (e.g. IntroCAD), you could
'tear-off' this menu, drag the window to a free screen location, and pick
colors from the tear off menu (much more convenient!) and the program
reacts as if you had used the real menu.  When you no longer need the
tear-off menu, close its window.)

Assuming the 'middleman' problem'tear-of' can be solved, it should not be
too difficult to implement this utility, which should work on ANY existing
Amiga program!
Send replies to : Lee_Robert_Willis@cup.portal.com
      __  __  __ __        __  _   __    __  __        __    o
The  /_  / / /_  /  |   / /_/ /_| /_    /_  /_/ / /| / /   /\O/\
    __/ /_/ /   /   |/|/ / / / \ /_    __/ / / / / |/ /   ///^\\\
       Software so good, it's a religious experience!       |_|     

UH2@psuvm.psu.edu (Lee Sailer) (09/10/90)

In article <33651@cup.portal.com>, Lee_Robert_Willis@cup.portal.com says:

>I have a Amiga Guru question:  I want to intercept the 'IntuiMessages' that
>are passed from Intuition to an application (where the "application" is
>any old pre-compiled Amiga program).

I'm not a real guru, but I play one on TV...

First, I recall that when SCRIPIT first showed, it came with source code,
so that's one place you could look for inspiration.

I've never even imagined being able to pull off what you ask, but basically I
think the principles aren't too scary.  When a program calls NewWindow(),
Intuition sets up the window, including giving it a Message Port that Intuition
can send messages too.

I think your program could do a Forbid() to stop everything else from happening
and then walk through the systems list of windows until it finds the one you
want to manage.  Assign its Message Port to one of your local variables,
and then run at a higher priority than the target task.  Your task should
look through the incoming messages for ones it wants to delete, modify, or
add new ones, and then WaitPort().  This will give the target task time
to process some or all of the messages in the queue.  If a new one arrives,
your task will awaken before the receiver gets a chance to get it.

I think the IntuiMessage itself contains the MsgPort to ReplyMsg() to.
To intercept replies, your task would have to change that MsgPort to
one of its own.  I guess it must also save a copy of the original MsgPort.
Then, it'll get the ReplyMsg()s, can do whatever it needs to do, and then
change its reply port back to the oringinal and reply to it.

Like I say.  I've never done this, but it seems like one possible way to
go at it.

         lee

eeh@public.BTR.COM (Eduardo E. Horvath eeh@btr.com) (09/10/90)

In article <90252.202734UH2@psuvm.psu.edu> UH2@psuvm.psu.edu (Lee Sailer) writes:
>In article <33651@cup.portal.com>, Lee_Robert_Willis@cup.portal.com says:

>>I have a Amiga Guru question:  I want to intercept the 'IntuiMessages' that
>>are passed from Intuition to an application (where the "application" is
>>any old pre-compiled Amiga program).

[...]

>I think your program could do a Forbid() to stop everything else from happening
>and then walk through the systems list of windows until it finds the one you
>want to manage.  Assign its Message Port to one of your local variables,
>and then run at a higher priority than the target task.  Your task should
>look through the incoming messages for ones it wants to delete, modify, or
>add new ones, and then WaitPort().  This will give the target task time
>to process some or all of the messages in the queue.  If a new one arrives,
>your task will awaken before the receiver gets a chance to get it.
>
>I think the IntuiMessage itself contains the MsgPort to ReplyMsg() to.
>To intercept replies, your task would have to change that MsgPort to
>one of its own.  I guess it must also save a copy of the original MsgPort.
>Then, it'll get the ReplyMsg()s, can do whatever it needs to do, and then
>change its reply port back to the oringinal and reply to it.
>
>Like I say.  I've never done this, but it seems like one possible way to
>go at it.
>
>         lee

	You also need to allocate a signal bit, put it in the message port
mp_SigBits field, and change the mp_SigTask field to point to your task.
Remember to save all of the information, because you should put it all back
before you close down.  You can wake up the original task through a Signal()
call.  Needless to say, this will not be compatible with any future protected
memory environment.

	Yes, I have done this as a test, and it does work.  But I don't 
recommend fiddling with other tasks' structures.

=========================================================================
Eduardo Horvath				eeh@btr.com
					..!{decwrl,mips,fernwood}!btr!eeh
	"Trust me, I am cogisant of what I am doing." - Hammeroid
=========================================================================

Newsgroups: comp.sys.amiga
Subject: Re: How does SCRIPIT work? (How intercept IntuiMessages?)
Summary: 
Expires: 
References: <33651@cup.portal.com> <90252.202734UH2@psuvm.psu.edu>
Sender: 
Followup-To: 
Distribution: 
Organization: BTR Public Access UNIX, MtnView CA, Contact: cs@btr.com 415-966-1429
Keywords: