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