This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_touch.c
364 lines (310 loc) · 8.86 KB
1
2
/*
Simple DirectMedia Layer
3
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_config.h"
/* General touch handling code for SDL */
25
#include "SDL_assert.h"
26
27
28
29
30
#include "SDL_events.h"
#include "SDL_events_c.h"
static int SDL_num_touch = 0;
31
static SDL_Touch **SDL_touchDevices = NULL;
32
33
34
35
36
37
/* Public functions */
int
SDL_TouchInit(void)
{
38
return (0);
39
40
}
41
int
42
SDL_GetNumTouchDevices(void)
43
44
45
46
47
48
{
return SDL_num_touch;
}
SDL_TouchID
SDL_GetTouchDevice(int index)
49
50
{
if (index < 0 || index >= SDL_num_touch) {
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
SDL_SetError("Unknown touch device");
return 0;
}
return SDL_touchDevices[index]->id;
}
static int
SDL_GetTouchIndex(SDL_TouchID id)
{
int index;
SDL_Touch *touch;
for (index = 0; index < SDL_num_touch; ++index) {
touch = SDL_touchDevices[index];
if (touch->id == id) {
return index;
}
68
}
69
return -1;
70
71
72
}
SDL_Touch *
73
SDL_GetTouch(SDL_TouchID id)
74
{
75
int index = SDL_GetTouchIndex(id);
76
if (index < 0 || index >= SDL_num_touch) {
77
SDL_SetError("Unknown touch device");
78
79
return NULL;
}
80
return SDL_touchDevices[index];
81
82
83
}
static int
84
SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
85
{
86
87
88
89
90
91
int index;
for (index = 0; index < touch->num_fingers; ++index) {
if (touch->fingers[index]->id == fingerid) {
return index;
}
}
92
93
94
95
return -1;
}
SDL_Finger *
96
SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id)
97
{
98
99
int index = SDL_GetFingerIndex(touch, id);
if (index < 0 || index >= touch->num_fingers) {
100
return NULL;
101
}
102
103
104
105
return touch->fingers[index];
}
int
106
SDL_GetNumTouchFingers(SDL_TouchID touchID)
107
{
108
109
110
111
112
113
SDL_Touch *touch = SDL_GetTouch(touchID);
if (touch) {
return touch->num_fingers;
}
return 0;
}
114
115
116
117
118
119
120
SDL_Finger *
SDL_GetTouchFinger(SDL_TouchID touchID, int index)
{
SDL_Touch *touch = SDL_GetTouch(touchID);
if (!touch) {
return NULL;
121
}
122
123
124
125
126
if (index < 0 || index >= touch->num_fingers) {
SDL_SetError("Unknown touch finger");
return NULL;
}
return touch->fingers[index];
127
128
129
}
int
130
SDL_AddTouch(SDL_TouchID touchID, const char *name)
131
{
132
SDL_Touch **touchDevices;
133
134
int index;
135
136
137
index = SDL_GetTouchIndex(touchID);
if (index >= 0) {
return index;
138
139
140
}
/* Add the touch to the list of touch */
141
142
143
touchDevices = (SDL_Touch **) SDL_realloc(SDL_touchDevices,
(SDL_num_touch + 1) * sizeof(*touchDevices));
if (!touchDevices) {
144
return SDL_OutOfMemory();
145
146
}
147
SDL_touchDevices = touchDevices;
148
149
index = SDL_num_touch++;
150
151
SDL_touchDevices[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchDevices[index]));
if (!SDL_touchDevices[index]) {
152
return SDL_OutOfMemory();
153
154
155
}
/* we're setting the touch properties */
156
157
158
159
SDL_touchDevices[index]->id = touchID;
SDL_touchDevices[index]->num_fingers = 0;
SDL_touchDevices[index]->max_fingers = 0;
SDL_touchDevices[index]->fingers = NULL;
160
161
162
163
/* Record this touch device for gestures */
/* We could do this on the fly in the gesture code if we wanted */
SDL_GestureAddTouch(touchID);
164
165
return index;
166
167
}
168
static int
169
SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
170
{
171
SDL_Finger *finger;
172
173
174
175
176
if (touch->num_fingers == touch->max_fingers) {
SDL_Finger **new_fingers;
new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers+1)*sizeof(*touch->fingers));
if (!new_fingers) {
177
return SDL_OutOfMemory();
178
}
179
180
181
touch->fingers = new_fingers;
touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger));
if (!touch->fingers[touch->max_fingers]) {
182
return SDL_OutOfMemory();
183
}
184
touch->max_fingers++;
185
186
}
187
188
189
190
191
192
finger = touch->fingers[touch->num_fingers++];
finger->id = fingerid;
finger->x = x;
finger->y = y;
finger->pressure = pressure;
return 0;
193
194
}
195
196
static int
SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid)
197
{
198
SDL_Finger *temp;
199
200
201
int index = SDL_GetFingerIndex(touch, fingerid);
if (index < 0) {
202
203
204
205
return -1;
}
touch->num_fingers--;
206
temp = touch->fingers[index];
207
touch->fingers[index] = touch->fingers[touch->num_fingers];
208
touch->fingers[touch->num_fingers] = temp;
209
210
211
212
return 0;
}
int
213
214
SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
SDL_bool down, float x, float y, float pressure)
215
216
{
int posted;
217
SDL_Finger *finger;
218
219
SDL_Touch* touch = SDL_GetTouch(id);
220
221
if (!touch) {
return -1;
222
223
}
224
225
226
227
228
229
230
231
232
finger = SDL_GetFinger(touch, fingerid);
if (down) {
if (finger) {
/* This finger is already down */
return 0;
}
if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
return 0;
233
}
234
235
236
237
238
239
posted = 0;
if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
SDL_Event event;
event.tfinger.type = SDL_FINGERDOWN;
event.tfinger.touchId = id;
240
event.tfinger.fingerId = fingerid;
241
242
243
244
245
246
247
event.tfinger.x = x;
event.tfinger.y = y;
event.tfinger.dx = 0;
event.tfinger.dy = 0;
event.tfinger.pressure = pressure;
posted = (SDL_PushEvent(&event) > 0);
}
248
249
250
} else {
if (!finger) {
/* This finger is already up */
251
return 0;
252
253
}
254
255
256
257
258
259
posted = 0;
if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
SDL_Event event;
event.tfinger.type = SDL_FINGERUP;
event.tfinger.touchId = id;
event.tfinger.fingerId = fingerid;
260
/* I don't trust the coordinates passed on fingerUp */
261
event.tfinger.x = finger->x;
262
263
264
265
266
event.tfinger.y = finger->y;
event.tfinger.dx = 0;
event.tfinger.dy = 0;
event.tfinger.pressure = pressure;
posted = (SDL_PushEvent(&event) > 0);
267
268
269
}
SDL_DelFinger(touch, fingerid);
270
}
271
return posted;
272
273
274
}
int
275
276
SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
float x, float y, float pressure)
277
278
279
280
{
SDL_Touch *touch;
SDL_Finger *finger;
int posted;
281
282
float xrel, yrel, prel;
283
284
touch = SDL_GetTouch(id);
if (!touch) {
285
return -1;
286
287
288
}
finger = SDL_GetFinger(touch,fingerid);
289
if (!finger) {
290
return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure);
291
292
}
293
294
295
xrel = x - finger->x;
yrel = y - finger->y;
prel = pressure - finger->pressure;
296
297
298
299
300
301
/* Drop events that don't change state */
if (!xrel && !yrel && !prel) {
#if 0
printf("Touch event didn't change state - dropped!\n");
#endif
302
303
304
return 0;
}
305
306
307
308
/* Update internal touch coordinates */
finger->x = x;
finger->y = y;
finger->pressure = pressure;
309
310
311
/* Post the event, if desired */
posted = 0;
312
if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
313
SDL_Event event;
314
315
316
317
318
319
event.tfinger.type = SDL_FINGERMOTION;
event.tfinger.touchId = id;
event.tfinger.fingerId = fingerid;
event.tfinger.x = x;
event.tfinger.y = y;
event.tfinger.dx = xrel;
320
event.tfinger.dy = yrel;
321
event.tfinger.pressure = pressure;
322
323
324
325
326
posted = (SDL_PushEvent(&event) > 0);
}
return posted;
}
327
328
void
SDL_DelTouch(SDL_TouchID id)
329
{
330
331
int i;
int index = SDL_GetTouchIndex(id);
332
SDL_Touch *touch = SDL_GetTouch(id);
333
334
if (!touch) {
335
336
337
338
339
return;
}
for (i = 0; i < touch->max_fingers; ++i) {
SDL_free(touch->fingers[i]);
340
}
341
342
343
344
345
SDL_free(touch->fingers);
SDL_free(touch);
SDL_num_touch--;
SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch];
346
347
}
348
349
350
351
352
353
354
355
356
357
358
359
360
361
void
SDL_TouchQuit(void)
{
int i;
for (i = SDL_num_touch; i--; ) {
SDL_DelTouch(SDL_touchDevices[i]->id);
}
SDL_assert(SDL_num_touch == 0);
if (SDL_touchDevices) {
SDL_free(SDL_touchDevices);
SDL_touchDevices = NULL;
}
362
}
363
364
/* vi: set ts=4 sw=4 expandtab: */