Implemented SDL_GetAbsoluteMouseState().
authorRyan C. Gordon <icculus@icculus.org>
Thu, 05 Jun 2014 00:03:33 -0400
changeset 894504248c700ada
parent 8944 045aac36daac
child 8946 c9592936dffc
Implemented SDL_GetAbsoluteMouseState().

X11 only for now, but this should be doable on every platform, I think.
include/SDL_mouse.h
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/test/SDL_test_common.c
src/video/x11/SDL_x11mouse.c
     1.1 --- a/include/SDL_mouse.h	Thu Jun 05 00:02:42 2014 -0400
     1.2 +++ b/include/SDL_mouse.h	Thu Jun 05 00:03:33 2014 -0400
     1.3 @@ -78,6 +78,31 @@
     1.4  extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y);
     1.5  
     1.6  /**
     1.7 + *  \brief Get the current state of the mouse, in relation to the desktop
     1.8 + *
     1.9 + *  This works just like SDL_GetMouseState(), but the coordinates will be
    1.10 + *  reported relative to the top-left of the desktop. This can be useful if
    1.11 + *  you need to track the mouse outside of a specific window and
    1.12 + *  SDL_CaptureMouse() doesn't fit your needs. For example, it could be
    1.13 + *  useful if you need to track the mouse while dragging a window, where
    1.14 + *  coordinates relative to a window might not be in sync at all times.
    1.15 + *
    1.16 + *  \note SDL_GetMouseState() returns the mouse position as SDL understands
    1.17 + *        it from the last pump of the event queue. This function, however,
    1.18 + *        queries the OS for the current mouse position, and as such, might
    1.19 + *        be a slightly less efficient function. Unless you know what you're
    1.20 + *        doing and have a good reason to use this function, you probably want
    1.21 + *        SDL_GetMouseState() instead.
    1.22 + *
    1.23 + *  \param x Returns the current X coord, relative to the desktop. Can be NULL.
    1.24 + *  \param y Returns the current Y coord, relative to the desktop. Can be NULL.
    1.25 + *  \return The current button state as a bitmask, which can be tested using the SDL_BUTTON(X) macros.
    1.26 + *
    1.27 + *  \sa SDL_GetMouseState
    1.28 + */
    1.29 +extern DECLSPEC Uint32 SDLCALL SDL_GetAbsoluteMouseState(int *x, int *y);
    1.30 +
    1.31 +/**
    1.32   *  \brief Retrieve the relative state of the mouse.
    1.33   *
    1.34   *  The current button state is returned as a button bitmask, which can
     2.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Thu Jun 05 00:02:42 2014 -0400
     2.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Thu Jun 05 00:03:33 2014 -0400
     2.3 @@ -581,3 +581,4 @@
     2.4  #define SDL_WinRTRunApp SDL_WinRTRunApp_REAL
     2.5  #define SDL_CaptureMouse SDL_CaptureMouse_REAL
     2.6  #define SDL_SetWindowHitTest SDL_SetWindowHitTest_REAL
     2.7 +#define SDL_GetAbsoluteMouseState SDL_GetAbsoluteMouseState_REAL
     3.1 --- a/src/dynapi/SDL_dynapi_procs.h	Thu Jun 05 00:02:42 2014 -0400
     3.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Thu Jun 05 00:03:33 2014 -0400
     3.3 @@ -614,3 +614,4 @@
     3.4  #endif
     3.5  SDL_DYNAPI_PROC(int,SDL_CaptureMouse,(SDL_bool a),(a),return)
     3.6  SDL_DYNAPI_PROC(int,SDL_SetWindowHitTest,(SDL_Window *a, SDL_HitTest b, void *c),(a,b,c),return)
     3.7 +SDL_DYNAPI_PROC(Uint32,SDL_GetAbsoluteMouseState,(int *a, int *b),(a,b),return)
     4.1 --- a/src/events/SDL_mouse.c	Thu Jun 05 00:02:42 2014 -0400
     4.2 +++ b/src/events/SDL_mouse.c	Thu Jun 05 00:03:33 2014 -0400
     4.3 @@ -469,6 +469,30 @@
     4.4      return mouse->buttonstate;
     4.5  }
     4.6  
     4.7 +Uint32
     4.8 +SDL_GetAbsoluteMouseState(int *x, int *y)
     4.9 +{
    4.10 +    SDL_Mouse *mouse = SDL_GetMouse();
    4.11 +    int tmpx, tmpy;
    4.12 +
    4.13 +    /* make sure these are never NULL for the backend implementations... */
    4.14 +    if (!x) {
    4.15 +        x = &tmpx;
    4.16 +    }
    4.17 +    if (!y) {
    4.18 +        y = &tmpy;
    4.19 +    }
    4.20 +
    4.21 +    *x = *y = 0;
    4.22 +
    4.23 +    if (!mouse->GetAbsoluteMouseState) {
    4.24 +        SDL_assert(0 && "This should really be implemented for every target.");
    4.25 +        return 0;
    4.26 +    }
    4.27 +
    4.28 +    return mouse->GetAbsoluteMouseState(x, y);
    4.29 +}
    4.30 +
    4.31  void
    4.32  SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
    4.33  {
     5.1 --- a/src/events/SDL_mouse_c.h	Thu Jun 05 00:02:42 2014 -0400
     5.2 +++ b/src/events/SDL_mouse_c.h	Thu Jun 05 00:03:33 2014 -0400
     5.3 @@ -66,6 +66,9 @@
     5.4      /* Set mouse capture */
     5.5      int (*CaptureMouse) (SDL_Window * window);
     5.6  
     5.7 +    /* Get absolute mouse coordinates. (x) and (y) are never NULL and set to zero before call. */
     5.8 +    Uint32 (*GetAbsoluteMouseState) (int *x, int *y);
     5.9 +
    5.10      /* Data common to all mice */
    5.11      SDL_MouseID mouseID;
    5.12      SDL_Window *focus;
     6.1 --- a/src/test/SDL_test_common.c	Thu Jun 05 00:02:42 2014 -0400
     6.2 +++ b/src/test/SDL_test_common.c	Thu Jun 05 00:03:33 2014 -0400
     6.3 @@ -1488,6 +1488,19 @@
     6.4                  }
     6.5              }
     6.6              break;
     6.7 +        case SDLK_a:
     6.8 +            if (withControl) {
     6.9 +                /* Ctrl-A reports absolute mouse position. */
    6.10 +                int x, y;
    6.11 +                const Uint32 mask = SDL_GetAbsoluteMouseState(&x, &y);
    6.12 +                SDL_Log("ABSOLUTE MOUSE: (%d, %d)%s%s%s%s%s\n", x, y,
    6.13 +                        (mask & SDL_BUTTON_LMASK) ? " [LBUTTON]" : "",
    6.14 +                        (mask & SDL_BUTTON_MMASK) ? " [MBUTTON]" : "",
    6.15 +                        (mask & SDL_BUTTON_RMASK) ? " [RBUTTON]" : "",
    6.16 +                        (mask & SDL_BUTTON_X1MASK) ? " [X2BUTTON]" : "",
    6.17 +                        (mask & SDL_BUTTON_X2MASK) ? " [X2BUTTON]" : "");
    6.18 +            }
    6.19 +            break;
    6.20          case SDLK_0:
    6.21              if (withControl) {
    6.22                  SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
     7.1 --- a/src/video/x11/SDL_x11mouse.c	Thu Jun 05 00:02:42 2014 -0400
     7.2 +++ b/src/video/x11/SDL_x11mouse.c	Thu Jun 05 00:03:33 2014 -0400
     7.3 @@ -353,6 +353,39 @@
     7.4      return 0;
     7.5  }
     7.6  
     7.7 +static Uint32
     7.8 +X11_GetAbsoluteMouseState(int *x, int *y)
     7.9 +{
    7.10 +    Display *display = GetDisplay();
    7.11 +    const int num_screens = SDL_GetNumVideoDisplays();
    7.12 +    int i;
    7.13 +
    7.14 +    /* !!! FIXME: should we XSync() here first? */
    7.15 +
    7.16 +    for (i = 0; i < num_screens; i++) {
    7.17 +        SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
    7.18 +        if (data != NULL) {
    7.19 +            Window root, child;
    7.20 +            int rootx, rooty, winx, winy;
    7.21 +            unsigned int mask;
    7.22 +            if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
    7.23 +                Uint32 retval = 0;
    7.24 +                retval |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
    7.25 +                retval |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
    7.26 +                retval |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
    7.27 +                *x = data->x + rootx;
    7.28 +                *y = data->y + rooty;
    7.29 +                return retval;
    7.30 +            }
    7.31 +        }
    7.32 +    }
    7.33 +
    7.34 +    SDL_assert(0 && "The pointer wasn't on any X11 screen?!");
    7.35 +
    7.36 +    return 0;
    7.37 +}
    7.38 +
    7.39 +
    7.40  void
    7.41  X11_InitMouse(_THIS)
    7.42  {
    7.43 @@ -365,6 +398,7 @@
    7.44      mouse->WarpMouse = X11_WarpMouse;
    7.45      mouse->SetRelativeMouseMode = X11_SetRelativeMouseMode;
    7.46      mouse->CaptureMouse = X11_CaptureMouse;
    7.47 +    mouse->GetAbsoluteMouseState = X11_GetAbsoluteMouseState;
    7.48  
    7.49      SDL_SetDefaultCursor(X11_CreateDefaultCursor());
    7.50  }