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