summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/events/SDL_touch.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/events/SDL_touch.c')
-rw-r--r--source/3rd-party/SDL2/src/events/SDL_touch.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/events/SDL_touch.c b/source/3rd-party/SDL2/src/events/SDL_touch.c
new file mode 100644
index 0000000..0037416
--- /dev/null
+++ b/source/3rd-party/SDL2/src/events/SDL_touch.c
@@ -0,0 +1,375 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ 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_internal.h"
+
+/* General touch handling code for SDL */
+
+#include "SDL_assert.h"
+#include "SDL_events.h"
+#include "SDL_events_c.h"
+#include "../video/SDL_sysvideo.h"
+
+
+static int SDL_num_touch = 0;
+static SDL_Touch **SDL_touchDevices = NULL;
+
+
+/* Public functions */
+int
+SDL_TouchInit(void)
+{
+ return (0);
+}
+
+int
+SDL_GetNumTouchDevices(void)
+{
+ return SDL_num_touch;
+}
+
+SDL_TouchID
+SDL_GetTouchDevice(int index)
+{
+ if (index < 0 || index >= SDL_num_touch) {
+ SDL_SetError("Unknown touch device index %d", index);
+ 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;
+ }
+ }
+ return -1;
+}
+
+SDL_Touch *
+SDL_GetTouch(SDL_TouchID id)
+{
+ int index = SDL_GetTouchIndex(id);
+ if (index < 0 || index >= SDL_num_touch) {
+ if (SDL_GetVideoDevice()->ResetTouch != NULL) {
+ SDL_SetError("Unknown touch id %d, resetting", (int) id);
+ (SDL_GetVideoDevice()->ResetTouch)(SDL_GetVideoDevice());
+ } else {
+ SDL_SetError("Unknown touch device id %d, cannot reset", (int) id);
+ }
+ return NULL;
+ }
+ return SDL_touchDevices[index];
+}
+
+static int
+SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
+{
+ int index;
+ for (index = 0; index < touch->num_fingers; ++index) {
+ if (touch->fingers[index]->id == fingerid) {
+ return index;
+ }
+ }
+ return -1;
+}
+
+static SDL_Finger *
+SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id)
+{
+ int index = SDL_GetFingerIndex(touch, id);
+ if (index < 0 || index >= touch->num_fingers) {
+ return NULL;
+ }
+ return touch->fingers[index];
+}
+
+int
+SDL_GetNumTouchFingers(SDL_TouchID touchID)
+{
+ SDL_Touch *touch = SDL_GetTouch(touchID);
+ if (touch) {
+ return touch->num_fingers;
+ }
+ return 0;
+}
+
+SDL_Finger *
+SDL_GetTouchFinger(SDL_TouchID touchID, int index)
+{
+ SDL_Touch *touch = SDL_GetTouch(touchID);
+ if (!touch) {
+ return NULL;
+ }
+ if (index < 0 || index >= touch->num_fingers) {
+ SDL_SetError("Unknown touch finger");
+ return NULL;
+ }
+ return touch->fingers[index];
+}
+
+int
+SDL_AddTouch(SDL_TouchID touchID, const char *name)
+{
+ SDL_Touch **touchDevices;
+ int index;
+
+ index = SDL_GetTouchIndex(touchID);
+ if (index >= 0) {
+ return index;
+ }
+
+ /* Add the touch to the list of touch */
+ touchDevices = (SDL_Touch **) SDL_realloc(SDL_touchDevices,
+ (SDL_num_touch + 1) * sizeof(*touchDevices));
+ if (!touchDevices) {
+ return SDL_OutOfMemory();
+ }
+
+ SDL_touchDevices = touchDevices;
+ index = SDL_num_touch;
+
+ SDL_touchDevices[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchDevices[index]));
+ if (!SDL_touchDevices[index]) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Added touch to list */
+ ++SDL_num_touch;
+
+ /* we're setting the touch properties */
+ SDL_touchDevices[index]->id = touchID;
+ SDL_touchDevices[index]->num_fingers = 0;
+ SDL_touchDevices[index]->max_fingers = 0;
+ SDL_touchDevices[index]->fingers = NULL;
+
+ /* Record this touch device for gestures */
+ /* We could do this on the fly in the gesture code if we wanted */
+ SDL_GestureAddTouch(touchID);
+
+ return index;
+}
+
+static int
+SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
+{
+ SDL_Finger *finger;
+
+ 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) {
+ return SDL_OutOfMemory();
+ }
+ touch->fingers = new_fingers;
+ touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger));
+ if (!touch->fingers[touch->max_fingers]) {
+ return SDL_OutOfMemory();
+ }
+ touch->max_fingers++;
+ }
+
+ finger = touch->fingers[touch->num_fingers++];
+ finger->id = fingerid;
+ finger->x = x;
+ finger->y = y;
+ finger->pressure = pressure;
+ return 0;
+}
+
+static int
+SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid)
+{
+ SDL_Finger *temp;
+
+ int index = SDL_GetFingerIndex(touch, fingerid);
+ if (index < 0) {
+ return -1;
+ }
+
+ touch->num_fingers--;
+ temp = touch->fingers[index];
+ touch->fingers[index] = touch->fingers[touch->num_fingers];
+ touch->fingers[touch->num_fingers] = temp;
+ return 0;
+}
+
+int
+SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
+ SDL_bool down, float x, float y, float pressure)
+{
+ int posted;
+ SDL_Finger *finger;
+
+ SDL_Touch* touch = SDL_GetTouch(id);
+ if (!touch) {
+ return -1;
+ }
+
+ 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;
+ }
+
+ posted = 0;
+ if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
+ SDL_Event event;
+ event.tfinger.type = SDL_FINGERDOWN;
+ event.tfinger.touchId = id;
+ event.tfinger.fingerId = fingerid;
+ 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);
+ }
+ } else {
+ if (!finger) {
+ /* This finger is already up */
+ return 0;
+ }
+
+ 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;
+ /* I don't trust the coordinates passed on fingerUp */
+ event.tfinger.x = finger->x;
+ event.tfinger.y = finger->y;
+ event.tfinger.dx = 0;
+ event.tfinger.dy = 0;
+ event.tfinger.pressure = pressure;
+ posted = (SDL_PushEvent(&event) > 0);
+ }
+
+ SDL_DelFinger(touch, fingerid);
+ }
+ return posted;
+}
+
+int
+SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
+ float x, float y, float pressure)
+{
+ SDL_Touch *touch;
+ SDL_Finger *finger;
+ int posted;
+ float xrel, yrel, prel;
+
+ touch = SDL_GetTouch(id);
+ if (!touch) {
+ return -1;
+ }
+
+ finger = SDL_GetFinger(touch,fingerid);
+ if (!finger) {
+ return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure);
+ }
+
+ xrel = x - finger->x;
+ yrel = y - finger->y;
+ prel = pressure - finger->pressure;
+
+ /* Drop events that don't change state */
+ if (!xrel && !yrel && !prel) {
+#if 0
+ printf("Touch event didn't change state - dropped!\n");
+#endif
+ return 0;
+ }
+
+ /* Update internal touch coordinates */
+ finger->x = x;
+ finger->y = y;
+ finger->pressure = pressure;
+
+ /* Post the event, if desired */
+ posted = 0;
+ if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
+ SDL_Event event;
+ 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;
+ event.tfinger.dy = yrel;
+ event.tfinger.pressure = pressure;
+ posted = (SDL_PushEvent(&event) > 0);
+ }
+ return posted;
+}
+
+void
+SDL_DelTouch(SDL_TouchID id)
+{
+ int i;
+ int index = SDL_GetTouchIndex(id);
+ SDL_Touch *touch = SDL_GetTouch(id);
+
+ if (!touch) {
+ return;
+ }
+
+ for (i = 0; i < touch->max_fingers; ++i) {
+ SDL_free(touch->fingers[i]);
+ }
+ SDL_free(touch->fingers);
+ SDL_free(touch);
+
+ SDL_num_touch--;
+ SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch];
+
+ /* Delete this touch device for gestures */
+ SDL_GestureDelTouch(id);
+}
+
+void
+SDL_TouchQuit(void)
+{
+ int i;
+
+ for (i = SDL_num_touch; i--; ) {
+ SDL_DelTouch(SDL_touchDevices[i]->id);
+ }
+ SDL_assert(SDL_num_touch == 0);
+
+ SDL_free(SDL_touchDevices);
+ SDL_touchDevices = NULL;
+ SDL_GestureQuit();
+}
+
+/* vi: set ts=4 sw=4 expandtab: */