Implemented mouse relative mode on Mac OS X.
--- a/src/events/SDL_mouse.c Sun Feb 27 21:36:23 2011 -0800
+++ b/src/events/SDL_mouse.c Sun Feb 27 22:06:46 2011 -0800
@@ -308,8 +308,18 @@
{
SDL_Mouse *mouse = SDL_GetMouse();
- /* Flush pending mouse motion */
- SDL_FlushEvent(SDL_MOUSEMOTION);
+ if (enabled == mouse->relative_mode) {
+ return 0;
+ }
+
+ if (!mouse->SetRelativeMouseMode) {
+ SDL_Unsupported();
+ return -1;
+ }
+
+ if (mouse->SetRelativeMouseMode(enabled) < 0) {
+ return -1;
+ }
/* Set the relative mode */
mouse->relative_mode = enabled;
@@ -319,6 +329,9 @@
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
}
+ /* Flush pending mouse motion */
+ SDL_FlushEvent(SDL_MOUSEMOTION);
+
/* Update cursor visibility */
SDL_SetCursor(NULL);
--- a/src/events/SDL_mouse_c.h Sun Feb 27 21:36:23 2011 -0800
+++ b/src/events/SDL_mouse_c.h Sun Feb 27 22:06:46 2011 -0800
@@ -49,6 +49,9 @@
/* Warp the mouse to (x,y) */
void (*WarpMouse) (SDL_Window * window, int x, int y);
+ /* Set relative mode */
+ int (*SetRelativeMouseMode) (SDL_bool enabled);
+
/* Data common to all mice */
SDL_Window *focus;
int x;
--- a/src/video/cocoa/SDL_cocoamouse.m Sun Feb 27 21:36:23 2011 -0800
+++ b/src/video/cocoa/SDL_cocoamouse.m Sun Feb 27 22:06:46 2011 -0800
@@ -116,6 +116,23 @@
CGWarpMouseCursorPosition(point);
}
+static int
+Cocoa_SetRelativeMouseMode(SDL_bool enabled)
+{
+ CGError result;
+
+ if (enabled) {
+ result = CGAssociateMouseAndMouseCursorPosition(NO);
+ } else {
+ result = CGAssociateMouseAndMouseCursorPosition(YES);
+ }
+ if (result != kCGErrorSuccess) {
+ SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
+ return -1;
+ }
+ return 0;
+}
+
void
Cocoa_InitMouse(_THIS)
{
@@ -123,8 +140,9 @@
mouse->CreateCursor = Cocoa_CreateCursor;
mouse->ShowCursor = Cocoa_ShowCursor;
+ mouse->FreeCursor = Cocoa_FreeCursor;
mouse->WarpMouse = Cocoa_WarpMouse;
- mouse->FreeCursor = Cocoa_FreeCursor;
+ mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
}
@@ -147,7 +165,13 @@
void
Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
{
- /* We're correctly using views even in fullscreen mode now */
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (mouse->relative_mode && [event type] == NSMouseMoved) {
+ float x = [event deltaX];
+ float y = [event deltaY];
+ SDL_SendMouseMotion(mouse->focus, 1, (int)x, (int)y);
+ }
}
void
--- a/src/video/cocoa/SDL_cocoawindow.m Sun Feb 27 21:36:23 2011 -0800
+++ b/src/video/cocoa/SDL_cocoawindow.m Sun Feb 27 22:06:46 2011 -0800
@@ -302,15 +302,14 @@
- (void)mouseMoved:(NSEvent *)theEvent
{
+ SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *window = _data->window;
NSPoint point;
int x, y;
-#ifdef RELATIVE_MOTION
- if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
+ if (mouse->relative_mode) {
return;
}
-#endif
point = [theEvent locationInWindow];
x = (int)point.x;
@@ -861,19 +860,6 @@
void
Cocoa_SetWindowGrab(_THIS, SDL_Window * window)
{
-#ifdef RELATIVE_MOTION
- /* FIXME: work in progress
- You set relative mode by using the following code in conjunction with
- CGDisplayHideCursor(kCGDirectMainDisplay) and
- CGDisplayShowCursor(kCGDirectMainDisplay)
- */
- if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
- (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
- CGAssociateMouseAndMouseCursorPosition(NO);
- } else {
- CGAssociateMouseAndMouseCursorPosition(YES);
- }
-#else
/* Move the cursor to the nearest point in the window */
if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
@@ -885,7 +871,6 @@
cgpoint.y = window->y + y;
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
}
-#endif
}
void
--- a/test/common.c Sun Feb 27 21:36:23 2011 -0800
+++ b/test/common.c Sun Feb 27 22:06:46 2011 -0800
@@ -812,7 +812,7 @@
{
if (event->type == SDL_MOUSEMOTION) {
/* Mouse motion is really spammy */
- return;
+ //return;
}
fprintf(stderr, "SDL EVENT: ");
@@ -1044,6 +1044,12 @@
}
}
break;
+ case SDLK_r:
+ if (event->key.keysym.mod & KMOD_CTRL) {
+ /* Ctrl-R toggle mouse relative mode */
+ SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode());
+ }
+ break;
case SDLK_z:
if (event->key.keysym.mod & KMOD_CTRL) {
/* Ctrl-Z minimize */