Add hint SDL_HINT_MOUSE_TOUCH_EVENTS for mouse events to generate touch events
authorSylvain Becker <sylvain.becker@gmail.com>
Thu, 04 Apr 2019 16:51:50 +0200
changeset 12688cc45bcb16ef2
parent 12687 712d84dd14c9
child 12689 d581caf613cd
Add hint SDL_HINT_MOUSE_TOUCH_EVENTS for mouse events to generate touch events

controlling whether mouse events should generate synthetic touch events
By default SDL will *not* generate touch events for mouse events
include/SDL_hints.h
include/SDL_touch.h
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/events/SDL_touch.c
     1.1 --- a/include/SDL_hints.h	Thu Apr 04 15:19:00 2019 +0200
     1.2 +++ b/include/SDL_hints.h	Thu Apr 04 16:51:50 2019 +0200
     1.3 @@ -316,6 +316,18 @@
     1.4  #define SDL_HINT_TOUCH_MOUSE_EVENTS    "SDL_TOUCH_MOUSE_EVENTS"
     1.5  
     1.6  /**
     1.7 + *  \brief  A variable controlling whether mouse events should generate synthetic touch events
     1.8 + *
     1.9 + *  This variable can be set to the following values:
    1.10 + *    "0"       - Mouse events will not generate touch events
    1.11 + *    "1"       - Mouse events will generate touch events
    1.12 + *
    1.13 + *  By default SDL will *not* generate touch events for mouse events
    1.14 + */
    1.15 +
    1.16 +#define SDL_HINT_MOUSE_TOUCH_EVENTS    "SDL_MOUSE_TOUCH_EVENTS"
    1.17 +
    1.18 +/**
    1.19   *  \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true.
    1.20   *
    1.21   */
     2.1 --- a/include/SDL_touch.h	Thu Apr 04 15:19:00 2019 +0200
     2.2 +++ b/include/SDL_touch.h	Thu Apr 04 16:51:50 2019 +0200
     2.3 @@ -60,6 +60,9 @@
     2.4  /* Used as the device ID for mouse events simulated with touch input */
     2.5  #define SDL_TOUCH_MOUSEID ((Uint32)-1)
     2.6  
     2.7 +/* Used as the SDL_TouchID for touch events simulated with mouse input */
     2.8 +#define SDL_MOUSE_TOUCHID ((Sint64)-1)
     2.9 +
    2.10  
    2.11  /* Function prototypes */
    2.12  
     3.1 --- a/src/events/SDL_mouse.c	Thu Apr 04 15:19:00 2019 +0200
     3.2 +++ b/src/events/SDL_mouse.c	Thu Apr 04 16:51:50 2019 +0200
     3.3 @@ -37,6 +37,9 @@
     3.4  /* The mouse state */
     3.5  static SDL_Mouse SDL_mouse;
     3.6  
     3.7 +/* for mapping mouse events to touch */
     3.8 +static SDL_bool track_mouse_down = SDL_FALSE;
     3.9 +
    3.10  static int
    3.11  SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
    3.12  
    3.13 @@ -104,6 +107,21 @@
    3.14      }
    3.15  }
    3.16  
    3.17 +static void SDLCALL
    3.18 +SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
    3.19 +{
    3.20 +    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
    3.21 +
    3.22 +    if (hint && (*hint == '1' || SDL_strcasecmp(hint, "true") == 0)) {
    3.23 +
    3.24 +        SDL_AddTouch(SDL_MOUSE_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "mouse_input");
    3.25 +
    3.26 +        mouse->mouse_touch_events = SDL_TRUE;
    3.27 +    } else {
    3.28 +        mouse->mouse_touch_events = SDL_FALSE;
    3.29 +    }
    3.30 +}
    3.31 +
    3.32  /* Public functions */
    3.33  int
    3.34  SDL_MouseInit(void)
    3.35 @@ -127,6 +145,9 @@
    3.36      SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
    3.37                          SDL_TouchMouseEventsChanged, mouse);
    3.38  
    3.39 +    SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
    3.40 +                        SDL_MouseTouchEventsChanged, mouse);
    3.41 +
    3.42      mouse->cursor_shown = SDL_TRUE;
    3.43  
    3.44      return (0);
    3.45 @@ -298,6 +319,17 @@
    3.46      int xrel;
    3.47      int yrel;
    3.48  
    3.49 +    /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
    3.50 +    if (mouse->mouse_touch_events) {
    3.51 +        if (mouseID != SDL_TOUCH_MOUSEID && !relative && track_mouse_down) {
    3.52 +            if (window) {
    3.53 +                float fx = (float)x / (float)window->w;
    3.54 +                float fy = (float)y / (float)window->h;
    3.55 +                SDL_SendTouchMotion(SDL_MOUSE_TOUCHID, 0, fx, fy, 1.0f);
    3.56 +            }
    3.57 +        }
    3.58 +    }
    3.59 +
    3.60      if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
    3.61          int center_x = 0, center_y = 0;
    3.62          SDL_GetWindowSize(window, &center_x, &center_y);
    3.63 @@ -443,6 +475,22 @@
    3.64      Uint32 type;
    3.65      Uint32 buttonstate = mouse->buttonstate;
    3.66  
    3.67 +    /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
    3.68 +    if (mouse->mouse_touch_events) {
    3.69 +        if (mouseID != SDL_TOUCH_MOUSEID && button == SDL_BUTTON_LEFT) {
    3.70 +            if (window) {
    3.71 +                float fx = (float)mouse->x / (float)window->w;
    3.72 +                float fy = (float)mouse->y / (float)window->h;
    3.73 +                if (state == SDL_PRESSED) {
    3.74 +                    track_mouse_down = SDL_TRUE;
    3.75 +                } else {
    3.76 +                    track_mouse_down = SDL_FALSE;
    3.77 +                }
    3.78 +                SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, track_mouse_down, fx, fy, 1.0f);
    3.79 +            }
    3.80 +        }
    3.81 +    }
    3.82 +
    3.83      /* Figure out which event to perform */
    3.84      switch (state) {
    3.85      case SDL_PRESSED:
     4.1 --- a/src/events/SDL_mouse_c.h	Thu Apr 04 15:19:00 2019 +0200
     4.2 +++ b/src/events/SDL_mouse_c.h	Thu Apr 04 16:51:50 2019 +0200
     4.3 @@ -93,6 +93,7 @@
     4.4      Uint32 double_click_time;
     4.5      int double_click_radius;
     4.6      SDL_bool touch_mouse_events;
     4.7 +    SDL_bool mouse_touch_events;
     4.8  
     4.9      /* Data for double-click tracking */
    4.10      int num_clickstates;
     5.1 --- a/src/events/SDL_touch.c	Thu Apr 04 15:19:00 2019 +0200
     5.2 +++ b/src/events/SDL_touch.c	Thu Apr 04 16:51:50 2019 +0200
     5.3 @@ -249,22 +249,25 @@
     5.4      {
     5.5          SDL_Mouse *mouse = SDL_GetMouse();
     5.6          if (mouse->touch_mouse_events) {
     5.7 -            SDL_Window *window = SDL_GetMouseFocus();
     5.8 -            if (window) {
     5.9 -                if (down) {
    5.10 -                    if (finger_touching == SDL_FALSE) {
    5.11 -                        int pos_x = (int)(x * (float)window->w);
    5.12 -                        int pos_y = (int)(y * (float)window->h);
    5.13 -                        finger_touching = SDL_TRUE;
    5.14 -                        track_touchid = id;
    5.15 -                        track_fingerid = fingerid;
    5.16 -                        SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
    5.17 -                        SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
    5.18 -                    }
    5.19 -                } else {
    5.20 -                    if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
    5.21 -                        SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
    5.22 -                        finger_touching = SDL_FALSE;
    5.23 +            /* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
    5.24 +            if (id != SDL_MOUSE_TOUCHID) {
    5.25 +                SDL_Window *window = SDL_GetMouseFocus();
    5.26 +                if (window) {
    5.27 +                    if (down) {
    5.28 +                        if (finger_touching == SDL_FALSE) {
    5.29 +                            int pos_x = (int)(x * (float)window->w);
    5.30 +                            int pos_y = (int)(y * (float)window->h);
    5.31 +                            finger_touching = SDL_TRUE;
    5.32 +                            track_touchid = id;
    5.33 +                            track_fingerid = fingerid;
    5.34 +                            SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
    5.35 +                            SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
    5.36 +                        }
    5.37 +                    } else {
    5.38 +                        if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
    5.39 +                            SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
    5.40 +                            finger_touching = SDL_FALSE;
    5.41 +                        }
    5.42                      }
    5.43                  }
    5.44              }
    5.45 @@ -339,12 +342,14 @@
    5.46      {
    5.47          SDL_Mouse *mouse = SDL_GetMouse();
    5.48          if (mouse->touch_mouse_events) {
    5.49 -            SDL_Window *window = SDL_GetMouseFocus();
    5.50 -            if (window) {
    5.51 -                if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
    5.52 -                    int pos_x = (int)(x * (float)window->w);
    5.53 -                    int pos_y = (int)(y * (float)window->h);
    5.54 -                    SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
    5.55 +            if (id != SDL_MOUSE_TOUCHID) {
    5.56 +                SDL_Window *window = SDL_GetMouseFocus();
    5.57 +                if (window) {
    5.58 +                    if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
    5.59 +                        int pos_x = (int)(x * (float)window->w);
    5.60 +                        int pos_y = (int)(y * (float)window->h);
    5.61 +                        SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
    5.62 +                    }
    5.63                  }
    5.64              }
    5.65          }