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