Mac and Linux SDL2 binary snapshots
Edward Rudd
2020-05-02 03f8528315fa46c95991a34f3325d7b33ae5538c
source/src/events/SDL_mouse.c
@@ -1,6 +1,6 @@
/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
@@ -27,12 +27,19 @@
#include "SDL_timer.h"
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "../SDL_hints_c.h"
#include "../video/SDL_sysvideo.h"
#ifdef __WIN32__
#include "../core/windows/SDL_windows.h"    // For GetDoubleClickTime()
#endif
/* #define DEBUG_MOUSE */
/* The mouse state */
static SDL_Mouse SDL_mouse;
/* for mapping mouse events to touch */
static SDL_bool track_mouse_down = SDL_FALSE;
static int
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
@@ -94,10 +101,24 @@
{
    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
    if (hint && (*hint == '0' || SDL_strcasecmp(hint, "false") == 0)) {
        mouse->touch_mouse_events = SDL_FALSE;
    } else {
        mouse->touch_mouse_events = SDL_TRUE;
    mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
}
static void SDLCALL
SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
    SDL_bool default_value;
#if defined(__ANDROID__) || (defined(__IPHONEOS__) && !defined(__TVOS__))
    default_value = SDL_TRUE;
#else
    default_value = SDL_FALSE;
#endif
    mouse->mouse_touch_events = SDL_GetStringBoolean(hint, default_value);
    if (mouse->mouse_touch_events) {
        SDL_AddTouch(SDL_MOUSE_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "mouse_input");
    }
}
@@ -123,6 +144,11 @@
    SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
                        SDL_TouchMouseEventsChanged, mouse);
    SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
                        SDL_MouseTouchEventsChanged, mouse);
    mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */
    mouse->cursor_shown = SDL_TRUE;
@@ -212,7 +238,7 @@
/* Check to see if we need to synthesize focus events */
static SDL_bool
SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate)
SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_bool send_mouse_motion)
{
    SDL_Mouse *mouse = SDL_GetMouse();
    SDL_bool inWindow = SDL_TRUE;
@@ -243,7 +269,9 @@
#ifdef DEBUG_MOUSE
            printf("Mouse left window, synthesizing move & focus lost event\n");
#endif
            SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
            if (send_mouse_motion) {
                SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
            }
            SDL_SetMouseFocus(NULL);
        }
        return SDL_FALSE;
@@ -254,7 +282,9 @@
        printf("Mouse entered window, synthesizing focus gain & move event\n");
#endif
        SDL_SetMouseFocus(window);
        SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
        if (send_mouse_motion) {
            SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
        }
    }
    return SDL_TRUE;
}
@@ -264,7 +294,7 @@
{
    if (window && !relative) {
        SDL_Mouse *mouse = SDL_GetMouse();
        if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) {
        if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate, (mouseID == SDL_TOUCH_MOUSEID) ? SDL_FALSE : SDL_TRUE)) {
            return 0;
        }
    }
@@ -295,8 +325,22 @@
    int xrel;
    int yrel;
    if (mouseID == SDL_TOUCH_MOUSEID && !mouse->touch_mouse_events) {
        return 0;
    /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
    if (mouse->mouse_touch_events) {
        if (mouseID != SDL_TOUCH_MOUSEID && !relative && track_mouse_down) {
            if (window) {
                float fx = (float)x / (float)window->w;
                float fy = (float)y / (float)window->h;
                SDL_SendTouchMotion(SDL_MOUSE_TOUCHID, 0, window, fx, fy, 1.0f);
            }
        }
    }
    /* SDL_HINT_TOUCH_MOUSE_EVENTS: if not set, discard synthetic mouse events coming from platform layer */
    if (mouse->touch_mouse_events == 0) {
        if (mouseID == SDL_TOUCH_MOUSEID) {
            return 0;
        }
    }
    if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
@@ -329,19 +373,16 @@
        yrel = y - mouse->last_y;
    }
    /* Drop events that don't change state */
    if (!xrel && !yrel) {
#ifdef DEBUG_MOUSE
        printf("Mouse event didn't change state - dropped!\n");
#endif
        return 0;
    }
    /* Ignore relative motion when first positioning the mouse */
    if (!mouse->has_position) {
        xrel = 0;
        yrel = 0;
        mouse->has_position = SDL_TRUE;
    } else if (!xrel && !yrel) {  /* Drop events that don't change state */
#ifdef DEBUG_MOUSE
        printf("Mouse event didn't change state - dropped!\n");
#endif
        return 0;
    }
    /* Ignore relative motion positioning the first touch */
@@ -400,6 +441,8 @@
        event.motion.type = SDL_MOUSEMOTION;
        event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
        event.motion.which = mouseID;
        /* Set us pending (or clear during a normal mouse movement event) as having triggered */
        mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID)? SDL_TRUE : SDL_FALSE;
        event.motion.state = mouse->buttonstate;
        event.motion.x = mouse->x;
        event.motion.y = mouse->y;
@@ -444,8 +487,27 @@
    Uint32 type;
    Uint32 buttonstate = mouse->buttonstate;
    if (mouseID == SDL_TOUCH_MOUSEID && !mouse->touch_mouse_events) {
        return 0;
    /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
    if (mouse->mouse_touch_events) {
        if (mouseID != SDL_TOUCH_MOUSEID && button == SDL_BUTTON_LEFT) {
            if (state == SDL_PRESSED) {
                track_mouse_down = SDL_TRUE;
            } else {
                track_mouse_down = SDL_FALSE;
            }
            if (window) {
                float fx = (float)mouse->x / (float)window->w;
                float fy = (float)mouse->y / (float)window->h;
                SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, window, track_mouse_down, fx, fy, 1.0f);
            }
        }
    }
    /* SDL_HINT_TOUCH_MOUSE_EVENTS: if not set, discard synthetic mouse events coming from platform layer */
    if (mouse->touch_mouse_events == 0) {
        if (mouseID == SDL_TOUCH_MOUSEID) {
            return 0;
        }
    }
    /* Figure out which event to perform */
@@ -465,7 +527,7 @@
    /* We do this after calculating buttonstate so button presses gain focus */
    if (window && state == SDL_PRESSED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE);
    }
    if (buttonstate == mouse->buttonstate) {
@@ -515,9 +577,9 @@
    /* We do this after dispatching event so button releases can lose focus */
    if (window && state == SDL_RELEASED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE);
    }
    return posted;
}
@@ -545,7 +607,7 @@
        SDL_SetMouseFocus(window);
    }
    if (!x && !y) {
    if (x == 0.0f && y == 0.0f) {
        return 0;
    }
@@ -607,6 +669,7 @@
        cursor = next;
    }
    mouse->cursors = NULL;
    mouse->cur_cursor = NULL;
    if (mouse->def_cursor && mouse->FreeCursor) {
        mouse->FreeCursor(mouse->def_cursor);
@@ -713,9 +776,9 @@
static SDL_bool
ShouldUseRelativeModeWarp(SDL_Mouse *mouse)
{
    if (!mouse->SetRelativeMouseMode) {
        SDL_assert(mouse->WarpMouse);   /* Need this functionality for relative mode warp implementation */
        return SDL_TRUE;
    if (!mouse->WarpMouse) {
        /* Need this functionality for relative mode warp implementation */
        return SDL_FALSE;
    }
    return SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE);
@@ -731,20 +794,12 @@
        return 0;
    }
    if (enabled && focusWindow) {
        /* Center it in the focused window to prevent clicks from going through
         * to background windows.
         */
        SDL_SetMouseFocus(focusWindow);
        SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
    }
    /* Set the relative mode */
    if (!enabled && mouse->relative_mode_warp) {
        mouse->relative_mode_warp = SDL_FALSE;
    } else if (enabled && ShouldUseRelativeModeWarp(mouse)) {
        mouse->relative_mode_warp = SDL_TRUE;
    } else if (mouse->SetRelativeMouseMode(enabled) < 0) {
    } else if (!mouse->SetRelativeMouseMode || mouse->SetRelativeMouseMode(enabled) < 0) {
        if (enabled) {
            /* Fall back to warp mode if native relative mode failed */
            if (!mouse->WarpMouse) {
@@ -757,6 +812,14 @@
    mouse->scale_accum_x = 0.0f;
    mouse->scale_accum_y = 0.0f;
    if (enabled && focusWindow) {
        /* Center it in the focused window to prevent clicks from going through
         * to background windows.
         */
        SDL_SetMouseFocus(focusWindow);
        SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
    }
    if (mouse->focus) {
        SDL_UpdateWindowGrab(mouse->focus);