Atlas - SDL_touch.c
Home / ext / SDL2 / src / events Lines: 2 | Size: 9502 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 31static int SDL_num_touch = 0; 32static SDL_Touch **SDL_touchDevices = NULL; 33 34 35/* Public functions */ 36int 37SDL_TouchInit(void) 38{ 39 return (0); 40} 41 42int 43SDL_GetNumTouchDevices(void) 44{ 45 return SDL_num_touch; 46} 47 48SDL_TouchID 49SDL_GetTouchDevice(int index) 50{ 51 if (index < 0 || index >= SDL_num_touch) { 52 SDL_SetError("Unknown touch device index %d", index); 53 return 0; 54 } 55 return SDL_touchDevices[index]->id; 56} 57 58static int 59SDL_GetTouchIndex(SDL_TouchID id) 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 73SDL_Touch * 74SDL_GetTouch(SDL_TouchID id) 75{ 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()); 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 89static int 90SDL_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 101static SDL_Finger * 102SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id) 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 111int 112SDL_GetNumTouchFingers(SDL_TouchID touchID) 113{ 114 SDL_Touch *touch = SDL_GetTouch(touchID); 115 if (touch) { 116 return touch->num_fingers; 117 } 118 return 0; 119} 120 121SDL_Finger * 122SDL_GetTouchFinger(SDL_TouchID touchID, int index) 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 135int 136SDL_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; 154 index = SDL_num_touch; 155 156 SDL_touchDevices[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchDevices[index])); 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; 166 SDL_touchDevices[index]->num_fingers = 0; 167 SDL_touchDevices[index]->max_fingers = 0; 168 SDL_touchDevices[index]->fingers = NULL; 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 177static int 178SDL_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 204static int 205SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid) 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 221int 222SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, 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; 245 if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) { 246 SDL_Event event; 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; 264 if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) { 265 SDL_Event event; 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 283int 284SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, 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; 321 if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) { 322 SDL_Event event; 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 336void 337SDL_DelTouch(SDL_TouchID id) 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--; 354 SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch]; 355 356 /* Delete this touch device for gestures */ 357 SDL_GestureDelTouch(id); 358} 359 360void 361SDL_TouchQuit(void) 362{ 363 int i; 364 365 for (i = SDL_num_touch; i--; ) { 366 SDL_DelTouch(SDL_touchDevices[i]->id); 367 } 368 SDL_assert(SDL_num_touch == 0); 369 370 SDL_free(SDL_touchDevices); 371 SDL_touchDevices = NULL; 372 SDL_GestureQuit(); 373} 374 375/* vi: set ts=4 sw=4 expandtab: */ 376[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.