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.
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "../SDL_internal.h"
23 /* General touch handling code for SDL */
25 #include "SDL_assert.h"
26 #include "SDL_events.h"
27 #include "SDL_events_c.h"
28 #include "../video/SDL_sysvideo.h"
31 static int SDL_num_touch = 0;
32 static SDL_Touch **SDL_touchDevices = NULL;
35 /* Public functions */
43 SDL_GetNumTouchDevices(void)
49 SDL_GetTouchDevice(int index)
51 if (index < 0 || index >= SDL_num_touch) {
52 SDL_SetError("Unknown touch device index %d", index);
55 return SDL_touchDevices[index]->id;
59 SDL_GetTouchIndex(SDL_TouchID id)
64 for (index = 0; index < SDL_num_touch; ++index) {
65 touch = SDL_touchDevices[index];
66 if (touch->id == id) {
74 SDL_GetTouch(SDL_TouchID id)
76 int index = SDL_GetTouchIndex(id);
77 if (index < 0 || index >= SDL_num_touch) {
78 if (SDL_GetVideoDevice()->ResetTouch != NULL) {
79 SDL_SetError("Unknown touch id %d, resetting", (int) id);
80 (SDL_GetVideoDevice()->ResetTouch)(SDL_GetVideoDevice());
82 SDL_SetError("Unknown touch device id %d, cannot reset", (int) id);
86 return SDL_touchDevices[index];
90 SDL_GetTouchDeviceType(SDL_TouchID id)
92 SDL_Touch *touch = SDL_GetTouch(id);
96 return SDL_TOUCH_DEVICE_INVALID;
100 SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
103 for (index = 0; index < touch->num_fingers; ++index) {
104 if (touch->fingers[index]->id == fingerid) {
112 SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id)
114 int index = SDL_GetFingerIndex(touch, id);
115 if (index < 0 || index >= touch->num_fingers) {
118 return touch->fingers[index];
122 SDL_GetNumTouchFingers(SDL_TouchID touchID)
124 SDL_Touch *touch = SDL_GetTouch(touchID);
126 return touch->num_fingers;
132 SDL_GetTouchFinger(SDL_TouchID touchID, int index)
134 SDL_Touch *touch = SDL_GetTouch(touchID);
138 if (index < 0 || index >= touch->num_fingers) {
139 SDL_SetError("Unknown touch finger");
142 return touch->fingers[index];
146 SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
148 SDL_Touch **touchDevices;
151 index = SDL_GetTouchIndex(touchID);
156 /* Add the touch to the list of touch */
157 touchDevices = (SDL_Touch **) SDL_realloc(SDL_touchDevices,
158 (SDL_num_touch + 1) * sizeof(*touchDevices));
160 return SDL_OutOfMemory();
163 SDL_touchDevices = touchDevices;
164 index = SDL_num_touch;
166 SDL_touchDevices[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchDevices[index]));
167 if (!SDL_touchDevices[index]) {
168 return SDL_OutOfMemory();
171 /* Added touch to list */
174 /* we're setting the touch properties */
175 SDL_touchDevices[index]->id = touchID;
176 SDL_touchDevices[index]->type = type;
177 SDL_touchDevices[index]->num_fingers = 0;
178 SDL_touchDevices[index]->max_fingers = 0;
179 SDL_touchDevices[index]->fingers = NULL;
181 /* Record this touch device for gestures */
182 /* We could do this on the fly in the gesture code if we wanted */
183 SDL_GestureAddTouch(touchID);
189 SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
193 if (touch->num_fingers == touch->max_fingers) {
194 SDL_Finger **new_fingers;
195 new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers+1)*sizeof(*touch->fingers));
197 return SDL_OutOfMemory();
199 touch->fingers = new_fingers;
200 touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger));
201 if (!touch->fingers[touch->max_fingers]) {
202 return SDL_OutOfMemory();
204 touch->max_fingers++;
207 finger = touch->fingers[touch->num_fingers++];
208 finger->id = fingerid;
211 finger->pressure = pressure;
216 SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid)
220 int index = SDL_GetFingerIndex(touch, fingerid);
225 touch->num_fingers--;
226 temp = touch->fingers[index];
227 touch->fingers[index] = touch->fingers[touch->num_fingers];
228 touch->fingers[touch->num_fingers] = temp;
233 SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
234 SDL_bool down, float x, float y, float pressure)
239 SDL_Touch* touch = SDL_GetTouch(id);
244 finger = SDL_GetFinger(touch, fingerid);
247 /* This finger is already down */
251 if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
256 if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
258 event.tfinger.type = SDL_FINGERDOWN;
259 event.tfinger.touchId = id;
260 event.tfinger.fingerId = fingerid;
263 event.tfinger.dx = 0;
264 event.tfinger.dy = 0;
265 event.tfinger.pressure = pressure;
266 posted = (SDL_PushEvent(&event) > 0);
270 /* This finger is already up */
275 if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
277 event.tfinger.type = SDL_FINGERUP;
278 event.tfinger.touchId = id;
279 event.tfinger.fingerId = fingerid;
280 /* I don't trust the coordinates passed on fingerUp */
281 event.tfinger.x = finger->x;
282 event.tfinger.y = finger->y;
283 event.tfinger.dx = 0;
284 event.tfinger.dy = 0;
285 event.tfinger.pressure = pressure;
286 posted = (SDL_PushEvent(&event) > 0);
289 SDL_DelFinger(touch, fingerid);
295 SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
296 float x, float y, float pressure)
301 float xrel, yrel, prel;
303 touch = SDL_GetTouch(id);
308 finger = SDL_GetFinger(touch,fingerid);
310 return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure);
313 xrel = x - finger->x;
314 yrel = y - finger->y;
315 prel = pressure - finger->pressure;
317 /* Drop events that don't change state */
318 if (!xrel && !yrel && !prel) {
320 printf("Touch event didn't change state - dropped!\n");
325 /* Update internal touch coordinates */
328 finger->pressure = pressure;
330 /* Post the event, if desired */
332 if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
334 event.tfinger.type = SDL_FINGERMOTION;
335 event.tfinger.touchId = id;
336 event.tfinger.fingerId = fingerid;
339 event.tfinger.dx = xrel;
340 event.tfinger.dy = yrel;
341 event.tfinger.pressure = pressure;
342 posted = (SDL_PushEvent(&event) > 0);
348 SDL_DelTouch(SDL_TouchID id)
351 int index = SDL_GetTouchIndex(id);
352 SDL_Touch *touch = SDL_GetTouch(id);
358 for (i = 0; i < touch->max_fingers; ++i) {
359 SDL_free(touch->fingers[i]);
361 SDL_free(touch->fingers);
365 SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch];
367 /* Delete this touch device for gestures */
368 SDL_GestureDelTouch(id);
376 for (i = SDL_num_touch; i--; ) {
377 SDL_DelTouch(SDL_touchDevices[i]->id);
379 SDL_assert(SDL_num_touch == 0);
381 SDL_free(SDL_touchDevices);
382 SDL_touchDevices = NULL;
386 /* vi: set ts=4 sw=4 expandtab: */