« PEBKAC | Main | Bit Rot »

And now, how to determine the mouse location as a CGPoint

There's a saying in regards to Mac OS X programming, and it's proven useful time and time again. "If it's getting too difficult, stop and back up. You're probably going about it all wrong." And, well, this is another one of those times. I've been working on a pet project, a user-level driver for a toy called Space Navigator (Long story there), and one of the parts to work on is emulating a mouse. Of course, that requires knowing the current mouse location, so that I can set a new location relative to it.

With the multi-OS and API heritage of Classic, Carbon, and Cocoa, there's quite a few ways to do this, but they have drawbacks. Since this was emulating an input device, CGEvent.h is used, to create events, adjust them, and post them. This calls for CGPoints, which are floating point values, and from the top left corner.

void GetGlobalMouse (Point * globalMouse); is outdated. It's supported in Carbon, but depreciated. Not only that, but Point uses integers.

OSStatus DSpGetMouse (Point *outGlobalPoint); is again outdated. It uses Display Sprockets, and again, Point.

OSStatus TrackMouseLocation (GrafPtr inPort, Point *outPt, MouseTrackingResult *outResult); is out of the question. No, it's not depreciated, but again with the Point. Not only that, but it blocks until a mousedown or mouseup. That simply won't do.

(NSPoint)[NSEvent mouseLocation]; is a lot closer. It's also floating points, and NSPointToCGPoint takes care of that. But there's one big problem; NSPoint measures from the bottom left corner; the y axis is flipped.

To fix the flip, you have to subtract that vertical value from ([[NSScreen mainScreen] frame]).size.height, which is quite a mouthful. Not only that, but it's quite a bit of work and CPU time for something that runs so many times. Sure, you could try to cache it, but then you have to watch out for when someone adds or removes a screen to the laptop, and it's all a big mess.

So. Stop. Back up a bit. We want to know the mouse's position for when we post an event. Wouldn't it be neat if it was already done for us?

CGEventRef ourEvent = CGEventCreate(NULL);
CGPoint ourLoc = CGEventGetLocation(ourEvent);
NSLog(@"Location? %f, %f", (float)ourLoc.x, (float)ourLoc.y);

Sure enough, it works! Just make sure to CFRelease after you're done.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on February 16, 2008 6:40 PM.

The previous post in this blog was PEBKAC.

The next post in this blog is Bit Rot.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.35