SDL  2.0
SDL_gesture.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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 
22 #include "../SDL_internal.h"
23 
24 /* General gesture handling code for SDL */
25 
26 #include "SDL_events.h"
27 #include "SDL_endian.h"
28 #include "SDL_events_c.h"
29 #include "SDL_gesture_c.h"
30 
31 /*
32 #include <stdio.h>
33 */
34 
35 /* TODO: Replace with malloc */
36 
37 #define MAXPATHSIZE 1024
38 
39 #define ENABLE_DOLLAR
40 
41 #define DOLLARNPOINTS 64
42 
43 #if defined(ENABLE_DOLLAR)
44 # define DOLLARSIZE 256
45 # define PHI 0.618033989
46 #endif
47 
48 typedef struct {
49  float x,y;
51 
52 typedef struct {
53  float length;
54 
55  int numPoints;
58 
59 typedef struct {
61  unsigned long hash;
63 
64 typedef struct {
69 
72 
75 
77 static int SDL_numGestureTouches = 0;
79 
80 #if 0
81 static void PrintPath(SDL_FloatPoint *path)
82 {
83  int i;
84  printf("Path:");
85  for (i=0; i<DOLLARNPOINTS; i++) {
86  printf(" (%f,%f)",path[i].x,path[i].y);
87  }
88  printf("\n");
89 }
90 #endif
91 
93 {
94  int i;
95  if (touchId < 0) recordAll = SDL_TRUE;
96  for (i = 0; i < SDL_numGestureTouches; i++) {
97  if ((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
99  if (touchId >= 0)
100  return 1;
101  }
102  }
103  return (touchId < 0);
104 }
105 
107 {
110 }
111 
112 static unsigned long SDL_HashDollar(SDL_FloatPoint* points)
113 {
114  unsigned long hash = 5381;
115  int i;
116  for (i = 0; i < DOLLARNPOINTS; i++) {
117  hash = ((hash<<5) + hash) + (unsigned long)points[i].x;
118  hash = ((hash<<5) + hash) + (unsigned long)points[i].y;
119  }
120  return hash;
121 }
122 
123 
125 {
126  if (dst == NULL) {
127  return 0;
128  }
129 
130  /* No Longer storing the Hash, rehash on load */
131  /* if (SDL_RWops.write(dst, &(templ->hash), sizeof(templ->hash), 1) != 1) return 0; */
132 
133 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
134  if (SDL_RWwrite(dst, templ->path,
135  sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
136  return 0;
137  }
138 #else
139  {
140  SDL_DollarTemplate copy = *templ;
141  SDL_FloatPoint *p = copy.path;
142  int i;
143  for (i = 0; i < DOLLARNPOINTS; i++, p++) {
144  p->x = SDL_SwapFloatLE(p->x);
145  p->y = SDL_SwapFloatLE(p->y);
146  }
147 
148  if (SDL_RWwrite(dst, copy.path,
149  sizeof(copy.path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
150  return 0;
151  }
152  }
153 #endif
154 
155  return 1;
156 }
157 
158 
160 {
161  int i,j,rtrn = 0;
162  for (i = 0; i < SDL_numGestureTouches; i++) {
164  for (j = 0; j < touch->numDollarTemplates; j++) {
165  rtrn += SaveTemplate(&touch->dollarTemplate[j], dst);
166  }
167  }
168  return rtrn;
169 }
170 
172 {
173  int i,j;
174  for (i = 0; i < SDL_numGestureTouches; i++) {
176  for (j = 0; j < touch->numDollarTemplates; j++) {
177  if (touch->dollarTemplate[j].hash == gestureId) {
178  return SaveTemplate(&touch->dollarTemplate[j], dst);
179  }
180  }
181  }
182  return SDL_SetError("Unknown gestureId");
183 }
184 
185 /* path is an already sampled set of points
186 Returns the index of the gesture on success, or -1 */
188 {
189  SDL_DollarTemplate* dollarTemplate;
190  SDL_DollarTemplate *templ;
191  int index;
192 
193  index = inTouch->numDollarTemplates;
194  dollarTemplate =
196  (index + 1) *
197  sizeof(SDL_DollarTemplate));
198  if (!dollarTemplate) {
199  return SDL_OutOfMemory();
200  }
201  inTouch->dollarTemplate = dollarTemplate;
202 
203  templ = &inTouch->dollarTemplate[index];
204  SDL_memcpy(templ->path, path, DOLLARNPOINTS*sizeof(SDL_FloatPoint));
205  templ->hash = SDL_HashDollar(templ->path);
206  inTouch->numDollarTemplates++;
207 
208  return index;
209 }
210 
212 {
213  int index = -1;
214  int i = 0;
215  if (inTouch == NULL) {
216  if (SDL_numGestureTouches == 0) return SDL_SetError("no gesture touch devices registered");
217  for (i = 0; i < SDL_numGestureTouches; i++) {
218  inTouch = &SDL_gestureTouch[i];
219  index = SDL_AddDollarGesture_one(inTouch, path);
220  if (index < 0)
221  return -1;
222  }
223  /* Use the index of the last one added. */
224  return index;
225  }
226  return SDL_AddDollarGesture_one(inTouch, path);
227 }
228 
230 {
231  int i,loaded = 0;
232  SDL_GestureTouch *touch = NULL;
233  if (src == NULL) return 0;
234  if (touchId >= 0) {
235  for (i = 0; i < SDL_numGestureTouches; i++) {
236  if (SDL_gestureTouch[i].id == touchId) {
237  touch = &SDL_gestureTouch[i];
238  }
239  }
240  if (touch == NULL) {
241  return SDL_SetError("given touch id not found");
242  }
243  }
244 
245  while (1) {
246  SDL_DollarTemplate templ;
247 
248  if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < DOLLARNPOINTS) {
249  if (loaded == 0) {
250  return SDL_SetError("could not read any dollar gesture from rwops");
251  }
252  break;
253  }
254 
255 #if SDL_BYTEORDER != SDL_LIL_ENDIAN
256  for (i = 0; i < DOLLARNPOINTS; i++) {
257  SDL_FloatPoint *p = &templ.path[i];
258  p->x = SDL_SwapFloatLE(p->x);
259  p->y = SDL_SwapFloatLE(p->y);
260  }
261 #endif
262 
263  if (touchId >= 0) {
264  /* printf("Adding loaded gesture to 1 touch\n"); */
265  if (SDL_AddDollarGesture(touch, templ.path) >= 0)
266  loaded++;
267  }
268  else {
269  /* printf("Adding to: %i touches\n",SDL_numGestureTouches); */
270  for (i = 0; i < SDL_numGestureTouches; i++) {
271  touch = &SDL_gestureTouch[i];
272  /* printf("Adding loaded gesture to + touches\n"); */
273  /* TODO: What if this fails? */
274  SDL_AddDollarGesture(touch,templ.path);
275  }
276  loaded++;
277  }
278  }
279 
280  return loaded;
281 }
282 
283 
284 #if defined(ENABLE_DOLLAR)
285 static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang)
286 {
287  /* SDL_FloatPoint p[DOLLARNPOINTS]; */
288  float dist = 0;
290  int i;
291  for (i = 0; i < DOLLARNPOINTS; i++) {
292  p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
293  p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
294  dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
295  (p.y-templ[i].y)*(p.y-templ[i].y)));
296  }
297  return dist/DOLLARNPOINTS;
298 
299 }
300 
302 {
303  /*------------BEGIN DOLLAR BLACKBOX------------------
304  -TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-
305  -"http://depts.washington.edu/aimgroup/proj/dollar/"
306  */
307  double ta = -M_PI/4;
308  double tb = M_PI/4;
309  double dt = M_PI/90;
310  float x1 = (float)(PHI*ta + (1-PHI)*tb);
311  float f1 = dollarDifference(points,templ,x1);
312  float x2 = (float)((1-PHI)*ta + PHI*tb);
313  float f2 = dollarDifference(points,templ,x2);
314  while (SDL_fabs(ta-tb) > dt) {
315  if (f1 < f2) {
316  tb = x2;
317  x2 = x1;
318  f2 = f1;
319  x1 = (float)(PHI*ta + (1-PHI)*tb);
320  f1 = dollarDifference(points,templ,x1);
321  }
322  else {
323  ta = x1;
324  x1 = x2;
325  f1 = f2;
326  x2 = (float)((1-PHI)*ta + PHI*tb);
327  f2 = dollarDifference(points,templ,x2);
328  }
329  }
330  /*
331  if (f1 <= f2)
332  printf("Min angle (x1): %f\n",x1);
333  else if (f1 > f2)
334  printf("Min angle (x2): %f\n",x2);
335  */
336  return SDL_min(f1,f2);
337 }
338 
339 /* DollarPath contains raw points, plus (possibly) the calculated length */
341 {
342  int i;
343  float interval;
344  float dist;
345  int numPoints = 0;
346  SDL_FloatPoint centroid;
347  float xmin,xmax,ymin,ymax;
348  float ang;
349  float w,h;
350  float length = path->length;
351 
352  /* Calculate length if it hasn't already been done */
353  if (length <= 0) {
354  for (i=1;i < path->numPoints; i++) {
355  float dx = path->p[i ].x - path->p[i-1].x;
356  float dy = path->p[i ].y - path->p[i-1].y;
357  length += (float)(SDL_sqrt(dx*dx+dy*dy));
358  }
359  }
360 
361  /* Resample */
362  interval = length/(DOLLARNPOINTS - 1);
363  dist = interval;
364 
365  centroid.x = 0;centroid.y = 0;
366 
367  /* printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y); */
368  for (i = 1; i < path->numPoints; i++) {
369  float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
370  (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
371  /* printf("d = %f dist = %f/%f\n",d,dist,interval); */
372  while (dist + d > interval) {
373  points[numPoints].x = path->p[i-1].x +
374  ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
375  points[numPoints].y = path->p[i-1].y +
376  ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
377  centroid.x += points[numPoints].x;
378  centroid.y += points[numPoints].y;
379  numPoints++;
380 
381  dist -= interval;
382  }
383  dist += d;
384  }
385  if (numPoints < DOLLARNPOINTS-1) {
386  if (is_recording) {
387  SDL_SetError("ERROR: NumPoints = %i", numPoints);
388  }
389  return 0;
390  }
391  /* copy the last point */
392  points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
393  numPoints = DOLLARNPOINTS;
394 
395  centroid.x /= numPoints;
396  centroid.y /= numPoints;
397 
398  /* printf("Centroid (%f,%f)",centroid.x,centroid.y); */
399  /* Rotate Points so point 0 is left of centroid and solve for the bounding box */
400  xmin = centroid.x;
401  xmax = centroid.x;
402  ymin = centroid.y;
403  ymax = centroid.y;
404 
405  ang = (float)(SDL_atan2(centroid.y - points[0].y,
406  centroid.x - points[0].x));
407 
408  for (i = 0; i<numPoints; i++) {
409  float px = points[i].x;
410  float py = points[i].y;
411  points[i].x = (float)((px - centroid.x)*SDL_cos(ang) -
412  (py - centroid.y)*SDL_sin(ang) + centroid.x);
413  points[i].y = (float)((px - centroid.x)*SDL_sin(ang) +
414  (py - centroid.y)*SDL_cos(ang) + centroid.y);
415 
416 
417  if (points[i].x < xmin) xmin = points[i].x;
418  if (points[i].x > xmax) xmax = points[i].x;
419  if (points[i].y < ymin) ymin = points[i].y;
420  if (points[i].y > ymax) ymax = points[i].y;
421  }
422 
423  /* Scale points to DOLLARSIZE, and translate to the origin */
424  w = xmax-xmin;
425  h = ymax-ymin;
426 
427  for (i=0; i<numPoints; i++) {
428  points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
429  points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
430  }
431  return numPoints;
432 }
433 
434 static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
435 {
437  int i;
438  float bestDiff = 10000;
439 
440  SDL_memset(points, 0, sizeof(points));
441 
443 
444  /* PrintPath(points); */
445  *bestTempl = -1;
446  for (i = 0; i < touch->numDollarTemplates; i++) {
447  float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
448  if (diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
449  }
450  return bestDiff;
451 }
452 #endif
453 
455 {
457  (SDL_numGestureTouches + 1) *
458  sizeof(SDL_GestureTouch));
459 
460  if (!gestureTouch) {
461  return SDL_OutOfMemory();
462  }
463 
464  SDL_gestureTouch = gestureTouch;
465 
469  return 0;
470 }
471 
473 {
474  int i;
475  for (i = 0; i < SDL_numGestureTouches; i++) {
476  if (SDL_gestureTouch[i].id == touchId) {
477  break;
478  }
479  }
480 
481  if (i == SDL_numGestureTouches) {
482  /* not found */
483  return -1;
484  }
485 
486  SDL_free(SDL_gestureTouch[i].dollarTemplate);
488 
491  return 0;
492 }
493 
495 {
496  int i;
497  for (i = 0; i < SDL_numGestureTouches; i++) {
498  /* printf("%i ?= %i\n",SDL_gestureTouch[i].id,id); */
499  if (SDL_gestureTouch[i].id == id)
500  return &SDL_gestureTouch[i];
501  }
502  return NULL;
503 }
504 
505 static void SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist)
506 {
509  event.mgesture.type = SDL_MULTIGESTURE;
510  event.mgesture.touchId = touch->id;
511  event.mgesture.x = touch->centroid.x;
512  event.mgesture.y = touch->centroid.y;
513  event.mgesture.dTheta = dTheta;
514  event.mgesture.dDist = dDist;
515  event.mgesture.numFingers = touch->numDownFingers;
517  }
518 }
519 
520 #if defined(ENABLE_DOLLAR)
522  SDL_GestureID gestureId,float error)
523 {
526  event.dgesture.type = SDL_DOLLARGESTURE;
527  event.dgesture.touchId = touch->id;
528  event.dgesture.x = touch->centroid.x;
529  event.dgesture.y = touch->centroid.y;
530  event.dgesture.gestureId = gestureId;
531  event.dgesture.error = error;
532  /* A finger came up to trigger this event. */
533  event.dgesture.numFingers = touch->numDownFingers + 1;
535  }
536 }
537 
539 {
542  event.dgesture.type = SDL_DOLLARRECORD;
543  event.dgesture.touchId = touch->id;
544  event.dgesture.gestureId = gestureId;
546  }
547 }
548 #endif
549 
550 
552 {
553  float x,y;
554 #if defined(ENABLE_DOLLAR)
555  int index;
556  int i;
557  float pathDx, pathDy;
558 #endif
559  SDL_FloatPoint lastP;
560  SDL_FloatPoint lastCentroid;
561  float lDist;
562  float Dist;
563  float dtheta;
564  float dDist;
565 
566  if (event->type == SDL_FINGERMOTION ||
567  event->type == SDL_FINGERDOWN ||
568  event->type == SDL_FINGERUP) {
569  SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
570 
571  /* Shouldn't be possible */
572  if (inTouch == NULL) return;
573 
574  x = event->tfinger.x;
575  y = event->tfinger.y;
576 
577  /* Finger Up */
578  if (event->type == SDL_FINGERUP) {
579 #if defined(ENABLE_DOLLAR)
581 #endif
582 
583  inTouch->numDownFingers--;
584 
585 #if defined(ENABLE_DOLLAR)
586  if (inTouch->recording) {
587  inTouch->recording = SDL_FALSE;
589  /* PrintPath(path); */
590  if (recordAll) {
592  for (i = 0; i < SDL_numGestureTouches; i++)
593  SDL_gestureTouch[i].recording = SDL_FALSE;
594  }
595  else {
596  index = SDL_AddDollarGesture(inTouch,path);
597  }
598 
599  if (index >= 0) {
600  SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
601  }
602  else {
603  SDL_SendDollarRecord(inTouch,-1);
604  }
605  }
606  else {
607  int bestTempl;
608  float error;
609  error = dollarRecognize(&inTouch->dollarPath,
610  &bestTempl,inTouch);
611  if (bestTempl >= 0){
612  /* Send Event */
613  unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
614  SDL_SendGestureDollar(inTouch,gestureId,error);
615  /* printf ("%s\n",);("Dollar error: %f\n",error); */
616  }
617  }
618 #endif
619  /* inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers]; */
620  if (inTouch->numDownFingers > 0) {
621  inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
622  x)/inTouch->numDownFingers;
623  inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
624  y)/inTouch->numDownFingers;
625  }
626  }
627  else if (event->type == SDL_FINGERMOTION) {
628  float dx = event->tfinger.dx;
629  float dy = event->tfinger.dy;
630 #if defined(ENABLE_DOLLAR)
631  SDL_DollarPath* path = &inTouch->dollarPath;
632  if (path->numPoints < MAXPATHSIZE) {
633  path->p[path->numPoints].x = inTouch->centroid.x;
634  path->p[path->numPoints].y = inTouch->centroid.y;
635  pathDx =
636  (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
637  pathDy =
638  (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
639  path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
640  path->numPoints++;
641  }
642 #endif
643  lastP.x = x - dx;
644  lastP.y = y - dy;
645  lastCentroid = inTouch->centroid;
646 
647  inTouch->centroid.x += dx/inTouch->numDownFingers;
648  inTouch->centroid.y += dy/inTouch->numDownFingers;
649  /* printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y); */
650  if (inTouch->numDownFingers > 1) {
651  SDL_FloatPoint lv; /* Vector from centroid to last x,y position */
652  SDL_FloatPoint v; /* Vector from centroid to current x,y position */
653  /* lv = inTouch->gestureLast[j].cv; */
654  lv.x = lastP.x - lastCentroid.x;
655  lv.y = lastP.y - lastCentroid.y;
656  lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
657  /* printf("lDist = %f\n",lDist); */
658  v.x = x - inTouch->centroid.x;
659  v.y = y - inTouch->centroid.y;
660  /* inTouch->gestureLast[j].cv = v; */
661  Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
662  /* SDL_cos(dTheta) = (v . lv)/(|v| * |lv|) */
663 
664  /* Normalize Vectors to simplify angle calculation */
665  lv.x/=lDist;
666  lv.y/=lDist;
667  v.x/=Dist;
668  v.y/=Dist;
669  dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
670 
671  dDist = (Dist - lDist);
672  if (lDist == 0) {dDist = 0;dtheta = 0;} /* To avoid impossible values */
673 
674  /* inTouch->gestureLast[j].dDist = dDist;
675  inTouch->gestureLast[j].dtheta = dtheta;
676 
677  printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
678  gdtheta = gdtheta*.9 + dtheta*.1;
679  gdDist = gdDist*.9 + dDist*.1
680  knob.r += dDist/numDownFingers;
681  knob.ang += dtheta;
682  printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
683  printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist); */
684  SDL_SendGestureMulti(inTouch,dtheta,dDist);
685  }
686  else {
687  /* inTouch->gestureLast[j].dDist = 0;
688  inTouch->gestureLast[j].dtheta = 0;
689  inTouch->gestureLast[j].cv.x = 0;
690  inTouch->gestureLast[j].cv.y = 0; */
691  }
692  /* inTouch->gestureLast[j].f.p.x = x;
693  inTouch->gestureLast[j].f.p.y = y;
694  break;
695  pressure? */
696  }
697  else if (event->type == SDL_FINGERDOWN) {
698 
699  inTouch->numDownFingers++;
700  inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
701  x)/inTouch->numDownFingers;
702  inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
703  y)/inTouch->numDownFingers;
704  /* printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
705  inTouch->centroid.x,inTouch->centroid.y); */
706 
707 #if defined(ENABLE_DOLLAR)
708  inTouch->dollarPath.length = 0;
709  inTouch->dollarPath.p[0].x = x;
710  inTouch->dollarPath.p[0].y = y;
711  inTouch->dollarPath.numPoints = 1;
712 #endif
713  }
714  }
715 }
716 
717 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_sqrt
#define SDL_atan2
#define SDL_SetError
#define SDL_memset
#define SDL_sin
#define SDL_PushEvent
#define SDL_RWwrite
#define SDL_RWread
#define SDL_realloc
#define SDL_fabs
#define SDL_free
#define SDL_memcpy
#define SDL_cos
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
#define SDL_SwapFloatLE(X)
Definition: SDL_endian.h:238
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
@ SDL_FINGERMOTION
Definition: SDL_events.h:136
@ SDL_FINGERUP
Definition: SDL_events.h:135
@ SDL_DOLLARRECORD
Definition: SDL_events.h:140
@ SDL_MULTIGESTURE
Definition: SDL_events.h:141
@ SDL_FINGERDOWN
Definition: SDL_events.h:134
@ SDL_DOLLARGESTURE
Definition: SDL_events.h:139
#define SDL_GetEventState(type)
Definition: SDL_events.h:808
#define SDL_ENABLE
Definition: SDL_events.h:795
static unsigned long SDL_HashDollar(SDL_FloatPoint *points)
Definition: SDL_gesture.c:112
#define PHI
Definition: SDL_gesture.c:45
static float dollarRecognize(const SDL_DollarPath *path, int *bestTempl, SDL_GestureTouch *touch)
Definition: SDL_gesture.c:434
int SDL_GestureAddTouch(SDL_TouchID touchId)
Definition: SDL_gesture.c:454
#define DOLLARSIZE
Definition: SDL_gesture.c:44
static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst)
Definition: SDL_gesture.c:124
#define DOLLARNPOINTS
Definition: SDL_gesture.c:41
int SDL_GestureDelTouch(SDL_TouchID touchId)
Definition: SDL_gesture.c:472
int SDL_SaveAllDollarTemplates(SDL_RWops *dst)
Save all currently loaded Dollar Gesture templates.
Definition: SDL_gesture.c:159
static float dollarDifference(SDL_FloatPoint *points, SDL_FloatPoint *templ, float ang)
Definition: SDL_gesture.c:285
static void SDL_SendGestureDollar(SDL_GestureTouch *touch, SDL_GestureID gestureId, float error)
Definition: SDL_gesture.c:521
int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *dst)
Save a currently loaded Dollar Gesture template.
Definition: SDL_gesture.c:171
int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
Load Dollar Gesture templates from a file.
Definition: SDL_gesture.c:229
#define MAXPATHSIZE
Definition: SDL_gesture.c:37
static void SDL_SendDollarRecord(SDL_GestureTouch *touch, SDL_GestureID gestureId)
Definition: SDL_gesture.c:538
static int dollarNormalize(const SDL_DollarPath *path, SDL_FloatPoint *points, SDL_bool is_recording)
Definition: SDL_gesture.c:340
static int SDL_AddDollarGesture_one(SDL_GestureTouch *inTouch, SDL_FloatPoint *path)
Definition: SDL_gesture.c:187
void SDL_GestureProcessEvent(SDL_Event *event)
Definition: SDL_gesture.c:551
static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id)
Definition: SDL_gesture.c:494
static SDL_bool recordAll
Definition: SDL_gesture.c:78
static int SDL_AddDollarGesture(SDL_GestureTouch *inTouch, SDL_FloatPoint *path)
Definition: SDL_gesture.c:211
void SDL_GestureQuit()
Definition: SDL_gesture.c:106
static void SDL_SendGestureMulti(SDL_GestureTouch *touch, float dTheta, float dDist)
Definition: SDL_gesture.c:505
static SDL_GestureTouch * SDL_gestureTouch
Definition: SDL_gesture.c:76
static float bestDollarDifference(SDL_FloatPoint *points, SDL_FloatPoint *templ)
Definition: SDL_gesture.c:301
int SDL_RecordGesture(SDL_TouchID touchId)
Begin Recording a gesture on the specified touch, or all touches (-1)
Definition: SDL_gesture.c:92
static int SDL_numGestureTouches
Definition: SDL_gesture.c:77
Sint64 SDL_GestureID
Definition: SDL_gesture.h:44
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
const GLdouble * v
Definition: SDL_opengl.h:2064
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
struct _cl_event * event
GLfixed GLfixed GLint GLint GLfixed points
GLenum src
GLuint GLfloat GLfloat GLfloat x1
GLuint index
GLfixed GLfixed x2
GLenum GLenum dst
GLfloat GLfloat p
GLsizei const GLchar *const * path
GLuint GLsizei GLsizei * length
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
uint16_t Uint16
Definition: SDL_stdinc.h:197
#define SDL_zero(x)
Definition: SDL_stdinc.h:426
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_min(x, y)
Definition: SDL_stdinc.h:412
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
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
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 int in j)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:163
SDL_FloatPoint p[MAXPATHSIZE]
Definition: SDL_gesture.c:56
SDL_FloatPoint path[DOLLARNPOINTS]
Definition: SDL_gesture.c:60
unsigned long hash
Definition: SDL_gesture.c:61
SDL_DollarTemplate * dollarTemplate
Definition: SDL_gesture.c:71
Uint16 numDownFingers
Definition: SDL_gesture.c:68
SDL_DollarPath dollarPath
Definition: SDL_gesture.c:67
SDL_FloatPoint centroid
Definition: SDL_gesture.c:66
SDL_bool recording
Definition: SDL_gesture.c:73
SDL_TouchID id
Definition: SDL_gesture.c:65
General event structure.
Definition: SDL_events.h:592