[comp.sys.amiga] How to find CLI window pointer

wfh58@leah.Albany.Edu (William F. Hammond) (07/21/89)

Elementary question:

Suppose that my program has found that it is running in a CLI.  How can
it find a pointer to the WINDOW of that CLI?  I know how to find the
"CON:" process, but I can't find the window.  I might be able to settle
for the RastPort (i.e., ...->RPort ).

It seems to be the case that posting text to a window via the console
device does NOT update the RastPort's drawing pen location.  Is this
correct?

Thanks.

------------------------------------------------------------------------
Bill Hammond                         Dept. of Mathematics & Statistics
518-442-4625                         SUNYA
wfh58@leah.albany.edu                Albany, NY 12222
-------------------------------------------------------------------------

cmcmanis%pepper@Sun.COM (Chuck McManis) (07/22/89)

In article <1914@leah.Albany.Edu> (William F. Hammond) writes:
->Elementary question:
->Suppose that my program has found that it is running in a CLI.  How can
->it find a pointer to the WINDOW of that CLI?  I know how to find the
->"CON:" process, but I can't find the window.  I might be able to settle
->for the RastPort (i.e., ...->RPort ).

You have to send the console handler (CON:) a packet that asks for the
window stuff. There is a program by Carolyn S. of CATS called ConsPackets.c
which gives an excellent example of this. It is on a fish disk as well. 

->It seems to be the case that posting text to a window via the console
->device does NOT update the RastPort's drawing pen location.  Is this
->correct?

Yes, but don't count on it. The Console.device makes a snapshot of
the window RastPort (don't ask me why) whenever it is reset, that
pen location changes in the snapshot, you can draw to your hearts
content in the Window's RPort without affecting the console text.
With 1.4 this will probably change somewhat since the console device
is getting rewhacked but don't ask me how.

--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.
"A most excellent barbarian ... Genghis Kahn!"

mks@cbmvax.UUCP (Michael Sinz - CATS) (07/22/89)

In article <1914@leah.Albany.Edu> wfh58@leah.Albany.Edu (William F. Hammond) writes:
>Elementary question:
>
>Suppose that my program has found that it is running in a CLI.  How can
>it find a pointer to the WINDOW of that CLI?  I know how to find the
>"CON:" process, but I can't find the window.  I might be able to settle
>for the RastPort (i.e., ...->RPort ).
>

What you need to do is:

1) Make sure that you are a CLI...

2) Check that there is a pr_ConsoleTask  (in the process structure)

3) Send a ACTION_DISK_INFO packet  (See AmigaDOS manual for details)

4) Check return result of the packet...  (Maybe a AUX: CLI...)

5) Get the window pointer from id_VolumeNode  (Again see AmigaDOS manual)

6) Check to see that the window pointer is not NULL  (May be a CNX:...)

Now, once you have this window pointer you can do most anything.  However
be carefull as you can get yourself into race conditions rather easily.

Attached is a bit of assembly code that will do this for you.  At the
end of the routine it will return the window in d2 or will branch to
an error routine.  (I just cut this out of some code I have here...)

--------------------------------------------------------------------------------
*******************************************************************************
*									      *
*	Copyright (c) 1985-89 by Michael Sinz    MKSoft Development	      *
*									      *
*	AmigaDOS EXEC release 1.0 or greater...				      *
*									      *
*******************************************************************************
*									      *
* Register usage through this system...					      *
*									      *
*	a0	- Scrap							      *
*	a1	- Scrap							      *
*	a2	- Pointer to FW_Info					      *
*	a3	- EXEC base save					      *
*	a4	- Task							      *
*	a5	- FindWindow struct					      *
*	a6	- ExecBase / IntuitionBase				      *
*	a7	- Stack pointer...  What else?				      *
*									      *
*	d0	- Scrap							      *
*	d1	- Scrap							      *
*	d2	- Window pointer					      *
*	d3	- pr_Console handler					      *
*	d4	- Block pen color					      *
*	d5	- Detail pen color					      *
*	d6	- CLI Task number (Used to make the colors)		      *
*	d7	- Zero...						      *
*									      *
*******************************************************************************
*
* We need to define a structure that has StandardPacket and InfoData in it...
* This is used when we send the packet to the console device for our window
* in order to find the Intuition Window Pointer for it...
*
	STRUCTURE		FindWindow,0
			STRUCT	FW_Pack,sp_SIZEOF
			STRUCT	FW_Info,id_SIZEOF
			LABEL	FW_SIZEOF
*
*******************************************************************************
*
* This is my little Packet Sending code.  In this case, I have defined a
* new structure that contains the StandardPacket structure and the InfoData
* structure needed for this call.  For quick work and smaller code, I allocate
* the packet from the stack.  Since packets *MUST* be long word aligned, a bit
* of work must be done to make sure that the memory is aligned...
*
		lea	-(FW_SIZEOF+4)(sp),sp	; Move stack to allocate space
*
* I allocate 4 bytes more than needed since I may need to move the pointer
* a bit.  I could actually do this by allocating 2 bytes more since
* the stack is always word aligned.  However, if the stack is long-word
* aligned, I want to keep it that way since code runs faster on the 68020/030
* when the stack is long-word aligned.
*
* As you can see, the address we get from the stack is then bumped by 3 and
* then the bottom 2 bits are cleared.  The new address is then either
* the original or 2 bytes further down the stack.  (Stack was already
* word aligned so those are the only possibilities.)
*
		move.l	sp,d1			; Get address
		addq.l	#3,d1			;   and make sure
		and.b	#$FC,d1			;   it is long word aligned
		move.l	d1,a5			; Point to the thing...
*
* Ok, so we have a packet at a5.  Now, we need to set the strange links
* that packets use.  Address of the packet gets stored in the messages
* list node name pointer  (??Weird stuf??)  and the packet's link stores
* the pointer to the message structure...
*
		lea	(FW_Pack+sp_Pkt)(a5),a1	; Get adress of FW_Pack.sp_Pkt
		move.l	a1,(FW_Pack+sp_Msg+LN_NAME)(a5)	; Store sp_Pkt in name
		move.l	a5,(FW_Pack+sp_Pkt+dp_Link)(a5)	; Store sp_Msg in link
*
* Packets are weird in that the packet reply port is not the standard
* message reply port (packets use their own reply methods...)
*
		lea	pr_MsgPort(a4),a0	; Set the reply port...
		move.l	a0,(FW_Pack+sp_Pkt+dp_Port)(a5)
*
* To get the address of the window a console task has, we do a packet
* of type ACTION_DISK_INFO.  (?!?)  This packet type takes a special
* InfoData structure that will contain the results of this call.
*
		move.l	#ACTION_DISK_INFO,(FW_Pack+sp_Pkt+dp_Type)(a5)
*
* So, we now have to set up a pointer to the InfoData structure.  However,
* this pointer is defined (due to BCPL AmigaDOS) as a BCPL pointer.  These
* pointers are simply the address of the item pointed to left-shifted 2.
* In other words, the bottom two bits are dropped.  This is why all of the
* AmigaDOS structures MUST BE long word aligned.  AmigaDOS can not address
* (via BCPL) non-long word addresses.
*
		lea	FW_Info(a5),a2		; InfoData structure address
		move.l	a2,d2
		asr.l	#2,d2			; Make BPTR out of it...
		move.l	d2,(FW_Pack+sp_Pkt+dp_Arg1)(a5)
*
* Ok, the packet is set up and ready to go.  We take our reply port
* (which is still in a0 from the steps above) and store it in a register
* that will not get modified by the call.  Then we just send the packet
* and wait for it to return.
*
		move.l	a0,d2		; Save our port address
		move.l	d3,a0		; Get console port address
		move.l	a5,a1		; Get message packet address
		CALLSYS	PutMsg		; Send Packet
		move.l	d2,a0		; Our message port...
		CALLSYS	WaitPort	; Wait for return
		move.l	d2,a0		; Restore it again...
		CALLSYS	GetMsg		; Get it from the port
*
* The packet came back and we should now do some testing for errors.
*
		move.l	id_VolumeNode(a2),d2		; Get window
		move.l	(FW_Pack+sp_Pkt+dp_Res1)(a5),d0	; Check return code...
		lea	(FW_SIZEOF+4)(sp),sp	; Move stack to deallocate
		addq.l	#1,d0			; Bump TRUE return to 0...
		bne.s	ErrorExit		; Exit if returned error...
		tst.l	d2			; Check the window...
		beq.s	ErrorExit		; Do color if there is one...
*
*******************************************************************************

At this point, d2 would have the window pointer...  If anything went wrong,
we would have gotten to the ErrorExit section of code somewhere...
-- 

/----------------------------------------------------------------------\
|      /// Michael Sinz -- CATS/Amiga Software/Support Engineer        |
|     ///  PHONE 215-431-9422  UUCP ( uunet | rutgers ) !cbmvax!mks    |
|    ///                                                               |
|\\\///      ...and then, just as all was in kaos, someone said:       |
| \XX/     "Let there be ... what was that!? ... An Amiga? ... light!" |
\----------------------------------------------------------------------/