SDL  2.0
SDL_touch.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
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.
8 
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:
12 
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.
20 */
21 #include "../SDL_internal.h"
22 
23 /* General touch handling code for SDL */
24 
25 #include "SDL_assert.h"
26 #include "SDL_events.h"
27 #include "SDL_events_c.h"
28 #include "../video/SDL_sysvideo.h"
29 
30 
31 static int SDL_num_touch = 0;
33 
34 
35 /* Public functions */
36 int
38 {
39  return (0);
40 }
41 
42 int
44 {
45  return SDL_num_touch;
46 }
47 
50 {
52  SDL_SetError("Unknown touch device index %d", index);
53  return 0;
54  }
55  return SDL_touchDevices[index]->id;
56 }
57 
58 static int
60 {
61  int index;
62  SDL_Touch *touch;
63 
64  for (index = 0; index < SDL_num_touch; ++index) {
65  touch = SDL_touchDevices[index];
66  if (touch->id == id) {
67  return index;
68  }
69  }
70  return -1;
71 }
72 
73 SDL_Touch *
75 {
76  int index = SDL_GetTouchIndex(id);
78  if (SDL_GetVideoDevice()->ResetTouch != NULL) {
79  SDL_SetError("Unknown touch id %d, resetting", (int) id);
81  } else {
82  SDL_SetError("Unknown touch device id %d, cannot reset", (int) id);
83  }
84  return NULL;
85  }
86  return SDL_touchDevices[index];
87 }
88 
89 static int
90 SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
91 {
92  int index;
93  for (index = 0; index < touch->num_fingers; ++index) {
94  if (touch->fingers[index]->id == fingerid) {
95  return index;
96  }
97  }
98  return -1;
99 }
100 
101 static SDL_Finger *
103 {
104  int index = SDL_GetFingerIndex(touch, id);
105  if (index < 0 || index >= touch->num_fingers) {
106  return NULL;
107  }
108  return touch->fingers[index];
109 }
110 
111 int
113 {
114  SDL_Touch *touch = SDL_GetTouch(touchID);
115  if (touch) {
116  return touch->num_fingers;
117  }
118  return 0;
119 }
120 
121 SDL_Finger *
123 {
124  SDL_Touch *touch = SDL_GetTouch(touchID);
125  if (!touch) {
126  return NULL;
127  }
128  if (index < 0 || index >= touch->num_fingers) {
129  SDL_SetError("Unknown touch finger");
130  return NULL;
131  }
132  return touch->fingers[index];
133 }
134 
135 int
136 SDL_AddTouch(SDL_TouchID touchID, const char *name)
137 {
138  SDL_Touch **touchDevices;
139  int index;
140 
141  index = SDL_GetTouchIndex(touchID);
142  if (index >= 0) {
143  return index;
144  }
145 
146  /* Add the touch to the list of touch */
147  touchDevices = (SDL_Touch **) SDL_realloc(SDL_touchDevices,
148  (SDL_num_touch + 1) * sizeof(*touchDevices));
149  if (!touchDevices) {
150  return SDL_OutOfMemory();
151  }
152 
153  SDL_touchDevices = touchDevices;
155 
157  if (!SDL_touchDevices[index]) {
158  return SDL_OutOfMemory();
159  }
160 
161  /* Added touch to list */
162  ++SDL_num_touch;
163 
164  /* we're setting the touch properties */
165  SDL_touchDevices[index]->id = touchID;
169 
170  /* Record this touch device for gestures */
171  /* We could do this on the fly in the gesture code if we wanted */
172  SDL_GestureAddTouch(touchID);
173 
174  return index;
175 }
176 
177 static int
178 SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
179 {
180  SDL_Finger *finger;
181 
182  if (touch->num_fingers == touch->max_fingers) {
183  SDL_Finger **new_fingers;
184  new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers+1)*sizeof(*touch->fingers));
185  if (!new_fingers) {
186  return SDL_OutOfMemory();
187  }
188  touch->fingers = new_fingers;
189  touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger));
190  if (!touch->fingers[touch->max_fingers]) {
191  return SDL_OutOfMemory();
192  }
193  touch->max_fingers++;
194  }
195 
196  finger = touch->fingers[touch->num_fingers++];
197  finger->id = fingerid;
198  finger->x = x;
199  finger->y = y;
200  finger->pressure = pressure;
201  return 0;
202 }
203 
204 static int
206 {
207  SDL_Finger *temp;
208 
209  int index = SDL_GetFingerIndex(touch, fingerid);
210  if (index < 0) {
211  return -1;
212  }
213 
214  touch->num_fingers--;
215  temp = touch->fingers[index];
216  touch->fingers[index] = touch->fingers[touch->num_fingers];
217  touch->fingers[touch->num_fingers] = temp;
218  return 0;
219 }
220 
221 int
223  SDL_bool down, float x, float y, float pressure)
224 {
225  int posted;
226  SDL_Finger *finger;
227 
228  SDL_Touch* touch = SDL_GetTouch(id);
229  if (!touch) {
230  return -1;
231  }
232 
233  finger = SDL_GetFinger(touch, fingerid);
234  if (down) {
235  if (finger) {
236  /* This finger is already down */
237  return 0;
238  }
239 
240  if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
241  return 0;
242  }
243 
244  posted = 0;
247  event.tfinger.type = SDL_FINGERDOWN;
248  event.tfinger.touchId = id;
249  event.tfinger.fingerId = fingerid;
250  event.tfinger.x = x;
251  event.tfinger.y = y;
252  event.tfinger.dx = 0;
253  event.tfinger.dy = 0;
254  event.tfinger.pressure = pressure;
255  posted = (SDL_PushEvent(&event) > 0);
256  }
257  } else {
258  if (!finger) {
259  /* This finger is already up */
260  return 0;
261  }
262 
263  posted = 0;
266  event.tfinger.type = SDL_FINGERUP;
267  event.tfinger.touchId = id;
268  event.tfinger.fingerId = fingerid;
269  /* I don't trust the coordinates passed on fingerUp */
270  event.tfinger.x = finger->x;
271  event.tfinger.y = finger->y;
272  event.tfinger.dx = 0;
273  event.tfinger.dy = 0;
274  event.tfinger.pressure = pressure;
275  posted = (SDL_PushEvent(&event) > 0);
276  }
277 
278  SDL_DelFinger(touch, fingerid);
279  }
280  return posted;
281 }
282 
283 int
285  float x, float y, float pressure)
286 {
287  SDL_Touch *touch;
288  SDL_Finger *finger;
289  int posted;
290  float xrel, yrel, prel;
291 
292  touch = SDL_GetTouch(id);
293  if (!touch) {
294  return -1;
295  }
296 
297  finger = SDL_GetFinger(touch,fingerid);
298  if (!finger) {
299  return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure);
300  }
301 
302  xrel = x - finger->x;
303  yrel = y - finger->y;
304  prel = pressure - finger->pressure;
305 
306  /* Drop events that don't change state */
307  if (!xrel && !yrel && !prel) {
308 #if 0
309  printf("Touch event didn't change state - dropped!\n");
310 #endif
311  return 0;
312  }
313 
314  /* Update internal touch coordinates */
315  finger->x = x;
316  finger->y = y;
317  finger->pressure = pressure;
318 
319  /* Post the event, if desired */
320  posted = 0;
323  event.tfinger.type = SDL_FINGERMOTION;
324  event.tfinger.touchId = id;
325  event.tfinger.fingerId = fingerid;
326  event.tfinger.x = x;
327  event.tfinger.y = y;
328  event.tfinger.dx = xrel;
329  event.tfinger.dy = yrel;
330  event.tfinger.pressure = pressure;
331  posted = (SDL_PushEvent(&event) > 0);
332  }
333  return posted;
334 }
335 
336 void
338 {
339  int i;
340  int index = SDL_GetTouchIndex(id);
341  SDL_Touch *touch = SDL_GetTouch(id);
342 
343  if (!touch) {
344  return;
345  }
346 
347  for (i = 0; i < touch->max_fingers; ++i) {
348  SDL_free(touch->fingers[i]);
349  }
350  SDL_free(touch->fingers);
351  SDL_free(touch);
352 
353  SDL_num_touch--;
355 
356  /* Delete this touch device for gestures */
358 }
359 
360 void
362 {
363  int i;
364 
365  for (i = SDL_num_touch; i--; ) {
367  }
369 
372  SDL_GestureQuit();
373 }
374 
375 /* vi: set ts=4 sw=4 expandtab: */
SDL_num_touch
static int SDL_num_touch
Definition: SDL_touch.c:31
SDL_events.h
NULL
#define NULL
Definition: begin_code.h:164
SDL_GetTouchDevice
SDL_TouchID SDL_GetTouchDevice(int index)
Get the touch ID with the given index, or 0 if the index is invalid.
Definition: SDL_touch.c:49
SDL_FingerID
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
SDL_GetFinger
static SDL_Finger * SDL_GetFinger(const SDL_Touch *touch, SDL_FingerID id)
Definition: SDL_touch.c:102
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:756
SDL_DelFinger
static int SDL_DelFinger(SDL_Touch *touch, SDL_FingerID fingerid)
Definition: SDL_touch.c:205
SDL_VideoDevice::ResetTouch
void(* ResetTouch)(_THIS)
Definition: SDL_sysvideo.h:172
SDL_SendTouch
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:222
index
GLuint index
Definition: SDL_opengl_glext.h:660
SDL_SendTouchMotion
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:284
SDL_Finger
Definition: SDL_touch.h:45
SDL_FINGERUP
@ SDL_FINGERUP
Definition: SDL_events.h:129
SDL_GetTouchIndex
static int SDL_GetTouchIndex(SDL_TouchID id)
Definition: SDL_touch.c:59
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_FINGERDOWN
@ SDL_FINGERDOWN
Definition: SDL_events.h:128
SDL_GestureQuit
void SDL_GestureQuit()
Definition: SDL_gesture.c:104
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:769
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_GetNumTouchFingers
int SDL_GetNumTouchFingers(SDL_TouchID touchID)
Get the number of active fingers for a given touch device.
Definition: SDL_touch.c:112
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:125
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
SDL_GestureDelTouch
int SDL_GestureDelTouch(SDL_TouchID touchId)
Definition: SDL_gesture.c:466
SDL_assert.h
SDL_FINGERMOTION
@ SDL_FINGERMOTION
Definition: SDL_events.h:130
SDL_Touch::num_fingers
int num_fingers
Definition: SDL_touch_c.h:30
SDL_Touch::fingers
SDL_Finger ** fingers
Definition: SDL_touch_c.h:32
SDL_AddTouch
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
Definition: SDL_touch.c:136
SDL_GetTouchFinger
SDL_Finger * SDL_GetTouchFinger(SDL_TouchID touchID, int index)
Get the finger object of the given touch, with the given index.
Definition: SDL_touch.c:122
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_DelTouch
void SDL_DelTouch(SDL_TouchID id)
Definition: SDL_touch.c:337
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_AddFinger
static int SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:178
SDL_TouchID
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_GestureAddTouch
int SDL_GestureAddTouch(SDL_TouchID touchId)
Definition: SDL_gesture.c:448
id
GLuint id
Definition: SDL_opengl_glext.h:528
SDL_Touch
Definition: SDL_touch_c.h:28
SDL_Touch::max_fingers
int max_fingers
Definition: SDL_touch_c.h:31
SDL_Touch::id
SDL_TouchID id
Definition: SDL_touch_c.h:29
SDL_Finger::y
float y
Definition: SDL_touch.h:48
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_Finger::pressure
float pressure
Definition: SDL_touch.h:49
SDL_GetNumTouchDevices
int SDL_GetNumTouchDevices(void)
Get the number of registered touch devices.
Definition: SDL_touch.c:43
SDL_touchDevices
static SDL_Touch ** SDL_touchDevices
Definition: SDL_touch.c:32
SDL_events_c.h
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_Finger::id
SDL_FingerID id
Definition: SDL_touch.h:46
SDL_Event
General event structure.
Definition: SDL_events.h:558
SDL_GetVideoDevice
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
SDL_Finger::x
float x
Definition: SDL_touch.h:47
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_TouchQuit
void SDL_TouchQuit(void)
Definition: SDL_touch.c:361
SDL_GetFingerIndex
static int SDL_GetFingerIndex(const SDL_Touch *touch, SDL_FingerID fingerid)
Definition: SDL_touch.c:90
SDL_TouchInit
int SDL_TouchInit(void)
Definition: SDL_touch.c:37
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_GetTouch
SDL_Touch * SDL_GetTouch(SDL_TouchID id)
Definition: SDL_touch.c:74