Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Implemented mouse relative mode on Mac OS X.
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Feb 28, 2011
1 parent 9ff304e commit 6c64eaf
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 22 deletions.
17 changes: 15 additions & 2 deletions src/events/SDL_mouse.c
Expand Up @@ -308,8 +308,18 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
{
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;
Expand All @@ -319,6 +329,9 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
}

/* Flush pending mouse motion */
SDL_FlushEvent(SDL_MOUSEMOTION);

/* Update cursor visibility */
SDL_SetCursor(NULL);

Expand Down
3 changes: 3 additions & 0 deletions src/events/SDL_mouse_c.h
Expand Up @@ -49,6 +49,9 @@ typedef struct
/* 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;
Expand Down
28 changes: 26 additions & 2 deletions src/video/cocoa/SDL_cocoamouse.m
Expand Up @@ -116,15 +116,33 @@
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)
{
SDL_Mouse *mouse = SDL_GetMouse();

mouse->CreateCursor = Cocoa_CreateCursor;
mouse->ShowCursor = Cocoa_ShowCursor;
mouse->WarpMouse = Cocoa_WarpMouse;
mouse->FreeCursor = Cocoa_FreeCursor;
mouse->WarpMouse = Cocoa_WarpMouse;
mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;

SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
}
Expand All @@ -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
Expand Down
19 changes: 2 additions & 17 deletions src/video/cocoa/SDL_cocoawindow.m
Expand Up @@ -302,15 +302,14 @@ - (void)mouseExited:(NSEvent *)theEvent

- (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;
Expand Down Expand Up @@ -861,19 +860,6 @@ - (void)rightMouseDown:(NSEvent *)theEvent
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)) {
Expand All @@ -885,7 +871,6 @@ - (void)rightMouseDown:(NSEvent *)theEvent
cgpoint.y = window->y + y;
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
}
#endif
}

void
Expand Down
8 changes: 7 additions & 1 deletion test/common.c
Expand Up @@ -812,7 +812,7 @@ PrintEvent(SDL_Event * event)
{
if (event->type == SDL_MOUSEMOTION) {
/* Mouse motion is really spammy */
return;
//return;
}

fprintf(stderr, "SDL EVENT: ");
Expand Down Expand Up @@ -1044,6 +1044,12 @@ CommonEvent(CommonState * state, SDL_Event * event, int *done)
}
}
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 */
Expand Down

0 comments on commit 6c64eaf

Please sign in to comment.