home *** CD-ROM | disk | FTP | other *** search
- /*
- * MoveMouse.c
- *
- * Based on code from Jon Wtte, Denis Pelli, Apple, and a timely suggestion
- * from Bo Lindbergh. This code checks to see if the Cursor Device Manager (CDM)
- * is present. If it is, it uses the CDM calls; otherwise, it directly jabs low memory,
- * in the traditional manner.
- *
- * Also included is glue for all of the CDM routines. On the PowerPC, the CDM glue is
- * currently (11/95) missing from InterfaceLib. Since InterfaceLib is a shared library, you can't
- * assume the glue will be present on a target machine. So this code includes
- * its own glue, the construction of which is thanks to a helpful suggestion from Bo Lindbergh.
- *
- * For documentation of the CDM, see Apple Tech Note "HW 01 - ADB (The Untold Story: Space Aliens
- * ate my mouse)".
- *
- * - Dan Sears (sears@netcom.com)
-
- * From Apple Developer Services:
- *
- * In the past, moving the cursor programatically on the Macintosh has
- * entailed the manipulation of low memory globals. This has worked for
- * all macs for quite some time. But with the advent of the power book
- * series and many 3rd party track balls, it has become apparent that the
- * low memory globals no longer contained adequate information for the
- * system to truly support all types of positioning devices. So, with the
- * new Centris CPU's, and CPU's from all lines after we are implementing a
- * new tool set that provides a much more comprehensive set of utilities
- * for dealing with the cursor location and mouse button state. We call
- * this new manager the Cursor Device Manager, and DTS will be documenting
- * it in a future tech not, but since many machines are now shipping that
- * do not use the traditional low memory globals to get the mouse location
- * and position the mouse, it is important to "leak" a little of the tech
- * note information early.
- *
- * First, the CDM (Cursor device manager) has its own trap ($AADB) and you
- * can determine if a machine supports the CDM by using the standard TrapAvailable
- * routine. (See inside mac for the source code to Trap
- * Available). Once you have determined that the CDM exists, you should
- * try not to use the low memory globals RawMouse and MTemp to get the
- * current cursor location, or set a new cursor location. Instead the CDM
- * provides 3 calls which you can use to get this info, the first is
- * CrsrDevNextDevice which will give you the next cursor device record in
- * the CDM list, if you pass it a NULL, it will give you the head of the
- * list. Once you have the first cursor device you can use it to get the
- * Cursor data record which contains the current cursor location in its
- * where field. You can set the current location with either the
- * CrsrDevMove (which moves relative to the current location) or the
- * CrsrDevMoveTo (which moves to an absolute location) routines.
- *
- * The following is some sample code which implement some generic routines
- * that work on all macintoshes. These routines are written not for speed
- * but for clarity, so if you are writing a device driver or time critical
- * code there are some things that you can do to speed up these routines,
- * like predetermine at the outset if the CDM exists, this way you
- * wouldn't have to check every time you want to use it, and getting the
- * cursor device only once and keeping the pointer to it around between
- * calls.
- *
- * HISTORY:
- * 8/94 dgp Downloaded from ftp://nada.kth.se/pub/hacks/mac-faq/MoveMouse.c
- * 10/94 dgp made minimal changes so that it would compile in CodeWarrior C. Untested.
- * 12/94 dgp updated for compatibility with Universal Header "CursorDevices.h". Untested.
- * 1/5/95 dgp updated for compatiblity with Universal Headers 2, in which
- * CursorDevices.h was extensively changed. Untested.
- * 6/26/95 dgp cosmetic changes. Still untested.
- * 11/10/95 cbs Added missing InterfaceLib glue
- 11/13/95 dgp renamed glue routines from "glueCallCursorDevice..." to "CallCursorDevice..."
- 11/13/95 dgp renamed glue routines from "glueCallCursorDevice..." to "CallCursorDevice..."
- */
-
- #if UNIVERSAL_HEADERS<2
- #error "Compiling this file requires a reasonably recent (1995 or later) copy of CursorDevices.h"
- #endif
- #ifndef __CURSORDEVICES__
- #include <CursorDevices.h>
- #endif
- #ifndef __TRAPS__
- // this is much quicker than looking for and reading the Traps.h header file.
- #define _CursorDeviceDispatch 0xAADB
- #define _Unimplemented 0xA89F
- // #include <Traps.h>
- #endif
-
- /*
- * Glue routines for the Cursor Device Manager
- */
- OSErr CallCursorDeviceMove(CursorDevicePtr ourDevice, long deltaX, long deltaY);
- OSErr CallCursorDeviceMoveTo(CursorDevicePtr ourDevice, long absX, long absY);
- OSErr CallCursorDeviceFlush(CursorDevicePtr ourDevice);
- OSErr CallCursorDeviceButtons(CursorDevicePtr ourDevice, short buttons);
- OSErr CallCursorDeviceButtonDown(CursorDevicePtr ourDevice);
- OSErr CallCursorDeviceButtonUp(CursorDevicePtr ourDevice);
- OSErr CallCursorDeviceButtonOp(CursorDevicePtr ourDevice, short buttonNumber, ButtonOpcode opcode, long data);
- OSErr CallCursorDeviceSetButtons(CursorDevicePtr ourDevice, short numberOfButtons);
- OSErr CallCursorDeviceSetAcceleration(CursorDevicePtr ourDevice, Fixed acceleration);
- OSErr CallCursorDeviceDoubleTime(CursorDevicePtr ourDevice, long durationTicks);
- OSErr CallCursorDeviceUnitsPerInch(CursorDevicePtr ourDevice, Fixed resolution);
- OSErr CallCursorDeviceNextDevice(CursorDevicePtr *ourDevice);
- OSErr CallCursorDeviceNewDevice(CursorDevicePtr *ourDevice);
- OSErr CallCursorDeviceDisposeDevice(CursorDevicePtr ourDevice);
-
- /*
- * Low memory globals for the mouse
- */
- #define xRawMouse 0x082C // low memory global that has current mouse loc
- #define xMTemp 0x0828 // low memory global that has current mouse loc
- #define xCrsrNew 0x08CE // set after you change mtemp and rawmouse
- #define xCrsrCouple 0x08CF // true if the cursor is tied to the mouse
-
- void GetMouseDevicePosition(Point *currentPoint);
- void SetMouseDevicePosition(Point newPoint);
- void SetMouseDevicePositionRel(Point newPoint);
- Boolean IsCDMAvailable(void);
-
- #if GENERATINGPOWERPC
- enum {
- glueUppCursorDeviceMoveProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (long))),
- glueUppCursorDeviceMoveToProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (long))),
- glueUppCursorDeviceFlushProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))),
- glueUppCursorDeviceButtonsProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (short))),
- glueUppCursorDeviceButtonDownProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))),
- glueUppCursorDeviceButtonUpProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))),
- glueUppCursorDeviceButtonOpProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (short))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (ButtonOpcode))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(4,SIZE_CODE(sizeof (long))),
- glueUppCursorDeviceSetButtonsProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (short))),
- glueUppCursorDeviceSetAccelerationProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (Fixed))),
- glueUppCursorDeviceDoubleTimeProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))),
- glueUppCursorDeviceUnitsPerInchProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (Fixed))),
- glueUppCursorDeviceNextDeviceProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr *))),
- glueUppCursorDeviceNewDeviceProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr *))),
- glueUppCursorDeviceDisposeDeviceProcInfo =
- kD0DispatchedPascalStackBased |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr)))
- };
- #endif
-
- #if !GENERATINGPOWERPC
- pascal void CallCursorTask(void)
- = {
- 0x2078,0x08EE, // MOVE.L jCrsrTask,A0
- 0x4E90 // JSR (A0)
- };
- #endif
-
- void
- GetMouseDevicePosition(
- Point *currentPoint)
- {
- CursorDevice *firstMouse;
- long delay;
-
- if (IsCDMAvailable()) {
- firstMouse = NULL; // start at head of cursor dev list
- CallCursorDeviceNextDevice(&firstMouse); // get the next cursor device
- Delay(1, &delay); // why is this necessary?! cbs
- *currentPoint = firstMouse->whichCursor->where;
- } else
- *currentPoint = *(Point *) xRawMouse; // use the low memory global
- }
-
- void
- SetMouseDevicePosition(
- Point newPoint)
- {
- CursorDevice *firstMouse;
-
- if (IsCDMAvailable()) {
- firstMouse = NULL;
- CallCursorDeviceNextDevice(&firstMouse);
- CallCursorDeviceMoveTo(firstMouse, (long) newPoint.h, (long) newPoint.v);
- } else {
- *(Point *) xRawMouse = newPoint;
- *(Point *) xMTemp = newPoint;
- *(Ptr) xCrsrNew = *(Ptr) xCrsrCouple; // Set CrsrNew if coupled
- #if !GENERATINGPOWERPC
- CallCursorTask(); // must call jCrsrTask to update system
- #endif
- }
- }
-
- void
- SetMouseDevicePositionRel(
- Point newPoint)
- {
- CursorDevice *firstMouse;
- Point tempPt;
-
- if (IsCDMAvailable()) {
- firstMouse = NULL;
- CallCursorDeviceNextDevice(&firstMouse);
- CallCursorDeviceMove(firstMouse, (long) newPoint.h, (long) newPoint.v);
- } else {
- tempPt = *(Point *) xRawMouse;
- tempPt.h += newPoint.h;
- tempPt.v += newPoint.v;
- *(Point *) xRawMouse = tempPt;
- *(Point *) xMTemp = tempPt;
- *(Ptr) xCrsrNew = *(Ptr) xCrsrCouple;
- #if !GENERATINGPOWERPC
- CallCursorTask();
- #endif
- }
- }
-
- Boolean IsCDMAvailable(void)
- {
- return NGetTrapAddress(_CursorDeviceDispatch, ToolTrap)
- != NGetTrapAddress(_Unimplemented, ToolTrap);
- }
-
- OSErr CallCursorDeviceMove(
- CursorDevicePtr ourDevice,
- long deltaX,
- long deltaY)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceMoveToProcInfo,
- 0, ourDevice, deltaX, deltaY);
- #else
- return CursorDeviceMove(ourDevice, deltaX, deltaY);
- #endif
- }
-
- OSErr
- CallCursorDeviceMoveTo(
- CursorDevicePtr ourDevice,
- long absX,
- long absY)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceMoveToProcInfo,
- 1, ourDevice, absX, absY);
- #else
- return CursorDeviceMoveTo(ourDevice, absX, absY);
- #endif
- }
-
- OSErr
- CallCursorDeviceFlush(
- CursorDevicePtr ourDevice)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceFlushProcInfo,
- 0x2, ourDevice);
- #else
- return CursorDeviceFlush(ourDevice);
- #endif
- }
-
- OSErr
- CallCursorDeviceButtons(
- CursorDevicePtr ourDevice,
- short buttons)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceButtonsProcInfo,
- 0x3, ourDevice, buttons);
- #else
- return CursorDeviceButtons(ourDevice, buttons);
- #endif
- }
-
- OSErr
- CallCursorDeviceButtonDown(
- CursorDevicePtr ourDevice)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceButtonDownProcInfo,
- 0x4, ourDevice);
- #else
- return CursorDeviceButtonDown(ourDevice);
- #endif
- }
-
- OSErr
- CallCursorDeviceButtonUp(
- CursorDevicePtr ourDevice)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceButtonUpProcInfo,
- 0x5, ourDevice);
- #else
- return CursorDeviceButtonUp(ourDevice);
- #endif
- }
-
- OSErr
- CallCursorDeviceButtonOp(
- CursorDevicePtr ourDevice,
- short buttonNumber,
- ButtonOpcode opcode,
- long data)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceButtonOpProcInfo,
- 0x6, ourDevice, buttonNumber, opcode, data);
- #else
- return CursorDeviceButtonOp(ourDevice, buttonNumber, opcode, data);
- #endif
- }
-
- OSErr
- CallCursorDeviceSetButtons(
- CursorDevicePtr ourDevice,
- short numberOfButtons)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceSetButtonsProcInfo,
- 0x7, ourDevice, numberOfButtons);
- #else
- return CursorDeviceSetButtons(ourDevice, numberOfButtons);
- #endif
- }
-
- OSErr
- CallCursorDeviceSetAcceleration(
- CursorDevicePtr ourDevice,
- Fixed acceleration)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceSetAccelerationProcInfo,
- 0x8, ourDevice, acceleration);
- #else
- return CursorDeviceSetAcceleration(ourDevice, acceleration);
- #endif
- }
-
- OSErr
- CallCursorDeviceDoubleTime(
- CursorDevicePtr ourDevice,
- long durationTicks)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceDoubleTimeProcInfo,
- 0x9, ourDevice, durationTicks);
- #else
- return CursorDeviceDoubleTime(ourDevice, durationTicks);
- #endif
- }
-
- OSErr
- CallCursorDeviceUnitsPerInch(
- CursorDevicePtr ourDevice,
- Fixed resolution)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceUnitsPerInchProcInfo,
- 0xA, ourDevice, resolution);
- #else
- return CursorDeviceUnitsPerInch(ourDevice, resolution);
- #endif
- }
-
- OSErr
- CallCursorDeviceNextDevice(
- CursorDevicePtr *ourDevice)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceNextDeviceProcInfo,
- 0xB, ourDevice);
- #else
- return CursorDeviceNextDevice(ourDevice);
- #endif
- }
-
- OSErr
- CallCursorDeviceNewDevice(
- CursorDevicePtr *ourDevice)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceNewDeviceProcInfo,
- 0xC, ourDevice);
- #else
- return CursorDeviceNewDevice(ourDevice);
- #endif
- }
-
- OSErr
- CallCursorDeviceDisposeDevice(
- CursorDevicePtr ourDevice)
- {
- #if GENERATINGPOWERPC
- return CallUniversalProc(
- GetToolboxTrapAddress(_CursorDeviceDispatch),
- glueUppCursorDeviceDisposeDeviceProcInfo,
- 0xD, ourDevice);
- #else
- return CursorDeviceDisposeDevice(ourDevice);
- #endif
- }