Add SDL_TouchDeviceType enum and SDL_GetTouchDeviceType(SDL_TouchID id). Touch device types include SDL_TOUCH_DEVICE_DIRECT (a touch screen with window-relative coordinates for touches), SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE (a trackpad-style device with absolute device coordinates), and SDL_TOUCH_DEVICE_INDIRECT_RELATIVE (a trackpad-style device with screen cursor-relative coordinates). Phone screens are an example of a direct device type. Mac trackpads are the indirect-absolute touch device type. The Apple TV remote is an indirect-relative touch device type.
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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
diff --git a/include/SDL_touch.h b/include/SDL_touch.h
index f4075e7..926a9e1 100644
--- a/include/SDL_touch.h
+++ b/include/SDL_touch.h
@@ -41,6 +41,14 @@ extern "C" {
typedef Sint64 SDL_TouchID;
typedef Sint64 SDL_FingerID;
+typedef enum
+{
+ SDL_TOUCH_DEVICE_INVALID = -1,
+ SDL_TOUCH_DEVICE_DIRECT, /* touch screen with window-relative coordinates */
+ SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, /* trackpad with absolute device coordinates */
+ SDL_TOUCH_DEVICE_INDIRECT_RELATIVE, /* trackpad with screen cursor-relative coordinates */
+} SDL_TouchDeviceType;
+
typedef struct SDL_Finger
{
SDL_FingerID id;
@@ -66,6 +74,11 @@ extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void);
extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index);
/**
+ * \brief Get the type of the given touch device.
+ */
+extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID);
+
+/**
* \brief Get the number of active fingers for a given touch device.
*/
extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID);
diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c
index 5443c21..8f22200 100644
--- a/src/core/linux/SDL_evdev.c
+++ b/src/core/linux/SDL_evdev.c
@@ -475,6 +475,7 @@ SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item)
}
ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */
+ SDL_TOUCH_DEVICE_DIRECT,
item->touchscreen_data->name);
if (ret < 0) {
SDL_free(item->touchscreen_data->slots);
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 73767fb..56915f5 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -712,3 +712,4 @@
#define SDL_RenderFillRectsF SDL_RenderFillRectsF_REAL
#define SDL_RenderCopyF SDL_RenderCopyF_REAL
#define SDL_RenderCopyExF SDL_RenderCopyExF_REAL
+#define SDL_GetTouchDeviceType SDL_GetTouchDeviceType_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 076205e..c95cf70 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -766,3 +766,4 @@ SDL_DYNAPI_PROC(int,SDL_RenderFillRectF,(SDL_Renderer *a, const SDL_FRect *b),(a
SDL_DYNAPI_PROC(int,SDL_RenderFillRectsF,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderCopyF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
+SDL_DYNAPI_PROC(SDL_TouchDeviceType,SDL_GetTouchDeviceType,(SDL_TouchID a),(a),return)
diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c
index 0037416..bed2c49 100644
--- a/src/events/SDL_touch.c
+++ b/src/events/SDL_touch.c
@@ -86,6 +86,16 @@ SDL_GetTouch(SDL_TouchID id)
return SDL_touchDevices[index];
}
+SDL_TouchDeviceType
+SDL_GetTouchDeviceType(SDL_TouchID id)
+{
+ SDL_Touch *touch = SDL_GetTouch(id);
+ if (touch) {
+ return touch->type;
+ }
+ return SDL_TOUCH_DEVICE_INVALID;
+}
+
static int
SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
{
@@ -133,7 +143,7 @@ SDL_GetTouchFinger(SDL_TouchID touchID, int index)
}
int
-SDL_AddTouch(SDL_TouchID touchID, const char *name)
+SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
{
SDL_Touch **touchDevices;
int index;
@@ -163,6 +173,7 @@ SDL_AddTouch(SDL_TouchID touchID, const char *name)
/* we're setting the touch properties */
SDL_touchDevices[index]->id = touchID;
+ SDL_touchDevices[index]->type = type;
SDL_touchDevices[index]->num_fingers = 0;
SDL_touchDevices[index]->max_fingers = 0;
SDL_touchDevices[index]->fingers = NULL;
diff --git a/src/events/SDL_touch_c.h b/src/events/SDL_touch_c.h
index 2a44310..4070a50 100644
--- a/src/events/SDL_touch_c.h
+++ b/src/events/SDL_touch_c.h
@@ -27,6 +27,7 @@
typedef struct SDL_Touch
{
SDL_TouchID id;
+ SDL_TouchDeviceType type;
int num_fingers;
int max_fingers;
SDL_Finger** fingers;
@@ -37,7 +38,7 @@ typedef struct SDL_Touch
extern int SDL_TouchInit(void);
/* Add a touch, returning the index of the touch, or -1 if there was an error. */
-extern int SDL_AddTouch(SDL_TouchID id, const char *name);
+extern int SDL_AddTouch(SDL_TouchID id, SDL_TouchDeviceType type, const char *name);
/* Get the touch with a given id */
extern SDL_Touch *SDL_GetTouch(SDL_TouchID id);
diff --git a/src/video/android/SDL_androidtouch.c b/src/video/android/SDL_androidtouch.c
index 5c3e4aa..37bf055 100644
--- a/src/video/android/SDL_androidtouch.c
+++ b/src/video/android/SDL_androidtouch.c
@@ -72,7 +72,7 @@ void Android_InitTouch(void)
if (0 < number) {
for (i = 0; i < number; ++i) {
- SDL_AddTouch((SDL_TouchID) ids[i], ""); /* no error handling */
+ SDL_AddTouch((SDL_TouchID) ids[i], SDL_TOUCH_DEVICE_DIRECT, ""); /* no error handling */
}
SDL_free(ids);
}
@@ -97,7 +97,7 @@ void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int actio
}
touchDeviceId = (SDL_TouchID)touch_device_id_in;
- if (SDL_AddTouch(touchDeviceId, "") < 0) {
+ if (SDL_AddTouch(touchDeviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
}
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index a8e95cc..ec2de82 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -1103,7 +1103,17 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
for (NSTouch *touch in touches) {
const SDL_TouchID touchId = (SDL_TouchID)(intptr_t)[touch device];
- if (SDL_AddTouch(touchId, "") < 0) {
+ SDL_TouchDeviceType devtype = SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101202 /* Added in the 10.12.2 SDK. */
+ if ([touch respondsToSelector:@selector(type)]) {
+ if ([touch type] == NSTouchTypeDirect) {
+ devtype = SDL_TOUCH_DEVICE_DIRECT;
+ }
+ }
+#endif
+
+ if (SDL_AddTouch(touchId, devtype, "") < 0) {
return;
}
diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c
index 14bc240..d27608a 100644
--- a/src/video/emscripten/SDL_emscriptenevents.c
+++ b/src/video/emscripten/SDL_emscriptenevents.c
@@ -428,7 +428,7 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo
int preventDefault = 0;
SDL_TouchID deviceId = 1;
- if (SDL_AddTouch(deviceId, "") < 0) {
+ if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
return 0;
}
diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m
index caabfac..7141f9f 100644
--- a/src/video/uikit/SDL_uikitview.m
+++ b/src/video/uikit/SDL_uikitview.m
@@ -39,7 +39,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
@implementation SDL_uikitview {
SDL_Window *sdlwindow;
- SDL_TouchID touchId;
+ SDL_TouchID directTouchId;
+ SDL_TouchID indirectTouchId;
+
UITouch * __weak firstFingerDown;
}
@@ -68,12 +70,13 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.autoresizesSubviews = YES;
+ directTouchId = 1;
+ indirectTouchId = 2;
+
#if !TARGET_OS_TV
self.multipleTouchEnabled = YES;
+ SDL_AddTouch(directTouchId, SDL_TOUCH_DEVICE_DIRECT, "");
#endif
-
- touchId = 1;
- SDL_AddTouch(touchId, "");
}
return self;
@@ -135,6 +138,30 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
sdlwindow = window;
}
+- (SDL_TouchDeviceType)touchTypeForTouch:(UITouch *)touch
+{
+#ifdef __IPHONE_9_0
+ if ([touch respondsToSelector:@selector((type))]) {
+ if (touch.type == UITouchTypeIndirect) {
+ return SDL_TOUCH_DEVICE_INDIRECT_RELATIVE;
+ }
+ }
+#endif
+
+ return SDL_TOUCH_DEVICE_DIRECT;
+}
+
+- (SDL_TouchID)touchIdForType:(SDL_TouchDeviceType)type
+{
+ switch (type) {
+ case SDL_TOUCH_DEVICE_DIRECT:
+ default:
+ return directTouchId;
+ case SDL_TOUCH_DEVICE_INDIRECT_RELATIVE:
+ return indirectTouchId;
+ }
+}
+
- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
{
CGPoint point = [touch locationInView:self];
@@ -162,8 +189,14 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
+ SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch];
+ SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
+ if (SDL_AddTouch(touchId, touchType, "") < 0) {
+ continue;
+ }
+
if (!firstFingerDown) {
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
int clicks = (int) touch.tapCount;
@@ -186,8 +219,14 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
+ SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch];
+ SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
+ if (SDL_AddTouch(touchId, touchType, "") < 0) {
+ continue;
+ }
+
if (touch == firstFingerDown) {
/* send mouse up */
int clicks = (int) touch.tapCount;
@@ -209,8 +248,14 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
+ SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch];
+ SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
+ if (SDL_AddTouch(touchId, touchType, "") < 0) {
+ continue;
+ }
+
if (touch == firstFingerDown) {
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 0c953a5..5b2cbef 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -614,7 +614,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
}
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
- SDL_AddTouch(1, "wayland_touch");
+ SDL_AddTouch(1, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch");
input->touch = wl_seat_get_touch(seat);
wl_touch_set_user_data(input->touch, input);
wl_touch_add_listener(input->touch, &touch_listener,
diff --git a/src/video/wayland/SDL_waylandtouch.c b/src/video/wayland/SDL_waylandtouch.c
index 1cf37c1..e7d4b77 100644
--- a/src/video/wayland/SDL_waylandtouch.c
+++ b/src/video/wayland/SDL_waylandtouch.c
@@ -89,7 +89,7 @@ touch_handle_touch(void *data,
*/
SDL_TouchID deviceId = 1;
- if (SDL_AddTouch(deviceId, "qt_touch_extension") < 0) {
+ if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "qt_touch_extension") < 0) {
SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
}
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 77d2f7f..b8d65d2 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -932,7 +932,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
PTOUCHINPUT input = &inputs[i];
const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);
- if (SDL_AddTouch(touchId, "") < 0) {
+
+ /* TODO: Can we use GetRawInputDeviceInfo and HID info to
+ determine if this is a direct or indirect touch device?
+ */
+ if (SDL_AddTouch(touchId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
continue;
}
diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp
index bc438f2..1ab6814 100644
--- a/src/video/winrt/SDL_winrtpointerinput.cpp
+++ b/src/video/winrt/SDL_winrtpointerinput.cpp
@@ -44,7 +44,7 @@ static unsigned int WINRT_LeftFingerDown = 0;
void
WINRT_InitTouch(_THIS)
{
- SDL_AddTouch(WINRT_TouchID, "");
+ SDL_AddTouch(WINRT_TouchID, SDL_TOUCH_DEVICE_DIRECT, "");
}
diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c
index 06a8937..c2a510e 100644
--- a/src/video/x11/SDL_x11xinput2.c
+++ b/src/video/x11/SDL_x11xinput2.c
@@ -244,6 +244,7 @@ X11_InitXinput2Multitouch(_THIS)
XIDeviceInfo *dev = &info[i];
for (j = 0; j < dev->num_classes; j++) {
SDL_TouchID touchId;
+ SDL_TouchDeviceType touchType;
XIAnyClassInfo *class = dev->classes[j];
XITouchClassInfo *t = (XITouchClassInfo*)class;
@@ -251,8 +252,14 @@ X11_InitXinput2Multitouch(_THIS)
if (class->type != XITouchClass)
continue;
+ if (t->mode == XIDependentTouch) {
+ touchType = SDL_TOUCH_DEVICE_INDIRECT_RELATIVE;
+ } else { /* XIDirectTouch */
+ touchType = SDL_TOUCH_DEVICE_DIRECT;
+ }
+
touchId = t->sourceid;
- SDL_AddTouch(touchId, dev->name);
+ SDL_AddTouch(touchId, touchType, dev->name);
}
}
X11_XIFreeDeviceInfo(info);