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