From: grobbins@Apple.COM (Grobbins)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Moving the mouse pointer-- how?
Date: 6 Oct 92 19:54:56 GMT
Organization: Apple Computer Inc., Cupertino, CA

In article <1992Oct6.002846.10641@acuson.com> brianc@acuson.com (Brian Cox) writes:
>jkreibic@sumter.cso.uiuc.edu (Jay Arnold Kreibich) writes:
>>  I am writing a driver program that needs to move the mouse cursor  
>>location around the screen, but I'm not quite sure how to do that.  Any  
>>tips on where to lookup functions that will assign a new mouse pointer  
>>location?
>
>Without getting in to the subjective merits of doing so, I'll just
>mention that Apple strongly discourages moving the mouse sprite
>without an analogous action from the user.  They discourage it to
>the extent that they don't provide a routine that does it.

While programmatic control of the mouse is discouraged, the
steps necessary are documented by DTS.  Pasted below are two of
several entries from the Q&A Stack on mouse movement.


Grobbins         grobbins@apple.com

---

from the Q&A Stack (available in the dts area of ftp.apple.com):


I'm writing a tablet (mouse, pointer, etc.) driver, and I need to be able to
position the cursor and post mouseUp mouseDown events. How do I do it?

Here is an explanation of the Macintosh@ mouse/cursor mechanism, which
should provide the information necessary for you to place the cursor:

The mouse is a "relative" device, which means it does not return actual
coordinates; it returns a "count" or amount of movement since the last
report.

When the mouse has new information, it interrupts the Macintosh. The
interrupt handler adds the horizontal and vertical counts to MTemp (a
low-memory location), and sets crsrNew to tell the system that the
coordinates are new. Some time later (but before normal VBLs are executed)
the cursor VBL task is executed, and it compares MTemp with RawMouse (which
has the last value), and figures out the delta (that is, the horizontal and
vertical distance moved), and does the scaling trick depending on what the
user has selected in the control panel. It also updates MTemp to reflect the
new value. Then it draws the cursor.

Here are the names and locations of the relevant low-memory locations:


    RawMouse          equ $82C               ;point
    MTemp             equ $828               ;point
    CrsrNew           equ $8CE               ;byte
    CrsrCouple        equ $8CF               ;byte


(NOTE: These may change in future CPUs.)

If you wish to place the cursor in an absolute location on the screen, you
must set RawMouse, and MTemp to the same value, and set CrsrNew to the same
value as CrsrCouple.

Keep in mind that moving the cursor from an application may violate the
Human Interface Guidelines, possibly confusing and frustrating the user.
Also keep in mind that the low-memory locations named above are not
documented, and as such, are considered unsupported and volatile.

Posting mouse down/up events is a simple matter of keeping track of the last
state of your device button, and when you detect a change, you post the
appropriate event. If you wish to support the ToolBox Event Manager call
Button, you must also update the low-memory global MBState. The high bit of
MBState reflects the current state of the mouse button: 1 = button up, 0 =
button down.

Unfortunately, the system mouse driver will change this value if it notices
that the state of MBState is different from the state of the real mouse
button. This means if there is a mouse connected to the Macintosh while your
device is connected, it will override whatever you put in MBState. On
systems equipped with ADB, this will happen only when the mouse moves, or
the button is pressed. On earlier systems this happens all the time, since
the button checking routine was a VBL task, and is always executed. One
possible workaround is to patch Button, and return the state of your button,
rather than MBState. The obvious problem is that you disable the real mouse
from working with Button.


----


How can I programmatically move the Macintosh@ mouse without the real mouse
interfering?

The real answer to your question is twofold: First, you can do exactly what
you want to do with the sample included below. HOWEVER, this is not a good
thing to do, it would be better if you took the solution used in Apple's
Guided Tour disks: Always hide the cursor and then decouple the cursor from
the mouse. Then, instead of using the system's cursor, simply draw your own
"cursor" using QuickDraw and treat it as a little animated bitmap on the
screen. This avoids all the problems that you have with the mouse competing.
(Apple does update the mouse globals with the mouse position so that other
things function correctly.)

Now, as promised, here is the way to do what you want using the real cursor.
As you have discovered, setting the crsrCouple variable to false prohibits
the mouse from affecting the cursor; unfortunately, it also prohibits the
jcrsrTask routine from drawing the cursor. The solution to this is to set
crsr couple to true, call the cursor drawing routine jCrsrTask yourself, and
then set the crsrCouple variable to false, as shown below:


procedure callcrsr;
              inline $2078 ,$08EE ,$4E90;
{            move.L    jcrsrTask,A0
            jsr    (A0)                            }

Procedure FudgeMouse;

type    PointPtr=^Point;

var        RawMouse:PointPtr;
        MTemp:PointPtr;
        RandPt:Point;
        CrsrNew:ptr;
        CrsrCouple:ptr;
        fred:Longint;
       
begin
        RawMouse:=PointPtr($82C);
        MTemp:=PointPtr($828);
        CrsrNew:=ptr($8CE);
        CrsrCouple:=ptr($8CF);
        RandPt:=RawMouse^;
        repeat
            RandPt.h:=RandPt.h+1;
            RandPt.V:=RandPt.v+1;
            RawMouse^:=RandPt;
            MTemp^:=RandPt;
            CrsrNew^:=1;
            CrsrCouple^:=1;
            callCrsr;
            crsrCouple^:=0;
            repeat until fred<tickCount;
            fred:=tickCount+3;
        until Button;
        crsrCouple^:=1;
end;



Newsgroups: comp.sys.mac.programmer