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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index ac605db..90d0e81 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 ae94abf..99dbcb8 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 451b451..893ecc7 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, ¢er_x, ¢er_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 8994e02..9f88d40 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 1f5810a..3274cc5 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);
+ }
}
}
}