svermeulen@Janus.MRC.AdhocNet.CA (Steve Vermeulen) (01/20/89)
To All,
I have a question regarding windows and their IDCMP ports.
I am developing an application where I would like to share
access to a window among several independent programs.
Access to the window will be granted on an exclusive
basis, the recepient will do its thing and no one else
will access the window until the recepient has released
its control. Only the original creator of the window
will be closing the window.
As far as I can see the only potentially hazardous part
about doing this is associated with the IDCMP messages
and ports. Since the message ports must know which
task to signal when a message is arrived one cannot
just pass a window pointer to another task and then
have that task wait on the window's UserPort for
messages with a line like:
Wait(1L << w->UserPort->mp_SigBit);
What I have tried to do (and have been completely
successful at doing so far) is to have the recepient
task (the one that is being granted usage of an
already opened window) save the various window
message port pointers, NULL out these fields
and then do a ModifyIDCMP() to have a new message
port created for it. Before the recepient returns
control of the window to the window's owner (the
program that called OpenWindow() in the first place)
it calls ModifyIDCMP(w, NULL) to close its ports
and then restores the original pointers.
The actual code that I am using looks like this:
-------------------------------------------------------------------------
wind = (struct Window *) msg->Data[6];
rp = wind->RPort;
w = msg->Data[2];
h = msg->Data[3];
mode = rp->DrawMode;
oldpen = rp->FgPen;
/** now take over the window's IDCMP port
note the positioning of Forbid()/Permit()
is this secure enough?
**/
Forbid();
oldUP = wind->UserPort;
oldWP = wind->WindowPort;
oldIDCMP = wind->IDCMPFlags;
oldFlags = wind->Flags & REPORTMOUSE;
wind->UserPort = NULL;
wind->WindowPort = NULL;
wind->IDCMPFlags = NULL;
Permit();
/** the original owner of the window has already
removed its menus from the screen, so now we
attach our menus and set up our IDCMP port...
You can probably ignore most of the stuff in
the middle, its just a simple event response
loop that rubberbands a box on the window to
show that we really can get away with doing
this.
**/
SetMenuStrip(wind, &firstmenu);
ModifyIDCMP(wind, MOUSEBUTTONS | MOUSEMOVE | MENUPICK);
wind->Flags |= REPORTMOUSE;
SetDrMd(rp, COMPLEMENT);
/** now we go into the message processing loop, here we
look for select button downs and mouse moves
**/
qflag = TRUE;
pendown = FALSE;
while (qflag)
{
Wait(1L << wind->UserPort->mp_SigBit);
while (imess = (struct IntuiMessage *) GetMsg(wind->UserPort))
{
class = imess->Class;
code = imess->Code;
ReplyMsg(imess);
switch (class)
{
case MENUPICK:
switch (ITEMNUM(code))
{
case 3:
/** user wants to shut down this
**/
flag = TRUE;
case 2:
/** user wants to return to the window's owner
**/
qflag = FALSE;
break;
}
break;
case MOUSEMOVE:
if (pendown)
{
box(rp, x1, y1, x2, y2);
x2 = mx; y2 = my;
box(rp, x1, y1, x2, y2);
}
break;
case MOUSEBUTTONS:
switch (code)
{
case SELECTDOWN:
if (pendown)
{
/** currently rubberbanding so stop now!
**/
box(rp, x1, y1, x2, y2);
pendown = FALSE;
SetDrMd(rp, JAM1);
do_wizzy_stuff_in_box(rp, psx, psy, x1, y1, x2, y2);
SetDrMd(rp, COMPLEMENT);
}
else
{
x2 = x1 = mx;
y2 = y1 = my;
pendown = TRUE;
box(rp, x1, y1, x2, y2);
}
break;
}
break;
}
}
} /** end of message processing **/
if (pendown) box(rp, x1, y1, x2, y2); /** erase rubberband **/
SetDrMd(rp, (long) mode);
SetAPen(rp, (long) oldpen);
/** START READING HERE AGAIN
now restore the old IDCMP... We kill our port
and then restore the original ports...
**/
ModifyIDCMP(wind, NULL);
Forbid();
wind->UserPort = oldUP;
wind->WindowPort = oldWP;
wind->IDCMPFlags = oldIDCMP;
wind->Flags |= oldFlags;
Permit();
ClearMenuStrip(wind); /** this should probably be before
the ModifyIDCMP() line.
**/
--------------------------------------------------------------------------
So any thoughts on this? Is this kosher, or should I go give
myself 40 lashes with a wet floppy disk to attone for my sins?
Have I missed an obvious bug that will bite back when I least
expect it? ...
Stephen Vermeulen
Author: Express Paint
Newsletter Editor of AMUC
SVermeulen%Janus.MRC.AdhocNet.CA@Uncaedu.BITnet