From: sevigny@vlsi.polymtl.ca (Benoit Sevigny)
Subject: Catching RBUTTON before Intuition
Organization: Ecole Polytechnique de Montreal
Date: Tue, 13 Oct 1992 04:46:19 GMT

I am trying to implement a Workbench-like selection box (those rotating dashed
lines you see when you select a group of icons.

Using the following code, I get a deadlock if, during the selection, I hit the
right button before I release the left button.  This is because Intuition
seems to receive the event (and tries to draw the menus) before I receive
it.  Is there any way to avoid that behaviour if I really want to cancel the
selection (and hence to get out of the loop) if the user presses the right
button?


AreaObj::update(Window *, Gadget *, int cl, int, int x, int y)
{
	RastPort *rp = &(win->WScreen->RastPort);
	struct IntuiMessage *imsg;
	UWORD box[8];
	UWORD pat = 0xff00;
	UWORD tpat = 0x0101;
	ULONG Class = IDCMP_MOUSEMOVE;
	rect r;

	x += win->LeftEdge;
	y += win->TopEdge;
	box[0] = box[2] = box[4] = box[6] = x;
	box[1] = box[3] = box[5] = box[7] = y;

	switch(cl) {

	case IDCMP_MOUSEBUTTONS:

		LockLayerInfo(&(scr->LayerInfo));
		LockLayers(&(scr->LayerInfo));

		// setup for dashed line
		SetIDCMP(IDCMP_MOUSEMOVE | IDCMP_INTUITICKS);
		SetDrMd(rp, COMPLEMENT);
		SetDrPt(rp, pat);

		do {
			Wait(ALLMASK);

			while(imsg = GT_GetIMsg(Environment.intuiport)) {

				Class = imsg->Class;
				x = imsg->MouseX + win->LeftEdge;
				y = imsg->MouseY + win->TopEdge;
				GT_ReplyIMsg(imsg);

				if(pat != 0xffff) {

					switch(Class) {

					case IDCMP_INTUITICKS:

					        // draw the box only if its
					        // that big
						if(abs(box[2]-box[6]) > 4 ||
                                                   abs(box[3]-box[7]) > 4) {

							Move(rp,box[6],box[7]);
							PolyDraw(rp, 4, box);
						      
							// rotate the pattern
							pat = (pat & 0xf) ?
                                                            0xf000|(pat >> 4) :
                                                            (pat >> 4);
							SetDrPt(rp, pat);
							Move(rp,box[6],box[7]);
							PolyDraw(rp, 4, box);
						}
						break;

					case IDCMP_MOUSEMOVE:

						// clear the previous box if it
						// was that big
						if(abs(box[2]-box[6]) > 4 ||
                                                   abs(box[3]-box[7]) > 4) {

							Move(rp,box[6],box[7]);
							PolyDraw(rp, 4, box);
						}
						box[0] = box[2] = x;
						box[3] = box[5] = y;

						// draw the new box
						if(abs(box[2]-box[6]) > 4 ||
                                                   abs(box[3]-box[7]) > 4) {

							Move(rp,box[6],box[7]);
							PolyDraw(rp, 4, box);
						}
						break;

					case IDCMP_MOUSEBUTTONS:

// here I shouldn't receive only the left button events

						// clear the last box
						if(abs(box[2]-box[6]) > 4 ||
                                                   abs(box[3]-box[7]) > 4) {

							Move(rp,box[6],box[7]);
							PolyDraw(rp, 4, box);
						}

						// get out of the loop
						pat = 0xffff;
					}
				}
			}

		} while(pat != 0xffff);

		SetDrPt(rp, pat);
		SetDrMd(rp, 0);
		ClearIDCMP(IDCMP_MOUSEMOVE | IDCMP_INTUITICKS);

		r = rect(box[6], box[7], box[2]-box[6], box[5]-box[7]);

		UnlockLayers(&(scr->LayerInfo));
		UnlockLayerInfo(&(scr->LayerInfo));
	}

	return 0;
}

--
-=*                                                                         *=-
   __ Skipping every ?86 numbered lines in your code will remove all your
__/// remaining bugs and bottlenecks 8^)
\XX/  Benoit W Sevigny, software engineering student, sevigny@info.polymtl.ca
Xref: sparky comp.sys.amiga.advocacy:26299 comp.sys.mac.advocacy:1435