tlm@pur-phy (Timothy Lee Meisenheimer) (01/28/89)
Well, I'm working on a little project which will have lots of little windows around (1 - X where X is related to how obnoxious you're feeling) and I'll be getting inputs (mouseclicks, gadgets, kill etc.) from them all. What I would like to ask is for those of you who have done something like this (like "Browser") what have you done in your event loop to read all these messages and tell which window they come from? I haven't seen any good examples yet (though I'm going to check out what Matt does in DME), and would appreciate any advice from those wiser than myself. Would you suggest looking at all the UserPorts? Replacing all the UserPorts with that of the first one? (that sounds fishy!) Thanks for any help. tim.
peter@sugar.uu.net (Peter da Silva) (01/29/89)
Browser 1.2 and 1.3 just opened an IDCMP for each window, and had a loop like this: while(1) { Wait(sigmask); /* sigmask is OR of all ports' sigbits */ for(each window, w) { while(msg = GetMsg(w->UserPort->mp_SigBits)) { copymsg = *msg; /* structure copy */ ReplyMsg(msg); switch(copymsg.Class) { ... } } } } Browser 1.4 and 1.5 had one IDCMP shared between all the windows, and used CLoseWindowSafely(). Unfortunately, it wasn't safe. So 1.6 has gone back to one IDCMP per window. -- Peter "Have you hugged your wolf today" da Silva `-_-' Hackercorp. ...texbell!sugar!peter, or peter@sugar.uu.net 'U`
cunniff@hpfcdc.HP.COM (Ross Cunniff) (01/29/89)
In article <1918@pur-phy> tlm@pur-phy (Timothy Lee Meisenheimer) writes: > Well, I'm working on a little project which will have lots of little > windows around (1 - X where X is related to how obnoxious you're feeling) > and I'll be getting inputs (mouseclicks, gadgets, kill etc.) from them > all... > ...what have you done in your event loop to read > all these messages and tell which window they come from? Well, probably the best thing is to share the same IDCMP port between all your windows. To do this, first get an IDCMP (from the first OpenWindow will do nicely). When you open subsequent windows, don't specify ANY IDCMP events in the NewWindow structure. Instead, do the following: Win = OpenWindow( &NewWin ); Win->UserPort = OrigWin->UserPort; ModifyIDCMP( Win, MOUSEBUTTONS|MOUSEMOVE|... (whatever) ); You now are sharing the same IDCMP between OrigWin and Win. You can tell which window an event came from by examining the Msg->IDCMPWindow field. BE CAREFUL, however, when you close Win. You will have to do something like the following, or you may get gurus: ILock = LockIBase( 0 ); while( Msg = GetMsg( Win->UserPort ) ) { ReplyMsg( Msg ); } Win->UserPort = NULL; CloseWindow( Win ); UnlockIBase( ILock ); (Your mileage on actual code may vary. Amiga Wizards???) Ross Cunniff Hewlett-Packard Colorado Languages Lab ...{ucbvax,hplabs}!hpfcrt!cunniff cunniff%hpfcrt@hplabs.ARPA
jimm@amiga.UUCP (Jim Mackraz) (01/30/89)
In article <3358@sugar.uu.net> peter@sugar.uu.net (Peter da Silva) writes:
)Browser 1.4 and 1.5 had one IDCMP shared between all the windows, and used
)CLoseWindowSafely(). Unfortunately, it wasn't safe. So 1.6 has gone back to
)one IDCMP per window.
Lots and lots of programs use a single port for multiple windows, using
CloseWindowSafely() and the protocol described in the V1.2 Intuition Enhancer
document. There is a field in the IntuiMessage to identify the window
to which the message pertains.
If there are problems, let them be known. If you think the problems might
have been your own or you don't understand what was going on, don't post
to the contrary. Please be specific or don't bother answering. The original
poster would now think that ports cannot be shared, when indeed they can and
are for many programs, including the Workbench.
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.
jesup@cbmvax.UUCP (Randell Jesup) (01/30/89)
In article <3358@sugar.uu.net> peter@sugar.uu.net (Peter da Silva) writes: > while(msg = GetMsg(w->UserPort->mp_SigBits)) { Now Peter, you know better than that! :-) ^^^^^^^^^^ >Browser 1.4 and 1.5 had one IDCMP shared between all the windows, and used >CLoseWindowSafely(). Unfortunately, it wasn't safe. So 1.6 has gone back to >one IDCMP per window. What was unsafe about it? -- Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup
peter@sugar.uu.net (Peter da Silva) (01/30/89)
In article <5844@cbmvax.UUCP>, jesup@cbmvax.UUCP (Randell Jesup) writes: > In article <3358@sugar.uu.net> peter@sugar.uu.net (Peter da Silva) writes: > > while(msg = GetMsg(w->UserPort->mp_SigBits)) { > Now Peter, you know better than that! :-) ^^^^^^^^^^ Yeh, what a bozo. "while(msg = GetMsg(w->UserPort))..." > >Browser 1.4 and 1.5 had one IDCMP shared between all the windows, and used > >CLoseWindowSafely(). Unfortunately, it wasn't safe. So 1.6 has gone back to > >one IDCMP per window. > What was unsafe about it? I don't know, but under heavy use I got Gurus. -- Peter "Have you hugged your wolf today" da Silva `-_-' Hackercorp. ...texbell!sugar!peter, or peter@sugar.uu.net 'U`
peter@sugar.uu.net (Peter da Silva) (01/30/89)
In article <3290@amiga.UUCP>, jimm@amiga.UUCP (Jim Mackraz) writes: > If there are problems, let them be known. If you think the problems might > have been your own or you don't understand what was going on, don't post > to the contrary. Please be specific or don't bother answering. The original > poster would now think that ports cannot be shared, when indeed they can and > are for many programs, including the Workbench. Well, when I use Browser I open and close windows a lot faster, and with more pending messages, than just about any other program that I can think of. And I found that very rarely Browser would guru on closing a window. I tried tracing it under SDB, but it seemed timing dependent. It never happened under SDB. It was definitely Browser doing it... and it wasn't any obvious booboos like replying to messages from a closed window. I eventually gave up on it because I wanted to get 1.6 out. I'll probably try again at a later date. I asked about it on this group when I had the problems, without any useful responses (got half a dozen copies of CloseWindowSafely. Thanks, folks). Anyway, while it's possible to share IDCMPs it's certainly not easy. You have to be VERY careful... when I figure out just how careful I'll be sure to let you know. I suspect there are programs out there with the same problems I had that just haven't been exersized enough (how often do you close windows? How about 6 at once with pending mouse clicks and resize messages?). -- Peter "Have you hugged your wolf today" da Silva `-_-' Hackercorp. ...texbell!sugar!peter, or peter@sugar.uu.net 'U`
billk@pnet01.cts.com (Bill W. Kelly) (01/30/89)
cunniff@hpfcdc.HP.COM (Ross Cunniff) writes: >In article <1918@pur-phy> tlm@pur-phy (Timothy Lee Meisenheimer) writes: >> Well, I'm working on a little project which will have lots of little >> windows around (1 - X where X is related to how obnoxious you're feeling) >> and I'll be getting inputs (mouseclicks, gadgets, kill etc.) from them >> all... >> ...what have you done in your event loop to read >> all these messages and tell which window they come from? > >Well, probably the best thing is to share the same IDCMP port between >all your windows. To do this, first get an IDCMP (from the first OpenWindow >will do nicely). When you open subsequent windows, don't specify ANY >IDCMP events in the NewWindow structure. Instead, do the following: > > Win = OpenWindow( &NewWin ); > Win->UserPort = OrigWin->UserPort; > ModifyIDCMP( Win, MOUSEBUTTONS|MOUSEMOVE|... (whatever) ); > [rest of message and sample code for closing window deleted] Ok, I give up. What's the _probem_ with allowing these poor little windows to each have their own IDCMP's? It doesn't seem as though it would require more code for each window to have its own IDCMP -- in fact, it seems like a much simpler/safer way to go than the alternative. Am I missing something? bill -- Bill W. Kelly billk@pnet01.cts.com {nosc ucsd hplabs!hp-sdd}!crash!pnet01!billk crash!pnet01!billk@nosc.mil
aaron@madnix.UUCP (Aaron Avery) (01/30/89)
In article <1918@pur-phy> tlm@newton.physics.purdue.edu.UUCP (Timothy Lee Meisenheimer) writes: >you suggest looking at all the UserPorts? Replacing all the UserPorts with >that of the first one? (that sounds fishy!) Thanks for any help. Well, that may sound fishy, but it's what the manual says to do and what works. Well, a variant anyway. What you want to do is to only define any IDCMPFlags in one of the windows before you open it. This window will then have a UserPort allocated for it. Now, after you open other windows with IDCMPFlags set to NULL, you set their UserPort variables to the one allocated for the first window. Now, call ModifyIDCMP() on those windows, saying which flags you want them to respond to. Now, all IDCMP messages for all windows will come in to that one UserPort. The IntuiMessage structure you are passed contains a pointer to which window the message pertains to (IDCMPWindow, a pointer to its Window structure). Later, when you go to close the windows, set all but one of the UserPort's to NULL before closing them. I'd suggest calling ModifyIDCMP() and clearing all flags before putting NULL in the UserPort. That's probably safest, but wasn't mentioned in my manual. Also note that you could just as well allocate your own message port and use that one, not having Intuition allocate even that one. If the IDCMPFlags variable is NULL when you call OpenWindow(), Intuition won't allocate a port. If the IDCMPFlags variable is non-NULL when you call ModifyIDCMP(), intuition won't allocate a port. That's how we controlled the port's allocation above. -- Aaron Avery, ASDG Inc. "A mime is a terrible thing to waste." -- Robin Williams ARPA: madnix!aaron@cs.wisc.edu {uunet|ncoast}!marque! UUCP: {harvard|rutgers|ucbvax}!uwvax!astroatc!nicmad!madnix!aaron
phil@titan.rice.edu (William LeFebvre) (01/31/89)
In article <3778@crash.cts.com> billk@pnet01.cts.com (Bill W. Kelly) writes: >What's the _probem_ with allowing these poor little windows to each have their >own IDCMP's? >... >Am I missing something? This is my thinking (and it might be wrong---I'm not sure). Separate IDCMPs means separate message ports. Separate ports means separate signal bits. And you can only have 32 sigbits, right (only 32 bits in a long)? That would imply to me that you can have, at the most, 32 open windows in your task, if you use a separate IDCMP for each window. This leads to something for which I don't know the answer: are sigbits allocated on a per-task basis or do they need to be unique throughout the entire system? In other words, can two separate tasks both be using the same signal bit for two separate ports? Seems to me that it would just be too restrictive if they couldn't. William LeFebvre Department of Computer Science Rice University <phil@Rice.edu>
jesup@cbmvax.UUCP (Randell Jesup) (02/01/89)
In article <2509@kalliope.rice.edu> phil@Rice.edu (William LeFebvre) writes: >This is my thinking (and it might be wrong---I'm not sure). Separate >IDCMPs means separate message ports. Separate ports means separate signal >bits. And you can only have 32 sigbits, right (only 32 bits in a long)? >That would imply to me that you can have, at the most, 32 open windows in >your task, if you use a separate IDCMP for each window. Actually less, since a number of signals (like ^C-F, plus others) are pre-allocated to the system. >This leads to something for which I don't know the answer: are sigbits >allocated on a per-task basis or do they need to be unique throughout the >entire system? In other words, can two separate tasks both be using the >same signal bit for two separate ports? Seems to me that it would just be >too restrictive if they couldn't. Yes, signal allocations are on a per-task basis. -- Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup
shf@well.UUCP (Stuart H. Ferguson) (02/01/89)
+-- tlm@newton.physics.purdue.edu.UUCP (Timothy Lee Meisenheimer) writes: | Well, I'm working on a little project which will have lots of little | windows | [...] what have you done in your event loop to read | all these messages and tell which window they come from? I haven't seen | any good examples yet (though I'm going to check out what Matt does in Modeler 3D lets you open an unlimited number of windows, and I just let Intuition create a new UserPort for each one. Modeler just waits on the logical-or of the waitmask for each window. Works fine. One thing that caused me some trouble, however, is the fact that Intuition will start to re-use SigBit's once you've used them all. This means that two windows can share the same signal bit -- not a terrible problem, but something to be aware of so you don't assume that all signal bits are unique. I made this assumption initially and found that windows stopped working in stress-testing (multi-dozens of windows). It wasn't hard to fix. -- Stuart Ferguson (shf@well.UUCP) Action by HAVOC
shf@well.UUCP (Stuart H. Ferguson) (02/01/89)
+-- shf@well.UUCP (Stuart H. Ferguson) writes: | logical-or of the waitmask for each window. Works fine. ^^^^^^^ I meant "bitwise," obviously. The code Peter Da.S. posted looked like about what I do. -- Stuart Ferguson (shf@well.UUCP) Action by HAVOC
billk@pnet01.cts.com (Bill W. Kelly) (02/01/89)
phil@titan.rice.edu (William LeFebvre) writes: >In article <3778@crash.cts.com> billk@pnet01.cts.com (Bill W. Kelly) writes: >>What's the _probem_ with allowing these poor little windows to each have their >>own IDCMP's? >>... >>Am I missing something? > >This is my thinking (and it might be wrong---I'm not sure). Separate >IDCMPs means separate message ports. Separate ports means separate signal >bits. And you can only have 32 sigbits, right (only 32 bits in a long)? >That would imply to me that you can have, at the most, 32 open windows in >your task, if you use a separate IDCMP for each window. For some reason, that completely slipped my mind. (Someone else also reminded me of this via email.) Each task has 16 (sixteen) user sigbits available to it. The other 16 sigbits are reserved for system use. (For example, bits 12-15 are for ^C, ^D, ^E, and ^F. For instance if from the CLI you type: 'break 3 C', process number three gets signaled with bit 12 -- SIGBREAKF_CTRL_C.) >This leads to something for which I don't know the answer: are sigbits >allocated on a per-task basis or do they need to be unique throughout the >entire system? In other words, can two separate tasks both be using the >same signal bit for two separate ports? Seems to me that it would just be >too restrictive if they couldn't. Each task has its own set of sigbits. The signals you have allocated, are waiting for, and have received are kept track of in the tc_SigAlloc, tc_SigWait, and tc_SigRecvd fields of each task structure. (This is the structure you get the address of when you call FindTask(0).) -- Bill W. Kelly billk@pnet01.cts.com {nosc ucsd hplabs!hp-sdd}!crash!pnet01!billk crash!pnet01!billk@nosc.mil
aaron@madnix.UUCP (Aaron Avery) (02/01/89)
In article <2509@kalliope.rice.edu> phil@Rice.edu (William LeFebvre) writes:
)This is my thinking (and it might be wrong---I'm not sure). Separate
)IDCMPs means separate message ports. Separate ports means separate signal
)bits. And you can only have 32 sigbits, right (only 32 bits in a long)?
)That would imply to me that you can have, at the most, 32 open windows in
)your task, if you use a separate IDCMP for each window.
That's my impression of what the problem is. Also, it's worse than that. The
system pre-allocates 16 sigbits for you, so you only have 16 more to allocate
yourself.
)This leads to something for which I don't know the answer: are sigbits
)allocated on a per-task basis or do they need to be unique throughout the
)entire system? In other words, can two separate tasks both be using the
)same signal bit for two separate ports? Seems to me that it would just be
)too restrictive if they couldn't.
Yes, they're on a per-task basis. 32 signals for the whole system would be a
TAD restrictive!-)
--
Aaron Avery, ASDG Inc. "A mime is a terrible thing to waste."
-- Robin Williams
ARPA: madnix!aaron@cs.wisc.edu {uunet|ncoast}!marque!
UUCP: {harvard|rutgers|ucbvax}!uwvax!astroatc!nicmad!madnix!aaron
janhen@wn2.sci.kun.nl (Jan Hendrikx) (02/02/89)
In article <439@madnix.UUCP>, aaron@madnix.UUCP (Aaron Avery) writes: > structure). Later, when you go to close the windows, set all but one of the > UserPort's to NULL before closing them. I'd suggest calling ModifyIDCMP() > and clearing all flags before putting NULL in the UserPort. That's probably > safest, but wasn't mentioned in my manual. Noooo! If you have a non-NULL UserPort when you use ModifyIDCMP to clear all the flags, the port will be de-allocated. (Thats what the Intuition manual and autodocs say about it). So you must FIRST NULL out the userports on all windows but the last, and THEN use ModifyIDCMP to clear the flags. (This is safe to do for all By the way, the version of CloseWindowSafely() that I got here uses Forbit()/Permit() around its message Remove()ing loop. What I say on the net uses LockIBase()/UnLockIBase(). Is that sufficient for the purpose (of making sure no new IntuiMessages are PutMsg()ed to the port)? > Aaron Avery, ASDG Inc. "A mime is a terrible thing to waste." -Olaf Seibert (using Jan's account)
peter@sugar.uu.net (Peter da Silva) (02/02/89)
In article <10549@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes: > One thing that caused me some trouble, however, is the fact that Intuition > will start to re-use SigBit's once you've used them all. This is *terrible*! It should either only ever use one SigBit, or it should refuse to open windows once it's run out. I can't believe this... > I made this assumption initially and found that windows stopped working > in stress-testing (multi-dozens of windows). It wasn't hard to fix. Oh well, expect occasional oddnesses if you habitually use in excess of 24 windows in Browser. It may lock up if you open 30 windows and then close them all... my first bug fix for 1.7, I guess. -- Peter "Have you hugged your wolf today" da Silva `-_-' Hackercorp. ...texbell!sugar!peter, or peter@sugar.uu.net 'U`
dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (02/03/89)
Another solution to the signal-bit problem which I have yet to
try, but which also seems workable, is to just open up a lot of windows
w/ independant IDCMP ports.
But nobody ever said they had to have *different* signal bits!!
That's right, once you get the port back, simply modify SigBit
to some common signal bit and then FreeSignal() the one that came with the
port.
When you CloseWindow() a window, first replace SigBit with a newly
allocated one (which the workbench will immediately deallocate when it
deletes the port). I.E.:
Short MasterSigBit;
main()
{
short tmp;
MasterSigBit = AllocSignal(-1);
...
win = OpenWindow(&Nw);
tmp = win->UserPort->mp_SigBit;
win->UserPort->mp_SigBit = MasterSigBit;
FreeSignal(tmp);
...
win->UserPort->mp_SigBit = AllocSignal(-1);
CloseWindow(win);
}
Now, this isn't quite as nice as sharing a single IDCMP port because
you now have to poll all the active window's ports whenever you get a signal,
but neither do you have to screw around much either.
Note that a simple 'window cache' .. I.E. remembering the last window
that an IDCMP came from and checking that first .. will yield almost the same
efficiency as sharing an IDCMP port.
-Matt
shf@well.UUCP (Stuart H. Ferguson) (02/03/89)
+-- aaron@madnix.UUCP (Aaron Avery) writes: | In article <2509@kalliope.rice.edu> phil@Rice.edu (William LeFebvre) writes: | )bits. And you can only have 32 sigbits, right (only 32 bits in a long)? | )That would imply to me that you can have, at the most, 32 open windows in | )your task, if you use a separate IDCMP for each window. | That's my impression of what the problem is. Also, it's worse than that. The | system pre-allocates 16 sigbits for you, so you only have 16 more to allocate | yourself. In case no one caught it the first time through -- Intuition re-uses signal bits to create new IDCMP ports _once all the unique ones_ are used up. In other words, if you want to open 50 windows, fine, but the last 34 or so will use the same signal bit for incoming messages. As long as you allocate all the signals you need up front, you can open mass quantities of windows and Intuition will take care of its own. -- Stuart Ferguson (shf@well.UUCP) Action by HAVOC
shimoda@infohh.rmi.de (Markus Schmidt) (02/04/89)
>IDCMPs means separate message ports. Separate ports means separate signal >bits. And you can only have 32 sigbits, right (only 32 bits in a long)? >That would imply to me that you can have, at the most, 32 open windows in >your task, if you use a separate IDCMP for each window. > Not quite right. The OS reserves 16 Signals for internal use, so you only have 16 for yourself. Shimoda
jimm@amiga.UUCP (Jim Mackraz) (02/04/89)
In article <327@wn2.sci.kun.nl> janhen@wn2.sci.kun.nl (Jan Hendrikx) writes:
)By the way, the version of CloseWindowSafely() that I got here uses
)Forbit()/Permit() around its message Remove()ing loop. What I say on
)the net uses LockIBase()/UnLockIBase(). Is that sufficient for the
)purpose (of making sure no new IntuiMessages are PutMsg()ed to the
)port)?
It is very incorrect. Let me quote from the autodocs of LockIBase:
* Grabs Intuition internal semaphore so that caller may examine
* IntuitionBase safely.
This has nothing to do with messaging, nothing to do with millions of other
pretend uses of LockIBase(). We reserve the right to assume that uses of
LockIBase() are exactly as documented.
Apart from this, Olaf, your interpretation of ModifyIDCMP() was sound.
)-Olaf Seibert (using Jan's account)
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.