summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Becker <sylvain.becker@gmail.com>2019-04-04 16:51:50 +0200
committerSylvain Becker <sylvain.becker@gmail.com>2019-04-04 16:51:50 +0200
commiteb4598e299596ca736047668343d5a92a56ceb2b (patch)
tree349e5fadf2f0230ed1bc972e9e983ba571651626
parent21cfa42d3bb24b77e9770ec8a6a958711fecd950 (diff)
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
-rw-r--r--include/SDL_hints.h12
-rw-r--r--include/SDL_touch.h3
-rw-r--r--src/events/SDL_mouse.c48
-rw-r--r--src/events/SDL_mouse_c.h1
-rw-r--r--src/events/SDL_touch.c49
5 files changed, 91 insertions, 22 deletions
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index ac605db095..90d0e8150a 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -316,6 +316,18 @@ extern "C" {
#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS"
/**
+ * \brief A variable controlling whether mouse events should generate synthetic touch events
+ *
+ * This variable can be set to the following values:
+ * "0" - Mouse events will not generate touch events
+ * "1" - Mouse events will generate touch events
+ *
+ * By default SDL will *not* generate touch events for mouse events
+ */
+
+#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS"
+
+/**
* \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true.
*
*/
diff --git a/include/SDL_touch.h b/include/SDL_touch.h
index ae94abf7bb..99dbcb8c3f 100644
--- a/include/SDL_touch.h
+++ b/include/SDL_touch.h
@@ -60,6 +60,9 @@ typedef struct SDL_Finger
/* Used as the device ID for mouse events simulated with touch input */
#define SDL_TOUCH_MOUSEID ((Uint32)-1)
+/* Used as the SDL_TouchID for touch events simulated with mouse input */
+#define SDL_MOUSE_TOUCHID ((Sint64)-1)
+
/* Function prototypes */
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index 451b451a5c..893ecc72bd 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -37,6 +37,9 @@
/* 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);
@@ -104,6 +107,21 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
}
}
+static void SDLCALL
+SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ SDL_Mouse *mouse = (SDL_Mouse *)userdata;
+
+ if (hint && (*hint == '1' || SDL_strcasecmp(hint, "true") == 0)) {
+
+ SDL_AddTouch(SDL_MOUSE_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "mouse_input");
+
+ mouse->mouse_touch_events = SDL_TRUE;
+ } else {
+ mouse->mouse_touch_events = SDL_FALSE;
+ }
+}
+
/* Public functions */
int
SDL_MouseInit(void)
@@ -127,6 +145,9 @@ SDL_MouseInit(void)
SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
SDL_TouchMouseEventsChanged, mouse);
+ SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
+ SDL_MouseTouchEventsChanged, mouse);
+
mouse->cursor_shown = SDL_TRUE;
return (0);
@@ -298,6 +319,17 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
int xrel;
int yrel;
+ /* 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, fx, fy, 1.0f);
+ }
+ }
+ }
+
if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
int center_x = 0, center_y = 0;
SDL_GetWindowSize(window, &center_x, &center_y);
@@ -443,6 +475,22 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
Uint32 type;
Uint32 buttonstate = mouse->buttonstate;
+ /* 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 (window) {
+ float fx = (float)mouse->x / (float)window->w;
+ float fy = (float)mouse->y / (float)window->h;
+ if (state == SDL_PRESSED) {
+ track_mouse_down = SDL_TRUE;
+ } else {
+ track_mouse_down = SDL_FALSE;
+ }
+ SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, track_mouse_down, fx, fy, 1.0f);
+ }
+ }
+ }
+
/* Figure out which event to perform */
switch (state) {
case SDL_PRESSED:
diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h
index 8994e02a0f..9f88d408a5 100644
--- a/src/events/SDL_mouse_c.h
+++ b/src/events/SDL_mouse_c.h
@@ -93,6 +93,7 @@ typedef struct
Uint32 double_click_time;
int double_click_radius;
SDL_bool touch_mouse_events;
+ SDL_bool mouse_touch_events;
/* Data for double-click tracking */
int num_clickstates;
diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c
index 1f5810af12..3274cc521e 100644
--- a/src/events/SDL_touch.c
+++ b/src/events/SDL_touch.c
@@ -249,22 +249,25 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
{
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse->touch_mouse_events) {
- SDL_Window *window = SDL_GetMouseFocus();
- if (window) {
- if (down) {
- if (finger_touching == SDL_FALSE) {
- int pos_x = (int)(x * (float)window->w);
- int pos_y = (int)(y * (float)window->h);
- finger_touching = SDL_TRUE;
- track_touchid = id;
- track_fingerid = fingerid;
- SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
- SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
- }
- } else {
- if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
- SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
- finger_touching = SDL_FALSE;
+ /* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
+ if (id != SDL_MOUSE_TOUCHID) {
+ SDL_Window *window = SDL_GetMouseFocus();
+ if (window) {
+ if (down) {
+ if (finger_touching == SDL_FALSE) {
+ int pos_x = (int)(x * (float)window->w);
+ int pos_y = (int)(y * (float)window->h);
+ finger_touching = SDL_TRUE;
+ track_touchid = id;
+ track_fingerid = fingerid;
+ SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
+ SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+ }
+ } else {
+ if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
+ SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+ finger_touching = SDL_FALSE;
+ }
}
}
}
@@ -339,12 +342,14 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
{
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse->touch_mouse_events) {
- SDL_Window *window = SDL_GetMouseFocus();
- if (window) {
- if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
- int pos_x = (int)(x * (float)window->w);
- int pos_y = (int)(y * (float)window->h);
- SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
+ if (id != SDL_MOUSE_TOUCHID) {
+ SDL_Window *window = SDL_GetMouseFocus();
+ if (window) {
+ if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
+ int pos_x = (int)(x * (float)window->w);
+ int pos_y = (int)(y * (float)window->h);
+ SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
+ }
}
}
}