[comp.sys.amiga.tech] Finding the Workbench screen

ranjit@eniac.seas.upenn.edu (R. Bhatnagar) (11/27/88)

How can I find the screen structure for the current Workbench
Screen short of opening a window on it and then looking in
the Window structure?  Mostly I want to find its size so I can
open another of the same size.  I could go to Preferences for
that, but there are other uses for the workbench's screen...

	- Ranjit

p.s. if it's something easy, I promise to feel stupid!
   
"Trespassers w"   ranjit@eniac.seas.upenn.edu	mailrus!eecae!netnews!eniac!...
If you throw a rock into the night and something barks, you know you hit a dog.

fgd3@jc3b21.UUCP (Fabbian G. Dufoe) (11/28/88)

From article <6356@netnews.upenn.edu>, by ranjit@eniac.seas.upenn.edu (R. Bhatnagar):
> How can I find the screen structure for the current Workbench
> Screen short of opening a window on it and then looking in
> the Window structure?  Mostly I want to find its size so I can
> open another of the same size.  

     It's something easy, but it's not easy to find.  You need to call
	  Success = GetScreenData(Buffer, Size, Type, Screen)
     Where
	  BOOL Success;
	  CPTR Buffer;
	  USHORT Size;
	  USHORT Type;
	  struct Screen *Screen;
     This function copies into the caller's buffer data from a screen
structure.  Typically, this call will be used to find the size, title bar
height, and other values for a standard screen, such as the Workbench
screen.
     To get the data for the Workbench screen, one would call
	  GetScreenData(buff, sizeof(struct Screen), WBENCHSCREEN, NULL)

Note: If the requested standard screen is not open, this function will have
the effect of opening it.

To read about GetScreenData() in the Autodocs, start reading about
GetPrefs().  Because of something wrong with the file GetScreenData doesn't
show up in the outline.  You have to page through the GetPrefs() section to
find it.

--Fabbian Dufoe
  350 Ling-A-Mor Terrace South
  St. Petersburg, Florida  33705
  813-823-2350

UUCP: ...codas!usfvax2!jc3b21!fgd3 
      ...uunet!pdn!jc3b21!fgd3

lphillips@lpami.van-bc.UUCP (Larry Phillips) (11/28/88)

> How can I find the screen structure for the current Workbench
> Screen short of opening a window on it and then looking in
> the Window structure? 

  Easiest path for finding the WB screen is through IntuitionBase,
FirstScreen, Flags. Just walk the screen list until you find the
one with the Flags bit ($0001) set. This is the WB. It's always
been first whenever I've looked.

-larry

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------+ 
|   //   Larry Phillips                                          |
| \X/    lpami.wimsey.bc.ca!lphillips or van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                  |
+----------------------------------------------------------------+

cmcmanis%pepper@Sun.COM (Chuck McManis) (11/29/88)

In article <6356@netnews.upenn.edu> (R. Bhatnagar) writes:
> How can I find the screen structure for the current Workbench
> Screen short of opening a window on it and then looking in
> the Window structure?

Use the 1.2 function GetScreenData().

	NAME
		GetScreenData -- Get a copy of a screen data structure

	SYNOPSIS
		Success = GetScreenData(Buffer, Size, Type, Screen)
		  D0			 A0      D0    D1     A1
		BOOL 		Success
		CPTR		*Buffer
		USHORT		Size;
		USHORT		Type;
		struct Screen 	*Screen;
	
	For the workbench screen call :
	suc = GetScreenData(buff, sizeof(struct Screen), WBENCHSCREEN, NULL);

	Now buff will have a copy of the workbench screens structure in it.
	Success == TRUE;


--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.

phil@titan.rice.edu (William LeFebvre) (11/30/88)

In article <79135@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>In article <6356@netnews.upenn.edu> (R. Bhatnagar) writes:
>> How can I find the screen structure for the current Workbench
>> Screen short of opening a window on it and then looking in
>> the Window structure?
>
>Use the 1.2 function GetScreenData().
>...

I'm glad this discussion came up, because just today I needed to do this
very thing. But I sure can't find any documentation on this function at
all.  It isn't in the RKMs and I can't find it in the autodocs.  Is it
hiding somewhere or is it un-documented?  If the latter, is it intended
for anyone's use?

As for *why* I need it:  I need to know the height of the default font
before I open a window (the Left and Top Edges and some Borders depend on
it).  Is there any other way to get it besides getting the workbench's
struct Screen and using Screen->Font->tf_YSize?  I suppose I could open
the window without gadgets (well, the system gadgets will be there of
course), get the YSize from the rastport, set up my gadgets and then add
them, but it just seems nicer to me to have the gadgets ready when I open
the window....

			William LeFebvre
			Department of Computer Science
			Rice University
			<phil@Rice.edu>

cmcmanis%pepper@Sun.COM (Chuck McManis) (12/01/88)

In article <2238@kalliope.rice.edu> phil@Rice.edu (William LeFebvre) writes:
>I'm glad this discussion came up, because just today I needed to do this
>very thing. But I sure can't find any documentation on [GetScreenData] at
>all.  It isn't in the RKMs and I can't find it in the autodocs.  Is it
>hiding somewhere or is it un-documented?  If the latter, is it intended
>for anyone's use?
>			William LeFebvre

Secret number 7 from the Amiga Archives. Not all functions in the AutoDocs
occur on page boundaries. When you say "can't find it in the Autodocs"
I assume you are using the infominder version of the autodocs. This 
assumption is based on two facts, one that it *is* in the autodocs if
you extract them from the arc file, and two if you go to the function 
that occurs alphabetically before GetScreenData in the infominder
'docs and page down you find GetScreenData at the end of it. The problem
is that the conversion from the text form to the infominder form 
missed a few page breaks and therefore some of the functions are "hidden"
by being attached to other functions. 

Note it couldn't possible by in the RKM until the 1.2+ versions come 
out from AW in the spring.


--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.

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (12/01/88)

In article <1982@van-bc.UUCP> lphillips@lpami.van-bc.UUCP (Larry Phillips) writes:
>  Easiest path for finding the WB screen is through IntuitionBase,
>FirstScreen, Flags. Just walk the screen list until you find the
>one with the Flags bit ($0001) set. This is the WB. It's always
>been first whenever I've looked.
>
	Shall I correct him, JimM, or shall you?

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
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

jimm@amiga.UUCP (Jim Mackraz) (12/02/88)

In article <1982@van-bc.UUCP> lphillips@lpami.van-bc.UUCP (Larry Phillips) writes:
)
)> How can I find the screen structure for the current Workbench
)> Screen short of opening a window on it and then looking in
)> the Window structure? 
)
)  Easiest path for finding the WB screen is through IntuitionBase,
)FirstScreen, Flags. Just walk the screen list until you find the
)one with the Flags bit ($0001) set. This is the WB. It's always
)been first whenever I've looked.
)
)-larry


Very terrible, Larry, on several counts.  (Not that you, yourself, are a
terrible person, he disclaimed, but that this advice is quite so.)

1) The Workbench screen is only FirstScreen when it's frontmost.

2) The identifier SCREENTYPE is four bits.  You would check to
   see if (Flags & SCREENTYPE) == WBENCHSCREEN;  Bit 0 is set for
   custom screens, too (no wonder it was always the first screen).

3) Now that you have your happy pointer to the Workbench screen (if lucky),
   it can be closed at any time, leaving you indirecting through free
   memory.  Nice.   ("Oh, but how often will that happen?" the hacker asked.)

   This is why GetScreenData() makes a copy of the screen, but be
   aware that pointers found in the copy are not guaranteed.

4) You forgot to stress the importance of protecting your walk down a shared
   list.  One uses LockIBase() for this.


Your code is broken, Pal.  With advice like this, who needs Multifinder?

Maybe next time.

	jimm

-- 
	Jim Mackraz, I and I Computing	  
	amiga!jimm	BIX:jmackraz
Opinions are my own.  Comments regarding the Amiga operating system, and
all others, are not to be taken as Commodore official policy.

mlelstv@faui44.informatik.uni-erlangen.de (Michael van Elst ) (12/02/88)

In article <7796@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>In article <1982@van-bc.UUCP> lphillips@lpami.van-bc.UUCP (Larry Phillips) writes:
>>  Easiest path for finding the WB screen is through IntuitionBase,
>>FirstScreen, Flags. Just walk the screen list until you find the
>>one with the Flags bit ($0001) set. This is the WB. It's always
>>been first whenever I've looked.
>>
>	Shall I correct him, JimM, or shall you?
>

Please use flame oil or instant wolves or...

I wish that any of the small scale programmers here in germany
would be 'corrected'.
Nearly any program published in german amiga magazines
uses IntuitionBase to find screen, windows, mouse positions.
They ask the hardware for mousebuttons and poke into the CIA ports
to print.

And the first thing they do is to stop interrupts and go to
supervisormode (why that ?) to avoid complications.

What a 'harmless' behaviour to get the workbench from the screen list
(if you LockIBase, UnLockIBase, etc..) :-)

				Michael van Elst

E-mail: UUCP: ...uunet!unido!fauern!faui44!mlelstv

lphillips@lpami.van-bc.UUCP (Larry Phillips) (12/03/88)

>In article <1982@van-bc.UUCP> lphillips@lpami.van-bc.UUCP (Larry Phillips) writes:

>>  Easiest path for finding the WB screen is through IntuitionBase,
>>FirstScreen, Flags. Just walk the screen list until you find the
>>one with the Flags bit ($0001) set. This is the WB. It's always
>>been first whenever I've looked.
>>
>	Shall I correct him, JimM, or shall you?

Don't be an ass Leo.  You took the time to read and reply. If I'm wrong,
correct me. I really don't mind, you know.

-larry

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------+ 
|   //   Larry Phillips                                          |
| \X/    lpami.wimsey.bc.ca!lphillips or van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                  |
+----------------------------------------------------------------+

jamiep@ncoast.UUCP (Jamie Purdon) (12/10/88)

Any screen with the "WBENCHSCREEN" bit set in the screen structure
is a "workbench" screen.  This is the way "multiple wbench screen"
hacks work.  So, so far as checking this bit, you were correct.
 
However, the 'screen list' does not start at YOUR screen.  If there
are screens behind yours then, yes, the 1st longword in your
screen struct will be a link to another screen.  *The* place
to begin scanning the screen structs is at
  IntuitionBase->FirstScreen
 
Unless you're simply checking if you're the "upfront" screen,
you should probably forbid/permit around any "screen structure walking".
 

(finishing DIGIpaint2....;-)

lphillips@lpami.van-bc.UUCP (Larry Phillips) (12/12/88)

> Any screen with the "WBENCHSCREEN" bit set in the screen structure
> is a "workbench" screen.  This is the way "multiple wbench screen"
> hacks work.  So, so far as checking this bit, you were correct.

Ahh... _information at last! I appreciate it Jamie. I never thought
about multiple WorkBench screens.

> However, the 'screen list' does not start at YOUR screen.  If there
> are screens behind yours then, yes, the 1st longword in your
> screen struct will be a link to another screen.  *The* place
> to begin scanning the screen structs is at
>   IntuitionBase->FirstScreen

Gotcha. I did specify IntuitionBase, FirstScreen, Flags though. Is there
a way to find the first, default, WorkBench screen as opposed to any
that have been added later?

Thanks again.

-larry

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (12/12/88)

In article <13231@ncoast.UUCP> jamiep@ncoast.UUCP (Jamie Purdon) writes:
>*The* place to begin scanning the screen structs is at
>  IntuitionBase->FirstScreen
> 
>Unless you're simply checking if you're the "upfront" screen,
>you should probably forbid/permit around any "screen structure walking".
> 
>(finishing DIGIpaint2....;-)

	If you're working on DigiPaintII, then you should be aware that
using Forbid/Permit is not *neccesarily* the correct way to inspect public
system structures.  I noticed GrabANIM doing the same thing with
IntuitionBase, and a big bell went off in my head (JimM's words can be
pretty infectious, you know...).

	The correct way to look at IntuitionBase is to first call
LockIBase().  This keeps Intuition from fooling with IntuitionBase while
you're looking at it.  You may think Forbid() does this, but if Intuition
just happens to be in the middle of a modification when it gets switched
out in time for you to say Forbid(), then IntuitionBase is in an
inconsistent state, and you could get propelled into The Twilight Zone.

	The Exec memory free list is arbitrated with Forbid/Permit (isn't
it?).  IntuitionBase is arbitrated with LockIBase/UnlockIBase().  If you
don't use the right locking mechanism, your program will lose one day.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
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

john13@garfield.MUN.EDU (John Russell) (12/14/88)

In article <7907@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>
>	If you're working on DigiPaintII, then you should be aware that
>using Forbid/Permit is not *neccesarily* the correct way to inspect public
>system structures.  I noticed GrabANIM doing the same thing with
>IntuitionBase, and a big bell went off in my head (JimM's words can be
>pretty infectious, you know...).
>
>	The correct way to look at IntuitionBase is to first call
>LockIBase().  

Now I've heard that too, but I've never seen a decent explanation of its
side-effects that would allow me to make any sort of safe use of it.
Incidentally, the same is true of GetScreenData until Chuck McManis's
article a few days ago. I notice the parameter to LockIBase in the 1.3
fd files is listed as "don't know".

Almost every time I've wanted to do something Intuition-related and
used LockIBase I've run into complete system freezeups. Forbid, which
does something similar, has done this on occasion but always it was
possible to track down the cause to something in my code and fix it.

For instance, let's say I want to...

locate window in system list (IntuitionBase->FirstWindow, etc).
ActivateWindow it
wait until it becomes active
twiddle it

For maximum safety it seems like all this should be a critical section:
the window list could be corrupted while I'm scanning it, and anytime
after I find it until I finish twiddling it the task which owns it might
close it.

If I use Lock/UnlockIBas around it, I know the ActivateWindow will cause
total lockup due to its asynchronous nature (I guess the input handler
gets stuck trying to modify IntuitionBase?). I'm pretty sure most of the
other twiddles I'd like to do will also run into the same problem. If
memory serves me correctly I've had lockups due to _other_ programs
popping up "insert disk" requesters or DMouse/WKeys et al doing layer
operations while trying out code that Locked IBase.

Forbid may give you less of a guarantee that the system will not be in an
inconsistent state, but what is the proper way to do anything more than a
trivial operation (say flipping a pointer) with LockIBase? Unlike many of
the other points on the Amiga learning curve (device io, superbitmap
manipulation, wb arg parsing) there don't seem to be any useful sources
that deal with it.

That might be a point to consider when adding new functions to 1.4 -- a
programmer's sample disk showing how to _properly_ use all the new goodies,
such as there were in the early days when every feature or function call
was an unknown quantity.

John
-- 
"The sinuous roots meshed together... the sun-dappled leaves... the arching
 branches... and put it all together? Nothing! Icky, icky tree!"
		    -- something like that anyway; from "The Kids in the Hall"

jesup@cbmvax.UUCP (Randell Jesup) (12/15/88)

In article <5034@garfield.MUN.EDU> john13@garfield.UUCP (John Russell) writes:
>In article <7907@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>>	The correct way to look at IntuitionBase is to first call
>>LockIBase().  

>Almost every time I've wanted to do something Intuition-related and
>used LockIBase I've run into complete system freezeups. Forbid, which
>does something similar, has done this on occasion but always it was
>possible to track down the cause to something in my code and fix it.
>
>For instance, let's say I want to...
>
>locate window in system list (IntuitionBase->FirstWindow, etc).
>ActivateWindow it
>wait until it becomes active
>twiddle it
>
>For maximum safety it seems like all this should be a critical section:
>the window list could be corrupted while I'm scanning it, and anytime
>after I find it until I finish twiddling it the task which owns it might
>close it.

	Well, you're right that that operation is something you'ld like to
be critical, but it can't be right now.  The reason is that your call to
Intuition, ActivateWindow, is (a) deferred and put on a queue for intuition
to do later, and (b) requires intuition, running as input.device, to be
able to LockIBase itself.  Since you left it locked, it goes into a wait
which it never comes out of.

	Solution: UnlockIBase after ActivateWindow.  If it isn't your window,
you can't easily get notified that it's active (without evil magic with
IDCMP), so you should Delay() a bit, LockIBase, check if the window (a)
still exists, and (b) is now active, and if so then do your magic, else
go and Delay again.  Yes, this is polling, but you're trying to do a fairly
evil thing to someone else's window, so the system won't help you much.
Make sure you use the Delay()s, they'll reduce the load.  Also note that some
other program or the user might make the window inactive before you notice
it's active, so think about it.

>Forbid may give you less of a guarantee that the system will not be in an
>inconsistent state, but what is the proper way to do anything more than a
>trivial operation (say flipping a pointer) with LockIBase? Unlike many of
>the other points on the Amiga learning curve (device io, superbitmap
>manipulation, wb arg parsing) there don't seem to be any useful sources
>that deal with it.

	Mainly because the operations you want to do aren't in general
supported operations.  Some of the types of things you want to do will be
in 1.4, but not at the window level, only screens.  Jimm, want to comment?

-- 
You've heard of CATS? Well, I'm a member of DOGS: Developers Of Great Software.
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

jimm@amiga.UUCP (Jim Mackraz) (12/20/88)

--

I thought it was pretty well explained what LockIBase() is and is not for.

It is for protecting your walking down the linked lists in the PUBLIC part
of IntuitionBase.

Hostile functions, such as calling ActivateWindow on a window which is not
your own (and which you cannot assure is going to stay open) is NOT part of
the job of LockIBase().

It turns out that ActivateWindow() is safe: if the window disappears, the
system will not crash.  But clearly, we have to make stronger position statements
on what "hostile" Intuition activity is proper (such as sizing somebody else's
window).  We'll address this as we can in V1.4.  The general theme will be
that we will try to make all functions you might want to "impose" on somebody's
window as safe as possible.  We'll provide easier ways to do the trickier
functions, like popping a window to full size.  Interim hacks, such as my
own IHelp, are iffy at best, and can be replaced after V1.4 with solid, supportable
programs.  The keyword here is "supportable."

Many of the things one might do while hacking Intuition stuff is NOT safe
under Forbid, because it can be deferred, and because it can block: either for
the Blitter or for lower level internal semaphores.

Let me make it very clear:  Only Intuition has any business performing
critical operations on Intuition data structures: LockIBase() is provided for
you to EXAMINE a select few linked lists which Intuition might want to
modify, if there were no arbitration.  (It turns out that the only public list
is the screen chain, based on FirstScreen).

Make ZERO Intuition function calls while LockIBase() is in effect.

The FD file is not the documentation.  The documentation is in the AutoDocs
and the Enhancer manual.  You pass LockIBase() a zero, and you pass UnlockIBase
whatever LockIBase() returned.

GetScreenData() is also well-documented as being a copy of the workbench screen,
and the caveat is that pointers found therein cannot be assumed to be valid
(since the workbench screen may close at any time).  In V1.4, this will
be made obsolete by a more general function to actually get a lock on a
screen itself, insuring that it is not closed, and you would then be allowed to
look indirect at data pointed to by the screen structure.

Don't give bad advice, folks, please.

I fully sympathize with the call for better examples of difficult functions
in the future.  We'll try to accomodate.  In the meantime, read the documents
we have out there.  Don't assume that Intution is a wonderful asynchronous
toolkit which you can run around in and munge.

	jimm

PS: And in case you haven't heard, programs using the private part of IntuitionBase
will neither compile nor work under V1.4.  Sympathy in this area will be very
hard to get out from me.

-- 
	Jim Mackraz, I and I Computing	  
	amiga!jimm	BIX:jmackraz
Opinions are my own.  Comments regarding the Amiga operating system, and
all others, are not to be taken as Commodore official policy.

bartonr@psu-cs.UUCP (Robert Barton) (02/12/89)

  Article 3813 From: shimoda@infohh.rmi.de (Markus Schmidt) :
> I remember Leo, flaming about someone Getting a pointer to
> Workbench-Screen, since WB-Screen might disappear due to CloseWBench().
> Now, I need such a Pointer too. If I open a Window (small, 2 by 2 pix)
> then, get the Pointer to WBench (by serarching a LockIBase()'d Screen-
> List), is there anything else that could make me meditating (except
> reading my taoistic books)?
   
  If you've already opened a window on the Workbench screen, you don't
need to LockIBase() and search the screen list, just use window->WScreen.
As long as your window stays open CloseWorkBench() won't be able to close
the screen.
  By the way, notice that CloseWorkBench() will now return FALSE if the
screen was already closed, contrary to what it says in the Intuition
manual and the RKM.