executor/src/ctlMouse.c
2009-06-16 14:55:37 -06:00

238 lines
5.9 KiB
C

/* Copyright 1986-1995 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_ctlMouse[] =
"$Id: ctlMouse.c 74 2004-12-30 03:38:55Z ctm $";
#endif
/* Forward declarations in ControlMgr.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "WindowMgr.h"
#include "ControlMgr.h"
#include "EventMgr.h"
#include "ToolboxUtil.h"
#include "ToolboxEvent.h"
#include "OSEvent.h"
#include "ListMgr.h"
#include "rsys/ctl.h"
#include "rsys/wind.h"
#include "rsys/pstuff.h"
#include "rsys/stdfile.h"
#include "rsys/hook.h"
/*
* Loser suggests that controls are tested in the opposite order that
* they're on the linked list. That would make sense, since it would
* insure that when drawn under normal circumstances, the control that
* is visible and clicked is the one that will be FindControl will
* return. Recursion is you friend.
*/
INTEGER
find_control_helper (Point p, ControlHandle c,
HIDDEN_ControlHandle *cp)
{
INTEGER retval;
ControlHandle next;
if (!c)
retval = 0;
else
{
next = CTL_NEXT_CONTROL(c);
if (!(retval = find_control_helper(p, next, cp)))
{
if (CTL_VIS (c) && CTL_HILITE (c) != 255)
{
retval = TestControl (c, p);
if (retval)
cp->p = RM (c);
}
}
}
return retval;
}
P3(PUBLIC pascal trap, INTEGER, FindControl, Point, p, /* IMI-323 */
WindowPtr, w, HIDDEN_ControlHandle *, cp)
{
INTEGER retval;
retval = w ? find_control_helper(p, WINDOW_CONTROL_LIST(w), cp) : 0;
if (!retval)
cp->p = 0;
return retval;
}
typedef pascal void (*actionp)(ControlHandle c, INTEGER part);
A3(PRIVATE inline, void, CALLACTION, ControlHandle, ch, INTEGER, inpart,
ProcPtr, a)
{
ROMlib_hook(ctl_cdefnumber);
HOOKSAVEREGS();
if (a == (ProcPtr) P_ROMlib_mytrack)
C_ROMlib_mytrack(ch, inpart);
else if (a == (ProcPtr) P_ROMlib_stdftrack)
C_ROMlib_stdftrack(ch, inpart);
else
CToPascalCall(a, CTOP_ROMlib_mytrack, ch, inpart);
HOOKRESTOREREGS();
}
P3 (PUBLIC pascal trap, INTEGER, TrackControl, /* IMI-323 */
ControlHandle, c, Point, p, ProcPtr, a)
{
INTEGER partstart, inpart;
EventRecord ev;
thumbstr thumb;
RgnHandle rh;
LONGINT l;
Point whereunswapped;
int retval;
CTL_CALL_EXCURSION
(c,
{
partstart = inpart = TestControl(c, p);
/* Super-Dice-It hack: It appears that Super Dice It 1.1
calls TrackControl with p in Global coordinates. Without
this mod, we get hosed */
if (!partstart)
{
GetMouse (&p);
p.h = CW (p.h);
p.v = CW (p.v);
partstart = inpart = TestControl (c, p);
}
if (CTL_ACTION_AS_LONG (c) == -1L)
{
/* if we don't draw before/after, then jim's demo cdefs
don't update pop up menu bars */
CTLCALL (c, drawCntl, 0);
/* this is not how IMI says to do it, but it makes
Microsoft Word work. */
CTLCALL (c, autoTrack, inpart);
CTLCALL (c, drawCntl, 0);
/* NOTE 1: force a return of inpart */
partstart = inpart;
goto done;
}
if (a == (ProcPtr) -1L)
a = CTL_ACTION (c);
/* #if 0 reading the above code suggests that
it's impossible to get here */
if (0 && a == (ProcPtr) -1L)
{
/* totally custom */
while (!GetOSEvent(mUpMask, &ev))
{
GlobalToLocal(&ev.where);
whereunswapped.h = CW(ev.where.h);
whereunswapped.v = CW(ev.where.v);
inpart = TestControl(c, whereunswapped);
CTLCALL(c, autoTrack, inpart);
}
CTLCALL (c, posCntl, ( (((int32) whereunswapped.v - p.v) << 16)
| (uint16) (whereunswapped.h - p.h)));
inpart = TestControl(c, whereunswapped);
}
else
/* #endif */
if (partstart > 128)
{
/* indicator */
/* The code used to & the result of CTLCALL with 0xf000
for no apparent reason. Taking it out fixed a bug in
Quicken. */
if (!CTLCALL (c, dragCntl, partstart))
{
thumb._tlimit.left = CW(p.h);
thumb._tlimit.top = CW(p.v);
CTLCALL(c, thumbCntl, (LONGINT) (long) &thumb);
rh = NewRgn();
CTLCALL(c, calcThumbRgn, (LONGINT) (long) rh);
PATASSIGN(DragPattern, ltGray);
l = DragTheRgn(rh, p, &thumb._tlimit, &thumb._tslop,
CW(thumb._taxis), a);
if ((uint32) l != 0x80008000)
{
CTLCALL(c, posCntl, l);
inpart = partstart;
}
DisposeRgn(rh);
}
}
else
{
/* not an indicator */
HxX(c, contrlHilite) = partstart;
CTLCALL(c, drawCntl, partstart);
/* CALLACTION can remove mouse up events which is why the
following line is not a GetOSEvent call. */
while (!OSEventAvail(mUpMask, &ev) && StillDown())
{
GlobalToLocal(&ev.where);
whereunswapped.h = CW(ev.where.h);
whereunswapped.v = CW(ev.where.v);
inpart = TestControl(c, whereunswapped);
if (inpart && inpart != partstart)
inpart = 0;
if (inpart != U(HxX(c, contrlHilite)))
{
HxX(c, contrlHilite) = inpart;
CTLCALL(c, drawCntl, partstart);
}
if (a && inpart)
CALLACTION(c, inpart, a);
}
GetOSEvent(mUpMask, &ev);
GlobalToLocal(&ev.where);
whereunswapped.h = CW(ev.where.h);
whereunswapped.v = CW(ev.where.v);
if (HxX(c, contrlHilite))
{
HxX(c, contrlHilite) = 0;
CTLCALL(c, drawCntl, partstart);
}
inpart = TestControl(c, whereunswapped);
}
done:;
});
retval = (partstart == inpart ? inpart : 0); /* DON'T CHANGE THIS
line w/o looking to Note 1
above */
return retval;
}
P2(PUBLIC pascal trap, INTEGER, TestControl, /* IMI-325 */
ControlHandle, c, Point, p)
{
int16 retval;
CTL_CALL_EXCURSION
(c,
{
if (Hx(c, contrlVis) && U(Hx(c, contrlHilite)) != 255)
retval = CTLCALL(c, testCntl, ((LONGINT) p.v << 16) |
(unsigned short) p.h);
else
retval = 0;
});
return retval;
}