Commit bd3ee07c83746ff35d6ee6aed9493312b727490e

Ryan C. Gordon 2018-12-05T16:49:38

wayland: Send SDL_TOUCH_MOUSEID mouse events for touches.

diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 5b2cbef..033e83d 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -399,15 +399,21 @@ touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial,
                    unsigned int timestamp, struct wl_surface *surface,
                    int id, wl_fixed_t fx, wl_fixed_t fy)
 {
-    float x, y;
-    SDL_WindowData* window;
+    SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);
+    const double dblx = wl_fixed_to_double(fx);
+    const double dbly = wl_fixed_to_double(fy);
+    const float x = dblx / window_data->sdlwindow->w;
+    const float y = dbly / window_data->sdlwindow->h;
 
-    window = (SDL_WindowData *)wl_surface_get_user_data(surface);
+    touch_add(id, x, y, surface);
 
-    x = wl_fixed_to_double(fx) / window->sdlwindow->w;
-    y = wl_fixed_to_double(fy) / window->sdlwindow->h;
+    if (!window_data->finger_touching) {
+        window_data->finger_touching = SDL_TRUE;
+        window_data->first_finger = id;
+        SDL_SendMouseMotion(window_data->sdlwindow, SDL_TOUCH_MOUSEID, 0, (int) dblx, (int) dbly);
+        SDL_SendMouseButton(window_data->sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+    }
 
-    touch_add(id, x, y, surface);
     SDL_SendTouch(1, (SDL_FingerID)id, SDL_TRUE, x, y, 1.0f);
 }
 
@@ -415,8 +421,14 @@ static void
 touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial,
                  unsigned int timestamp, int id)
 {
+    SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
     float x = 0, y = 0;
 
+    if ((window_data->finger_touching) && (window_data->first_finger == id)) {
+        SDL_SendMouseButton(window_data->sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+        window_data->finger_touching = SDL_FALSE;
+    }
+
     touch_del(id, &x, &y);
     SDL_SendTouch(1, (SDL_FingerID)id, SDL_FALSE, x, y, 0.0f);
 }
@@ -425,13 +437,15 @@ static void
 touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
                      int id, wl_fixed_t fx, wl_fixed_t fy)
 {
-    float x, y;
-    SDL_WindowData* window;
-
-    window = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
-
-    x = wl_fixed_to_double(fx) / window->sdlwindow->w;
-    y = wl_fixed_to_double(fy) / window->sdlwindow->h;
+    SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
+    const double dblx = wl_fixed_to_double(fx);
+    const double dbly = wl_fixed_to_double(fy);
+    const float x = dblx / window_data->sdlwindow->w;
+    const float y = dbly / window_data->sdlwindow->h;
+
+    if ((window_data->finger_touching) && (window_data->first_finger == id)) {
+        SDL_SendMouseMotion(window_data->sdlwindow, SDL_TOUCH_MOUSEID, 0, (int) dblx, (int) dbly);
+    }
 
     touch_update(id, x, y);
     SDL_SendTouchMotion(1, (SDL_FingerID)id, x, y, 1.0f);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 298ae26..4b69f7a 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -26,6 +26,7 @@
 
 #include "../SDL_sysvideo.h"
 #include "SDL_syswm.h"
+#include "../../events/SDL_touch_c.h"
 
 #include "SDL_waylandvideo.h"
 
@@ -74,6 +75,9 @@ typedef struct {
         uint32_t serial;
         int width, height;
     } resize;
+
+    SDL_bool finger_touching;  /* for mapping touch events to mice */
+    SDL_FingerID first_finger;
 } SDL_WindowData;
 
 extern void Wayland_ShowWindow(_THIS, SDL_Window *window);