Implemented mouse relative mode on Mac OS X.
authorSam Lantinga
Sun, 27 Feb 2011 22:06:46 -0800
changeset 54061517da4ab6b1
parent 5405 64fa8526e1ce
child 5407 40c9d744e595
Implemented mouse relative mode on Mac OS X.
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/video/cocoa/SDL_cocoamouse.m
src/video/cocoa/SDL_cocoawindow.m
test/common.c
     1.1 --- a/src/events/SDL_mouse.c	Sun Feb 27 21:36:23 2011 -0800
     1.2 +++ b/src/events/SDL_mouse.c	Sun Feb 27 22:06:46 2011 -0800
     1.3 @@ -308,8 +308,18 @@
     1.4  {
     1.5      SDL_Mouse *mouse = SDL_GetMouse();
     1.6  
     1.7 -    /* Flush pending mouse motion */
     1.8 -    SDL_FlushEvent(SDL_MOUSEMOTION);
     1.9 +    if (enabled == mouse->relative_mode) {
    1.10 +        return 0;
    1.11 +    }
    1.12 +
    1.13 +    if (!mouse->SetRelativeMouseMode) {
    1.14 +        SDL_Unsupported();
    1.15 +        return -1;
    1.16 +    }
    1.17 +
    1.18 +    if (mouse->SetRelativeMouseMode(enabled) < 0) {
    1.19 +        return -1;
    1.20 +    }
    1.21  
    1.22      /* Set the relative mode */
    1.23      mouse->relative_mode = enabled;
    1.24 @@ -319,6 +329,9 @@
    1.25          SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
    1.26      }
    1.27  
    1.28 +    /* Flush pending mouse motion */
    1.29 +    SDL_FlushEvent(SDL_MOUSEMOTION);
    1.30 +
    1.31      /* Update cursor visibility */
    1.32      SDL_SetCursor(NULL);
    1.33  
     2.1 --- a/src/events/SDL_mouse_c.h	Sun Feb 27 21:36:23 2011 -0800
     2.2 +++ b/src/events/SDL_mouse_c.h	Sun Feb 27 22:06:46 2011 -0800
     2.3 @@ -49,6 +49,9 @@
     2.4      /* Warp the mouse to (x,y) */
     2.5      void (*WarpMouse) (SDL_Window * window, int x, int y);
     2.6  
     2.7 +    /* Set relative mode */
     2.8 +    int (*SetRelativeMouseMode) (SDL_bool enabled);
     2.9 +
    2.10      /* Data common to all mice */
    2.11      SDL_Window *focus;
    2.12      int x;
     3.1 --- a/src/video/cocoa/SDL_cocoamouse.m	Sun Feb 27 21:36:23 2011 -0800
     3.2 +++ b/src/video/cocoa/SDL_cocoamouse.m	Sun Feb 27 22:06:46 2011 -0800
     3.3 @@ -116,6 +116,23 @@
     3.4      CGWarpMouseCursorPosition(point);
     3.5  }
     3.6  
     3.7 +static int
     3.8 +Cocoa_SetRelativeMouseMode(SDL_bool enabled)
     3.9 +{
    3.10 +    CGError result;
    3.11 +
    3.12 +    if (enabled) {
    3.13 +        result = CGAssociateMouseAndMouseCursorPosition(NO);
    3.14 +    } else {
    3.15 +        result = CGAssociateMouseAndMouseCursorPosition(YES);
    3.16 +    }
    3.17 +    if (result != kCGErrorSuccess) {
    3.18 +        SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
    3.19 +        return -1;
    3.20 +    }
    3.21 +    return 0;
    3.22 +}
    3.23 +
    3.24  void
    3.25  Cocoa_InitMouse(_THIS)
    3.26  {
    3.27 @@ -123,8 +140,9 @@
    3.28  
    3.29      mouse->CreateCursor = Cocoa_CreateCursor;
    3.30      mouse->ShowCursor = Cocoa_ShowCursor;
    3.31 +    mouse->FreeCursor = Cocoa_FreeCursor;
    3.32      mouse->WarpMouse = Cocoa_WarpMouse;
    3.33 -    mouse->FreeCursor = Cocoa_FreeCursor;
    3.34 +    mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
    3.35  
    3.36      SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
    3.37  }
    3.38 @@ -147,7 +165,13 @@
    3.39  void
    3.40  Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
    3.41  {
    3.42 -    /* We're correctly using views even in fullscreen mode now */
    3.43 +    SDL_Mouse *mouse = SDL_GetMouse();
    3.44 +
    3.45 +    if (mouse->relative_mode && [event type] == NSMouseMoved) {
    3.46 +        float x = [event deltaX];
    3.47 +        float y = [event deltaY];
    3.48 +        SDL_SendMouseMotion(mouse->focus, 1, (int)x, (int)y);
    3.49 +    }
    3.50  }
    3.51  
    3.52  void
     4.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Sun Feb 27 21:36:23 2011 -0800
     4.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Sun Feb 27 22:06:46 2011 -0800
     4.3 @@ -302,15 +302,14 @@
     4.4  
     4.5  - (void)mouseMoved:(NSEvent *)theEvent
     4.6  {
     4.7 +    SDL_Mouse *mouse = SDL_GetMouse();
     4.8      SDL_Window *window = _data->window;
     4.9      NSPoint point;
    4.10      int x, y;
    4.11  
    4.12 -#ifdef RELATIVE_MOTION
    4.13 -    if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
    4.14 +    if (mouse->relative_mode) {
    4.15          return;
    4.16      }
    4.17 -#endif
    4.18  
    4.19      point = [theEvent locationInWindow];
    4.20      x = (int)point.x;
    4.21 @@ -861,19 +860,6 @@
    4.22  void
    4.23  Cocoa_SetWindowGrab(_THIS, SDL_Window * window)
    4.24  {
    4.25 -#ifdef RELATIVE_MOTION
    4.26 -    /* FIXME: work in progress
    4.27 -        You set relative mode by using the following code in conjunction with
    4.28 -        CGDisplayHideCursor(kCGDirectMainDisplay) and
    4.29 -        CGDisplayShowCursor(kCGDirectMainDisplay)
    4.30 -    */
    4.31 -    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
    4.32 -        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
    4.33 -        CGAssociateMouseAndMouseCursorPosition(NO);
    4.34 -    } else {
    4.35 -        CGAssociateMouseAndMouseCursorPosition(YES);
    4.36 -    }
    4.37 -#else
    4.38      /* Move the cursor to the nearest point in the window */
    4.39      if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
    4.40          (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
    4.41 @@ -885,7 +871,6 @@
    4.42          cgpoint.y = window->y + y;
    4.43          CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
    4.44      }
    4.45 -#endif
    4.46  }
    4.47  
    4.48  void
     5.1 --- a/test/common.c	Sun Feb 27 21:36:23 2011 -0800
     5.2 +++ b/test/common.c	Sun Feb 27 22:06:46 2011 -0800
     5.3 @@ -812,7 +812,7 @@
     5.4  {
     5.5      if (event->type == SDL_MOUSEMOTION) {
     5.6          /* Mouse motion is really spammy */
     5.7 -        return;
     5.8 +        //return;
     5.9      }
    5.10  
    5.11      fprintf(stderr, "SDL EVENT: ");
    5.12 @@ -1044,6 +1044,12 @@
    5.13                  }
    5.14              }
    5.15              break;
    5.16 +        case SDLK_r:
    5.17 +            if (event->key.keysym.mod & KMOD_CTRL) {
    5.18 +                /* Ctrl-R toggle mouse relative mode */
    5.19 +                SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode());
    5.20 +            }
    5.21 +            break;
    5.22          case SDLK_z:
    5.23              if (event->key.keysym.mod & KMOD_CTRL) {
    5.24                  /* Ctrl-Z minimize */