[els_touch]set flick's endtime as current time
[framework/uifw/elementary.git] / src / lib / els_touch.c
1 /*
2  *
3  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
4  */
5 #include <Elementary.h>
6 #include <math.h>
7 #include "elm_priv.h"
8
9 #define SMART_NAME "elm_touch"
10 #define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
11 #define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
12
13 #define PRESS_TIME          250   // ms
14 #define RELEASE_TIME         50   // ms
15 #define LONG_HOLD_TIME      500   // ms
16
17 #define N_FINGER             3
18 #define DEFAULT_FRAMERATE   60
19 #define DOUBLE_ERROR        0.00001
20
21 // for one finger
22 #define DBL_TAP_DISTANCE    30    // pixel
23 #define DRAG_THRESHOLD       3    // pixel
24 #define INIT_DRAG_THRESHOLD 15    // pixel
25 #define MOVE_HISTORY_SIZE    5
26 #define MAX_MOVE_DISTANCE   15
27 #define FLICK_THRESHOLD      5
28
29 // for two finger
30 #define MOVE_THRESHOLD      15
31 #define FINGER_DISTANCE     10
32
33 typedef struct _Mouse_Data Mouse_Data;
34
35 struct _Mouse_Data
36 {
37    Evas_Coord x;
38    Evas_Coord y;
39    int time;
40    int device;
41 };
42
43 typedef enum _Two_Drag_Mode
44 {
45    TWO_DRAG_NONE,
46    TWO_DRAG_PINCH,
47    TWO_DRAG_VERTICAL,
48    TWO_DRAG_HORIZONTAL,
49 } Two_Drag_Mode;
50
51 typedef struct _Two_Mouse_Data Two_Mouse_Data;
52
53 struct _Two_Mouse_Data
54 {
55    Evas_Point first;
56    Evas_Point second;
57    Two_Drag_Mode mode;
58 };
59
60 typedef struct _Three_Mouse_Data Three_Mouse_Data;
61
62 struct _Three_Mouse_Data
63 {
64    Evas_Point first;
65    Evas_Point second;
66    Evas_Point third;
67 };
68
69 typedef enum _Touch_State
70 {
71    TOUCH_STATE_NONE,
72    TOUCH_STATE_DOWN,
73    TOUCH_STATE_DOWN_DURING_DRAG,
74    TOUCH_STATE_DOWN_UP,
75    TOUCH_STATE_DOWN_UP_DOWN,
76    TOUCH_STATE_HOLD,
77    TOUCH_STATE_DRAG,
78    TOUCH_STATE_TWO_DOWN,
79    TOUCH_STATE_TWO_DOWN_DURING_DRAG,
80    TOUCH_STATE_TWO_DRAG,
81    TOUCH_STATE_THREE_DOWN
82 } Touch_State;
83
84 typedef enum _One_Drag_Mode
85 {
86    ONE_DRAG_NONE,
87    ONE_DRAG_VERTICAL,
88    ONE_DRAG_HORIZONTAL
89 } One_Drag_Mode;
90
91 typedef struct _Flick_Data Flick_Data;
92
93 struct _Flick_Data
94 {
95    int flick_index;
96    Evas_Coord_Point last;
97    Evas_Coord_Point avg_distance;
98 };
99
100 typedef struct _Mouse_Diff_Data Mouse_Diff_Data;
101
102 struct _Mouse_Diff_Data
103 {
104    Evas_Coord dx, dy;
105    double time;
106 };
107
108 typedef struct _Smart_Data Smart_Data;
109
110 struct _Smart_Data
111 {
112    Evas_Object *smart_obj;
113    Evas_Object *child_obj;
114
115    Eina_Bool running;
116
117    int screen_angle;
118    Touch_State state;
119    One_Drag_Mode one_drag_mode;
120    Eina_Bool is_one_drag_mode;
121    Two_Drag_Mode two_drag_mode;
122    int numOfTouch;
123
124    // for flick
125    int last_move_history_index;
126    int move_history_count;
127    Flick_Data flick_data;
128    Mouse_Diff_Data move_history[MOVE_HISTORY_SIZE];
129
130    Mouse_Data first_down[N_FINGER];
131    Mouse_Data last_down[N_FINGER];
132    Mouse_Data last_drag[N_FINGER];
133
134    Ecore_Animator *animator_move;
135    Ecore_Animator *animator_flick;
136    Ecore_Animator *animator_two_move;
137
138    // timers
139    Ecore_Timer *press_timer;
140    Ecore_Timer *long_press_timer;
141    Ecore_Timer *release_timer;
142    Ecore_Timer *press_release_timer;
143 };
144
145 /* local subsystem functions */
146 // mouse callbacks
147 static float _smart_velocity_easeinoutcubic(int index);
148 static void _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev);
149 static void _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev);
150 static void _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev);
151 static void _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev);
152 static void _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev);
153 static void _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev);
154 // animator callbacks
155 static int _smart_animation_move(void *data);
156 static int _smart_animation_flick(void *data);
157 static int _smart_animation_two_move(void *data);
158 // enter mode functions
159 static void _smart_enter_none(Smart_Data *sd);
160 static void _smart_enter_down(Smart_Data *sd);
161 static void _smart_enter_down_during_drag(Smart_Data *sd);
162 static void _smart_enter_down_up(Smart_Data *sd, int downTime, int time);
163 static void _smart_enter_down_up_down(Smart_Data *sd);
164 static void _smart_enter_hold(Smart_Data *sd);
165 static void _smart_enter_drag(Smart_Data *sd);
166 static void _smart_enter_two_down(Smart_Data *sd);
167 static void _smart_enter_two_down_during_drag(Smart_Data *sd);
168 static void _smart_enter_two_drag(Smart_Data *sd);
169 static void _smart_enter_three_down(Smart_Data *sd);
170 // emit functions
171 static void _smart_emit_press(Smart_Data *sd);
172 static void _smart_emit_tap(Smart_Data *sd);
173 static void _smart_emit_double_tap(Smart_Data *sd);
174 static void _smart_emit_long_hold(Smart_Data *sd);
175 static void _smart_emit_release(Smart_Data *sd);
176 static void _smart_emit_two_press(Smart_Data *sd);
177 static void _smart_emit_two_tap(Smart_Data *sd);
178 static void _smart_emit_two_move_start(Smart_Data *sd);
179 static void _smart_emit_two_move(Smart_Data *sd);
180 static void _smart_emit_two_move_end(Smart_Data *sd);
181 static void _smart_emit_three_press(Smart_Data *sd);
182 static void _smart_emit_three_tap(Smart_Data *sd);
183 // timer handlers
184 static int _smart_press_timer_handler(void *data);
185 static int _smart_long_press_timer_handler(void *data);
186 static int _smart_release_timer_handler(void *data);
187 static int _smart_press_release_timer_handler(void *data);
188
189 static void _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy);
190 static void _smart_start_flick(Smart_Data *sd);
191 static void _smart_stop_animator_move(Smart_Data *sd);
192 static void _smart_stop_animator_flick(Smart_Data *sd);
193 static void _smart_stop_animator_two_move(Smart_Data *sd);
194 static Two_Drag_Mode _smart_check_two_drag_mode(Smart_Data *sd);
195 static void _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data);
196 static void _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data);
197 static void _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data);
198 static void _smart_stop_all_timers(Smart_Data *sd);
199 static void _smart_init(void);
200 static void _smart_del(Evas_Object *obj);
201 static void _smart_add(Evas_Object *obj);
202
203 /* local subsystem globals */
204 static Evas_Smart *_smart = NULL;
205
206 /* externally accessible functions */
207    Evas_Object *
208 _elm_smart_touch_add(Evas *evas)
209 {
210    _smart_init();
211    return evas_object_smart_add(evas, _smart);
212 }
213
214    void
215 _elm_smart_touch_child_set(Evas_Object *obj, Evas_Object *child)
216 {
217    API_ENTRY return;
218    if (child == sd->child_obj) return;
219
220    if (sd->child_obj) // delete callbacks of old object
221      {
222         evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
223         evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
224         evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
225         evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
226         evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
227         evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
228         _smart_stop_all_timers(sd);
229         _smart_stop_animator_move(sd);
230         _smart_stop_animator_flick(sd);
231         _smart_stop_animator_two_move(sd);
232
233         sd->child_obj = NULL;
234      }
235
236    if (child)
237      {
238         sd->child_obj = child;
239
240         // add callbacks
241         evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down, sd);
242         evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up, sd);
243         evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move, sd);
244         evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down, sd);
245         evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_UP, _smart_multi_up, sd);
246         evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move, sd);
247
248         _smart_enter_none(sd);
249
250         sd->is_one_drag_mode = EINA_FALSE;
251      }
252
253    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
254 }
255
256    void
257 _elm_smart_touch_start(Evas_Object *obj)
258 {
259    API_ENTRY return;
260    if (sd->running) return;
261
262    sd->running = EINA_TRUE;
263    _smart_enter_none(sd);
264 }
265
266    void
267 _elm_smart_touch_stop(Evas_Object *obj)
268 {
269    API_ENTRY return;
270    sd->running = EINA_FALSE;
271    _smart_stop_all_timers(sd);
272    _smart_stop_animator_move(sd);
273    _smart_stop_animator_flick(sd);
274    _smart_stop_animator_two_move(sd);
275    _smart_enter_none(sd);
276 }
277
278    void
279 _elm_smart_touch_reset(Evas_Object *obj)
280 {
281    API_ENTRY return;
282    _smart_stop_all_timers(sd);
283    _smart_stop_animator_move(sd);
284    _smart_stop_animator_flick(sd);
285    _smart_stop_animator_two_move(sd);
286    _smart_enter_none(sd);
287 }
288
289    void
290 _elm_smart_touch_screen_angle_update(Evas_Object *obj, int screen_angle)
291 {
292    API_ENTRY return;
293    sd->screen_angle = screen_angle;
294 }
295
296    void
297 _elm_smart_touch_is_one_drag_mode_enable(Evas_Object *obj, Eina_Bool is_one_drag_mode)
298 {
299    API_ENTRY return;
300    sd->is_one_drag_mode = is_one_drag_mode;
301 }
302
303 /* local subsystem functions */
304 /** reference from htsd://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html
305  * Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration
306  * @param                t   Number                Current time (in frames or seconds)
307  * @param                b   Number                Starting value
308  * @param                c   Number                Change needed in value
309  * @param                d   Number                Expected easing duration (in frames or seconds)
310  * @param                k1  Number                first sustain value
311  * @param                k2  Number                second sustain value
312  * @return                   Number                The correct value
313  public static function easeInOutCubic (t:Number, b:Number, c:Number, d:Number, p_params:Object):Number {
314  if ((t/=d/2) < 1) return c/2*t*t*t + b;
315  return c/2*((t-=2)*t*t + 2) + b;
316  }
317  */
318 static float
319 _smart_velocity_easeinoutcubic(int index)
320 {
321    float d = 60.0f;
322    float t = d - index; // we want to get reversed value
323    float c = 1.0f;
324    float k1 = 0.1f;
325    float k2 = 0.05f;
326    float velocity;
327    if ((t /= (d / 2)) < 1)
328      {
329         velocity = (c / 2) * t * t * t;
330      }
331    else
332      {
333         t -= 2;
334         velocity = (c / 2) * (t * t * t + 2);
335      }
336    if (velocity < k1 && velocity > k2) velocity = 0.1;
337    else if (velocity < k2) velocity = 0.05;
338    return velocity;
339 }
340
341 /* mouse callbacks */
342 static void
343 _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev)
344 {
345    Smart_Data *sd;
346    Evas_Event_Mouse_Down *event;
347    Mouse_Data mouse_data;
348
349    sd = data;
350    if (!sd || sd->running == EINA_FALSE) return;
351
352    event = (Evas_Event_Mouse_Down*)ev;
353
354    switch (sd->state)
355      {
356       case TOUCH_STATE_NONE:
357          mouse_data.x = event->canvas.x;
358          mouse_data.y = event->canvas.y;
359          mouse_data.time = event->timestamp;
360          mouse_data.device = -1;
361          _smart_set_first_down(sd, 0, &mouse_data);
362          _smart_set_last_down(sd, 0, &mouse_data);
363          _smart_set_last_drag(sd, 0, &mouse_data);
364          _smart_enter_down(sd);
365          break;
366
367       case TOUCH_STATE_DRAG:
368          mouse_data.x = event->canvas.x;
369          mouse_data.y = event->canvas.y;
370          mouse_data.time = event->timestamp;
371          mouse_data.device = -1;
372          _smart_set_first_down(sd, 0, &mouse_data);
373          _smart_set_last_down(sd, 0, &mouse_data);
374          _smart_set_last_drag(sd, 0, &mouse_data);
375          if (sd->animator_move)
376            {
377               ecore_animator_del(sd->animator_move);
378               sd->animator_move = NULL;
379            }
380          if (sd->animator_flick)
381            {
382               ecore_animator_del(sd->animator_flick);
383               sd->animator_flick = NULL;
384            }
385          _smart_enter_down_during_drag(sd);
386          break;
387
388       case TOUCH_STATE_DOWN_UP:
389          if (event->flags == EVAS_BUTTON_DOUBLE_CLICK) {
390               mouse_data.x = event->canvas.x;
391               mouse_data.y = event->canvas.y;
392               mouse_data.time = event->timestamp;
393               mouse_data.device = -1;
394               _smart_set_last_down(sd, 0, &mouse_data);
395               _smart_set_last_drag(sd, 0, &mouse_data);
396               _smart_enter_down_up_down(sd);
397          }
398          break;
399
400       default:
401          break;
402      }
403 }
404
405 static void
406 _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev)
407 {
408    Smart_Data *sd;
409    sd = data;
410    Evas_Event_Mouse_Up *event;
411
412    if (!sd || sd->running == EINA_FALSE) return;
413
414    event = (Evas_Event_Mouse_Up*)ev;
415
416    switch (sd->state)
417      {
418       case TOUCH_STATE_DOWN:
419          _smart_stop_animator_move(sd);
420          _smart_stop_animator_flick(sd);
421          _smart_enter_down_up(sd, (event->timestamp - sd->last_down[0].time), event->timestamp);
422          break;
423
424       case TOUCH_STATE_DOWN_DURING_DRAG:
425            {
426               Evas_Point point;
427               point.x = sd->last_drag[0].x;
428               point.y = sd->last_drag[0].y;
429               evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
430               _smart_enter_none(sd);
431            } break;
432
433       case TOUCH_STATE_DOWN_UP_DOWN:
434            {
435               int dx = sd->last_down[0].x - sd->first_down[0].x;
436               int dy = sd->last_down[0].y - sd->first_down[0].y;
437               if ((dx * dx + dy * dy) <= (DBL_TAP_DISTANCE * DBL_TAP_DISTANCE))
438                 _smart_emit_double_tap(sd);
439               _smart_stop_all_timers(sd);
440               _smart_enter_none(sd);
441            } break;
442
443       case TOUCH_STATE_HOLD:
444          _smart_emit_release(sd);
445          _smart_stop_all_timers(sd);
446          _smart_enter_none(sd);
447          break;
448
449       case TOUCH_STATE_DRAG:
450          _smart_emit_release(sd);
451          _smart_start_flick(sd);
452          break;
453
454       case TOUCH_STATE_TWO_DOWN:
455          _smart_emit_two_tap(sd);
456          _smart_stop_all_timers(sd);
457          _smart_enter_none(sd);
458          break;
459
460       case TOUCH_STATE_TWO_DRAG:
461          _smart_stop_animator_two_move(sd);
462          _smart_stop_all_timers(sd);
463          _smart_enter_none(sd);
464          break;
465
466       case TOUCH_STATE_THREE_DOWN:
467          _smart_emit_three_tap(sd);
468          _smart_stop_all_timers(sd);
469          _smart_enter_none(sd);
470          break;
471
472       default:
473          _smart_emit_release(sd);
474          _smart_stop_all_timers(sd);
475          _smart_enter_none(sd);
476          DBG("\nERROR: wrong state in mouse_up\n\n");
477          break;
478      }
479
480 }
481
482 static void
483 _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev)
484 {
485    Smart_Data *sd;
486    sd = data;
487    if (!sd || sd->running == EINA_FALSE) return;
488
489    Evas_Event_Mouse_Move *event = (Evas_Event_Mouse_Move*)ev;
490    int dx = 0;
491    int dy = 0;
492
493    Mouse_Data mouse_data;
494    mouse_data.x = event->cur.canvas.x;
495    mouse_data.y = event->cur.canvas.y;
496    mouse_data.time = event->timestamp;
497    mouse_data.device = -1;
498
499    switch (sd->state)
500      {
501       case TOUCH_STATE_DOWN:
502       case TOUCH_STATE_DOWN_DURING_DRAG:
503          dx = mouse_data.x - sd->last_drag[0].x;
504          dy = mouse_data.y - sd->last_drag[0].y;
505
506          if ((abs(dx) > INIT_DRAG_THRESHOLD) || (abs(dy) > INIT_DRAG_THRESHOLD))
507            {
508               if (sd->animator_move)
509                 {
510                    ecore_animator_del(sd->animator_move);
511                    sd->animator_move = NULL;
512                 }
513               if (sd->animator_flick)
514                 {
515                    ecore_animator_del(sd->animator_flick);
516                    sd->animator_flick = NULL;
517                 }
518               _smart_set_last_drag(sd, 0, &mouse_data);
519               // Note:
520               // last_down - location where the drag starts
521               // (which is different than fisrtDown)
522               _smart_set_last_down(sd, 0, &mouse_data);
523               _smart_enter_drag(sd);
524            }
525          break;
526
527       case TOUCH_STATE_DRAG:
528          dx = mouse_data.x - sd->last_drag[0].x;
529          dy = mouse_data.y - sd->last_drag[0].y;
530
531          if ((abs(dx) > DRAG_THRESHOLD) || (abs(dy) > DRAG_THRESHOLD))
532            {
533               _smart_set_last_drag(sd, 0, &mouse_data);
534               _smart_save_move_history(sd, mouse_data.x, mouse_data.y, dx, dy);
535            }
536          break;
537
538       case TOUCH_STATE_TWO_DOWN:
539          _smart_set_last_drag(sd, 0, &mouse_data);
540
541          sd->two_drag_mode = _smart_check_two_drag_mode(sd);
542          if (sd->two_drag_mode != TWO_DRAG_NONE)
543            {
544               DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
545               _smart_enter_two_drag(sd);
546            }
547          break;
548
549       case TOUCH_STATE_TWO_DRAG:
550          _smart_set_last_drag(sd, 0, &mouse_data);
551          break;
552
553       case TOUCH_STATE_THREE_DOWN:
554          _smart_set_last_drag(sd, 0, &mouse_data);
555          break;
556
557       default:
558          break;
559      }
560 }
561
562 static void
563 _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev)
564 {
565    Smart_Data *sd;
566
567    sd = data;
568    if (!sd || sd->running == EINA_FALSE) return;
569
570    Evas_Event_Multi_Down *event = (Evas_Event_Multi_Down*)ev;
571    Mouse_Data mouse_data;
572
573    switch (sd->state)
574      {
575       case TOUCH_STATE_DOWN:
576          sd->numOfTouch++;
577          if (sd->numOfTouch == 1)
578            {
579               mouse_data.x = event->output.x;
580               mouse_data.y = event->output.y;
581               mouse_data.time = event->timestamp;
582               mouse_data.device = event->device;
583               _smart_set_first_down(sd, 1, &mouse_data);
584               _smart_set_last_down(sd, 1, &mouse_data);
585               _smart_set_last_drag(sd, 1, &mouse_data);
586               _smart_stop_animator_move(sd);
587               _smart_stop_animator_flick(sd);
588               _smart_stop_animator_two_move(sd);
589               _smart_enter_two_down(sd);
590            }
591          break;
592
593       case TOUCH_STATE_DOWN_DURING_DRAG:
594       case TOUCH_STATE_DRAG:
595          sd->numOfTouch++;
596          if (sd->numOfTouch == 1)
597            {
598               mouse_data.x = event->output.x;
599               mouse_data.y = event->output.y;
600               mouse_data.time = event->timestamp;
601               mouse_data.device = event->device;
602               _smart_set_first_down(sd, 1, &mouse_data);
603               _smart_set_last_down(sd, 1, &mouse_data);
604               _smart_set_last_drag(sd, 1, &mouse_data);
605               if (sd->animator_move)
606                 {
607                    ecore_animator_del(sd->animator_move);
608                    sd->animator_move = NULL;
609                 }
610               if (sd->animator_flick)
611                 {
612                    ecore_animator_del(sd->animator_flick);
613                    sd->animator_flick = NULL;
614                 }
615               if (sd->animator_two_move)
616                 {
617                    ecore_animator_del(sd->animator_two_move);
618                    sd->animator_two_move = NULL;
619                 }
620               _smart_enter_two_down_during_drag(sd);
621            }
622          break;
623
624       case TOUCH_STATE_TWO_DOWN:
625       case TOUCH_STATE_TWO_DRAG:
626          sd->numOfTouch++;
627          if (sd->numOfTouch == 2)
628            {
629               mouse_data.x = event->output.x;
630               mouse_data.y = event->output.y;
631               mouse_data.time = event->timestamp;
632               mouse_data.device = event->device;
633               _smart_set_first_down(sd, 2, &mouse_data);
634               _smart_set_last_down(sd, 2, &mouse_data);
635               _smart_set_last_drag(sd, 2, &mouse_data);
636               _smart_stop_animator_move(sd);
637               _smart_stop_animator_flick(sd);
638               _smart_stop_animator_two_move(sd);
639               _smart_enter_three_down(sd);
640            }
641          break;
642
643       default:
644          break;
645      }
646 }
647
648 static void
649 _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev)
650 {
651    Smart_Data *sd;
652    Evas_Event_Multi_Up *event;
653
654    sd = data;
655    if (!sd || sd->running == EINA_FALSE) return;
656
657    event = (Evas_Event_Multi_Up*)ev;
658
659    switch (sd->state)
660      {
661       case TOUCH_STATE_TWO_DOWN:
662          _smart_emit_two_tap(sd);
663          _smart_stop_all_timers(sd);
664          _smart_enter_none(sd);
665          break;
666
667       case TOUCH_STATE_TWO_DOWN_DURING_DRAG:
668            {
669               Evas_Point point;
670               point.x = sd->last_drag[0].x;
671               point.y = sd->last_drag[0].y;
672               evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
673               _smart_emit_two_tap(sd);
674               _smart_stop_all_timers(sd);
675               _smart_enter_none(sd);
676            } break;
677
678       case TOUCH_STATE_TWO_DRAG:
679          _smart_stop_animator_two_move(sd);
680          _smart_stop_all_timers(sd);
681          _smart_enter_none(sd);
682          break;
683
684       case TOUCH_STATE_THREE_DOWN:
685          _smart_emit_three_tap(sd);
686          _smart_stop_all_timers(sd);
687          _smart_enter_none(sd);
688          break;
689
690       default:
691          _smart_stop_all_timers(sd);
692          _smart_enter_none(sd);
693          break;
694      }
695 }
696
697 static void
698 _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev)
699 {
700    Smart_Data *sd;
701    Evas_Event_Multi_Move *event;
702    Mouse_Data mouse_data;
703
704    sd = data;
705    if (!sd || sd->running == EINA_FALSE) return;
706
707    event = (Evas_Event_Multi_Move*)ev;
708    mouse_data.x = event->cur.output.x;
709    mouse_data.y = event->cur.output.y;
710    mouse_data.time = event->timestamp;
711    mouse_data.device = event->device;
712
713    switch (sd->state)
714      {
715       case TOUCH_STATE_TWO_DOWN:
716       case TOUCH_STATE_TWO_DOWN_DURING_DRAG:
717          if (sd->first_down[1].device == event->device)
718            {
719               _smart_set_last_drag(sd, 1, &mouse_data);
720               sd->two_drag_mode = _smart_check_two_drag_mode(sd);
721               if (sd->two_drag_mode != TWO_DRAG_NONE)
722                 {
723                    DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
724                    _smart_enter_two_drag(sd);
725                 }
726            }
727          break;
728
729       case TOUCH_STATE_TWO_DRAG:
730          if (sd->first_down[1].device == event->device)
731            {
732               _smart_set_last_drag(sd, 1, &mouse_data);
733            }
734          break;
735
736       case TOUCH_STATE_THREE_DOWN:
737          if (sd->first_down[1].device == event->device)
738            {
739               _smart_set_last_drag(sd, 1, &mouse_data);
740            }
741          else if (sd->first_down[2].device == event->device)
742            {
743               _smart_set_last_drag(sd, 2, &mouse_data);
744            }
745          break;
746
747       default:
748          break;
749      }
750 }
751
752 /* animators */
753 static int
754 _smart_animation_move(void *data)
755 {
756    Smart_Data *sd;
757
758    sd = data;
759    if (sd->child_obj)
760      {
761         DBG("<< animation_move >>\n");
762         // get the position here instead of mouse_move event
763         Evas *evas = evas_object_evas_get(sd->child_obj);
764         Evas_Point point;
765         evas_pointer_canvas_xy_get(evas, &point.x, &point.y);
766         if (sd->is_one_drag_mode)
767           {
768              if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
769                {
770                   // Note:
771                   // first_down - location of mouse down
772                   // last_down - location where the drag started
773                   point.x = sd->last_down[0].x;
774                }
775              else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
776                {
777                   point.y = sd->last_down[0].y;
778                }
779           }
780         evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
781         return ECORE_CALLBACK_RENEW;
782      }
783    else
784      {
785         _smart_stop_animator_move(sd);
786         _smart_enter_none(sd);
787         return ECORE_CALLBACK_CANCEL;
788      }
789 }
790
791 static int
792 _smart_animation_flick(void *data)
793 {
794    Smart_Data *sd;
795    Flick_Data *flick_data;
796
797    sd = data;
798    flick_data = &(sd->flick_data);
799
800    if (flick_data && sd->child_obj)
801      {
802         // calculate dx, dy
803         float velocity = _smart_velocity_easeinoutcubic(flick_data->flick_index);
804         Evas_Coord dx = flick_data->avg_distance.x * velocity;
805         Evas_Coord dy = flick_data->avg_distance.y * velocity;
806         flick_data->flick_index++;
807         flick_data->last.x += dx;
808         flick_data->last.y += dy;
809         DBG("<< animation_flick |%d|%d|%f| >>\n", dx, dy, ecore_loop_time_get());
810
811         // stop flick animator
812         if (dx == 0 && dy == 0)
813           {
814              _smart_stop_animator_flick(sd);
815              if (sd->state == TOUCH_STATE_DRAG)
816                _smart_enter_none(sd);
817              return ECORE_CALLBACK_CANCEL;
818           }
819         else
820           {
821              Evas_Coord_Point point;
822              point = flick_data->last;
823              if (sd->is_one_drag_mode)
824                {
825                   if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
826                     {
827                        point.x = sd->first_down[0].x;
828                     }
829                   else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
830                     {
831                        point.y = sd->first_down[0].y;
832                     }
833                }
834              evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
835              return ECORE_CALLBACK_RENEW;
836           }
837      }
838    else
839      {
840         _smart_stop_animator_flick(sd);
841         _smart_enter_none(sd);
842         return ECORE_CALLBACK_CANCEL;
843      }
844 }
845
846 static int
847 _smart_animation_two_move(void *data)
848 {
849    Smart_Data *sd;
850
851    sd = data;
852
853    if (sd->child_obj)
854      {
855         _smart_emit_two_move(sd);
856         return ECORE_CALLBACK_RENEW;
857      }
858    else
859      {
860         _smart_stop_animator_two_move(sd);
861         _smart_enter_none(sd);
862         return ECORE_CALLBACK_CANCEL;
863      }
864
865 }
866
867 /* state switching */
868 static void
869 _smart_enter_none(Smart_Data *sd)
870 {
871    sd->numOfTouch = 0;
872    sd->two_drag_mode = TWO_DRAG_NONE;
873    sd->state = TOUCH_STATE_NONE;
874    DBG("\nTOUCH_STATE_NONE\n");
875 }
876
877 static void
878 _smart_enter_down(Smart_Data *sd)
879 {
880    // set press timer
881    sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
882
883    // set long press timer
884    sd->long_press_timer = ecore_timer_add(((double)LONG_HOLD_TIME)/1000.0, _smart_long_press_timer_handler, sd);
885
886    sd->state = TOUCH_STATE_DOWN;
887    DBG("\nTOUCH_STATE_DOWN\n");
888 }
889
890 static void
891 _smart_enter_down_during_drag(Smart_Data *sd)
892 {
893    // set press timer
894    sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
895
896    sd->state = TOUCH_STATE_DOWN_DURING_DRAG;
897    DBG("\nTOUCH_STATE_DOWN_DURING_DRAG\n");
898 }
899
900 static void
901 _smart_enter_down_up(Smart_Data *sd, int downTime, int time)
902 {
903    // remove sd->press_timer and set new timer
904    int timerTime = RELEASE_TIME - (downTime - PRESS_TIME);
905    if (sd->press_timer)
906      {
907         ecore_timer_del(sd->press_timer);
908         sd->press_timer = NULL;
909         sd->press_release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_press_release_timer_handler, sd);
910
911      }
912    else
913      {
914         sd->release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_release_timer_handler, sd);
915      }
916
917    if (sd->long_press_timer) // remove long press timer
918      {
919         ecore_timer_del(sd->long_press_timer);
920         sd->long_press_timer = NULL;
921      }
922
923    sd->state = TOUCH_STATE_DOWN_UP;
924    DBG("\nTOUCH_STATE_DOWN_UP\n");
925 }
926
927 static void
928 _smart_enter_down_up_down(Smart_Data *sd)
929 {
930    if (sd->press_release_timer) // remove press_release_timer
931      {
932         ecore_timer_del(sd->press_release_timer);
933         sd->press_release_timer = NULL;
934      }
935
936    if (sd->release_timer) // remove ReleaseTimer
937      {
938         ecore_timer_del(sd->release_timer);
939         sd->release_timer = NULL;
940      }
941
942    sd->state = TOUCH_STATE_DOWN_UP_DOWN;
943    DBG("\nTOUCH_STATE_DOWN_UP_DOWN\n");
944 }
945
946 static void
947 _smart_enter_hold(Smart_Data *sd)
948 {
949    sd->state = TOUCH_STATE_HOLD;
950    DBG("\nTOUCH_STATE_HOLD\n");
951 }
952
953 static void
954 _smart_enter_drag(Smart_Data *sd)
955 {
956    if (sd->press_timer) // remove press_timer
957      {
958         ecore_timer_del(sd->press_timer);
959         sd->press_timer = NULL;
960      }
961
962    if (sd->press_release_timer) // remove press_release_timer
963      {
964         ecore_timer_del(sd->press_release_timer);
965         sd->press_release_timer = NULL;
966      }
967
968    if (sd->release_timer) // remove ReleaseTimer
969      {
970         ecore_timer_del(sd->release_timer);
971         sd->release_timer = NULL;
972      }
973
974    if (sd->long_press_timer) // remove long press timer
975      {
976         ecore_timer_del(sd->long_press_timer);
977         sd->long_press_timer = NULL;
978      }
979
980    if (sd->child_obj)
981      {
982         if (sd->is_one_drag_mode)
983           {
984              sd->one_drag_mode = ONE_DRAG_NONE;
985              int abs_dx = abs(sd->first_down[0].x - sd->last_drag[0].x);
986              int abs_dy = abs(sd->first_down[0].y - sd->last_drag[0].y);
987              abs_dx = (abs_dx == 0) ? 1 : abs_dx;
988              DBG("<< abs_dx[%d], abs_dy[%d] >>\n\n", abs_dx, abs_dy);
989              float degree = (float)abs_dy / (float)abs_dx;
990              // more than 70 degree
991              if (degree > tan(70 * M_PI / 180))
992                {
993                   sd->one_drag_mode = ONE_DRAG_VERTICAL;
994                }
995              // less than 20 degree
996              else if (degree < tan(20 * M_PI / 180))
997                {
998                   sd->one_drag_mode = ONE_DRAG_HORIZONTAL;
999                }
1000           }
1001         Evas_Point point;
1002         point.x = sd->last_down[0].x;
1003         point.y = sd->last_down[0].y;
1004         evas_object_smart_callback_call(sd->child_obj, "one,move,start", &point);
1005
1006         // initialize flick variables
1007         sd->last_move_history_index = -1;
1008         sd->move_history_count = 0;
1009
1010         sd->animator_move = ecore_animator_add(_smart_animation_move, sd);
1011         DBG("<< sd->animator_move >>\n");
1012         sd->state = TOUCH_STATE_DRAG;
1013         DBG("\nTOUCH_STATE_DRAG\n");
1014      }
1015    else
1016      {
1017         sd->state = TOUCH_STATE_NONE;
1018      }
1019 }
1020
1021 static void
1022 _smart_enter_two_down(Smart_Data *sd)
1023 {
1024    _smart_stop_all_timers(sd);
1025
1026    if (sd->child_obj)
1027      {
1028         DBG("<< enter two down >>\n");
1029         sd->state = TOUCH_STATE_TWO_DOWN;
1030         _smart_emit_two_press(sd);
1031      }
1032 }
1033
1034 static void
1035 _smart_enter_two_down_during_drag(Smart_Data *sd)
1036 {
1037    _smart_stop_all_timers(sd);
1038
1039    if (sd->child_obj)
1040      {
1041         DBG("<< enter two down >>\n");
1042         sd->state = TOUCH_STATE_TWO_DOWN_DURING_DRAG;
1043         _smart_emit_two_press(sd);
1044      }
1045 }
1046
1047 static void
1048 _smart_enter_two_drag(Smart_Data *sd)
1049 {
1050    if (sd->child_obj)
1051      {
1052         DBG("<< sd->animator_two_move >>\n");
1053         sd->state = TOUCH_STATE_TWO_DRAG;
1054         _smart_emit_two_move_start(sd);
1055         sd->animator_two_move = ecore_animator_add(_smart_animation_two_move, sd);
1056      }
1057    else
1058      {
1059         sd->state = TOUCH_STATE_NONE;
1060      }
1061 }
1062
1063 static void
1064 _smart_enter_three_down(Smart_Data *sd)
1065 {
1066    if (sd->child_obj)
1067      {
1068         sd->state = TOUCH_STATE_THREE_DOWN;
1069         _smart_emit_three_press(sd);
1070      }
1071 }
1072
1073 /* producing output events */
1074 static void
1075 _smart_emit_press(Smart_Data *sd)
1076 {
1077    if (sd->child_obj)
1078      {
1079         DBG("<< emit_press >>\n");
1080         Evas_Point point;
1081         point.x = sd->last_down[0].x;
1082         point.y = sd->last_down[0].y;
1083         evas_object_smart_callback_call(sd->child_obj, "one,press", &point);
1084      }
1085 }
1086
1087 static void
1088 _smart_emit_tap(Smart_Data *sd)
1089 {
1090    if (sd->child_obj)
1091      {
1092         DBG("<< emit_tap >>\n");
1093         Evas_Point point;
1094         point.x = sd->last_down[0].x;
1095         point.y = sd->last_down[0].y;
1096         evas_object_smart_callback_call(sd->child_obj, "one,single,tap", &point);
1097      }
1098 }
1099
1100 static void
1101 _smart_emit_double_tap(Smart_Data *sd)
1102 {
1103    if (sd->child_obj)
1104      {
1105         DBG("<< emit_double_tap >>\n");
1106         Evas_Point point;
1107         point.x = sd->last_down[0].x;
1108         point.y = sd->last_down[0].y;
1109         evas_object_smart_callback_call(sd->child_obj, "one,double,tap", &point);
1110      }
1111 }
1112
1113 static void
1114 _smart_emit_long_hold(Smart_Data *sd)
1115 {
1116    if (sd->child_obj)
1117      {
1118         DBG("<< emit_long_hold >>\n");
1119         Evas_Point point;
1120         point.x = sd->last_down[0].x;
1121         point.y = sd->last_down[0].y;
1122         evas_object_smart_callback_call(sd->child_obj, "one,long,press", &point);
1123      }
1124 }
1125
1126 static void
1127 _smart_emit_release(Smart_Data *sd)
1128 {
1129    if (sd->child_obj)
1130      {
1131         DBG("<< emit_release >>\n");
1132         Evas_Point point;
1133         point.x = sd->last_down[0].x;
1134         point.y = sd->last_down[0].y;
1135         evas_object_smart_callback_call(sd->child_obj, "one,release", &point);
1136      }
1137 }
1138
1139 static void
1140 _smart_emit_two_press(Smart_Data *sd)
1141 {
1142    if (sd->child_obj)
1143      {
1144         DBG("<< emit_two_press >>\n");
1145         Two_Mouse_Data two_mouse_data;
1146         two_mouse_data.first.x = sd->last_down[0].x;
1147         two_mouse_data.first.y = sd->last_down[0].y;
1148         two_mouse_data.second.x = sd->last_down[1].x;
1149         two_mouse_data.second.y = sd->last_down[1].y;
1150         two_mouse_data.mode = sd->two_drag_mode;
1151         evas_object_smart_callback_call(sd->child_obj, "two,press", &two_mouse_data);
1152      }
1153 }
1154
1155 static void
1156 _smart_emit_two_tap(Smart_Data *sd)
1157 {
1158    if (sd->child_obj)
1159      {
1160         DBG("<< emit_two_tap >>\n");
1161         Two_Mouse_Data two_mouse_data;
1162         two_mouse_data.first.x = sd->last_down[0].x;
1163         two_mouse_data.first.y = sd->last_down[0].y;
1164         two_mouse_data.second.x = sd->last_down[1].x;
1165         two_mouse_data.second.y = sd->last_down[1].y;
1166         two_mouse_data.mode = sd->two_drag_mode;
1167         evas_object_smart_callback_call(sd->child_obj, "two,tap", &two_mouse_data);
1168      }
1169 }
1170
1171 static void
1172 _smart_emit_two_move_start(Smart_Data *sd)
1173 {
1174    if (sd->child_obj)
1175      {
1176         DBG("<< emit_two_move_start >>\n");
1177         Two_Mouse_Data two_mouse_data;
1178         two_mouse_data.first.x = sd->last_drag[0].x;
1179         two_mouse_data.first.y = sd->last_drag[0].y;
1180         two_mouse_data.second.x = sd->last_drag[1].x;
1181         two_mouse_data.second.y = sd->last_drag[1].y;
1182         two_mouse_data.mode = sd->two_drag_mode;
1183         evas_object_smart_callback_call(sd->child_obj, "two,move,start", &two_mouse_data);
1184      }
1185 }
1186
1187 static void
1188 _smart_emit_two_move(Smart_Data *sd)
1189 {
1190    if (sd->child_obj)
1191      {
1192         Two_Mouse_Data two_mouse_data;
1193         two_mouse_data.first.x = sd->last_drag[0].x;
1194         two_mouse_data.first.y = sd->last_drag[0].y;
1195         two_mouse_data.second.x = sd->last_drag[1].x;
1196         two_mouse_data.second.y = sd->last_drag[1].y;
1197         two_mouse_data.mode = sd->two_drag_mode;
1198         evas_object_smart_callback_call(sd->child_obj, "two,move", &two_mouse_data);
1199      }
1200 }
1201
1202 static void
1203 _smart_emit_two_move_end(Smart_Data *sd)
1204 {
1205    if (sd->child_obj)
1206      {
1207         DBG("<< emit_two_move_end >>\n");
1208         Two_Mouse_Data two_mouse_data;
1209         two_mouse_data.first.x = sd->last_drag[0].x;
1210         two_mouse_data.first.y = sd->last_drag[0].y;
1211         two_mouse_data.second.x = sd->last_drag[1].x;
1212         two_mouse_data.second.y = sd->last_drag[1].y;
1213         two_mouse_data.mode = sd->two_drag_mode;
1214         evas_object_smart_callback_call(sd->child_obj, "two,move,end", &two_mouse_data);
1215      }
1216 }
1217
1218 static void
1219 _smart_emit_three_press(Smart_Data *sd)
1220 {
1221    if (sd->child_obj)
1222      {
1223         DBG("<< emit_three_press >>\n");
1224         Three_Mouse_Data three_mouse_data;
1225         three_mouse_data.first.x = sd->last_drag[0].x;
1226         three_mouse_data.first.y = sd->last_drag[0].y;
1227         three_mouse_data.second.x = sd->last_drag[1].x;
1228         three_mouse_data.second.y = sd->last_drag[1].y;
1229         three_mouse_data.third.x = sd->last_drag[2].x;
1230         three_mouse_data.third.y = sd->last_drag[2].y;
1231         evas_object_smart_callback_call(sd->child_obj, "three,press", &three_mouse_data);
1232      }
1233 }
1234
1235 static void
1236 _smart_emit_three_tap(Smart_Data *sd)
1237 {
1238    if (sd->child_obj)
1239      {
1240         DBG("<< emit_three_tap >>\n");
1241         Three_Mouse_Data three_mouse_data;
1242         three_mouse_data.first.x = sd->last_drag[0].x;
1243         three_mouse_data.first.y = sd->last_drag[0].y;
1244         three_mouse_data.second.x = sd->last_drag[1].x;
1245         three_mouse_data.second.y = sd->last_drag[1].y;
1246         three_mouse_data.third.x = sd->last_drag[2].x;
1247         three_mouse_data.third.y = sd->last_drag[2].y;
1248         evas_object_smart_callback_call(sd->child_obj, "three,tap", &three_mouse_data);
1249      }
1250 }
1251
1252 /* timer event handling */
1253 static int
1254 _smart_press_timer_handler(void *data)
1255 {
1256    Smart_Data *sd;
1257
1258    sd = data;
1259    _smart_emit_press(sd);
1260    sd->press_timer = NULL;
1261    return ECORE_CALLBACK_CANCEL;
1262 }
1263
1264 static int
1265 _smart_long_press_timer_handler(void *data)
1266 {
1267    Smart_Data *sd;
1268
1269    sd = data;
1270    _smart_emit_long_hold(sd);
1271    _smart_enter_hold(sd);
1272    sd->long_press_timer = NULL;
1273    return ECORE_CALLBACK_CANCEL;
1274 }
1275
1276 static int
1277 _smart_release_timer_handler(void *data)
1278 {
1279    Smart_Data *sd;
1280
1281    sd = data;
1282    _smart_emit_tap(sd);
1283    _smart_stop_all_timers(sd);
1284    _smart_enter_none(sd);
1285    sd->release_timer = NULL;
1286    return ECORE_CALLBACK_CANCEL;
1287 }
1288
1289 static int
1290 _smart_press_release_timer_handler(void *data)
1291 {
1292    static int prevent_handler = 0;
1293    if (prevent_handler != 0) return ECORE_CALLBACK_CANCEL;
1294    prevent_handler = 1;
1295    Smart_Data *sd;
1296
1297    sd = data;
1298    _smart_emit_press(sd);
1299    _smart_emit_tap(sd);
1300    _smart_stop_all_timers(sd);
1301    _smart_enter_none(sd);
1302    sd->press_release_timer = NULL;
1303    prevent_handler = 0;
1304    return ECORE_CALLBACK_CANCEL;
1305 }
1306
1307 /* other functions */
1308 static void
1309 _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy)
1310 {
1311    // save pan information to the pan history
1312    int index = (sd->last_move_history_index + 1) % MOVE_HISTORY_SIZE;
1313    sd->last_move_history_index = index;
1314    sd->move_history[index].dx = dx;
1315    sd->move_history[index].dy = dy;
1316    sd->move_history[index].time = ecore_time_get();
1317    sd->move_history_count++;
1318 }
1319
1320 static void
1321 _smart_start_flick(Smart_Data *sd)
1322 {
1323    if (sd->animator_move)
1324      {
1325         ecore_animator_del(sd->animator_move);
1326         DBG("<< stop_animator_move >>\n");
1327         sd->animator_move = NULL;
1328
1329         // start flick
1330         // accumulate sd->move_history data
1331         int nSamples = 0;
1332         int totalDx = 0;
1333         int totalDy = 0;
1334         int index = sd->last_move_history_index;
1335         int todo = sd->move_history_count > MOVE_HISTORY_SIZE ? MOVE_HISTORY_SIZE : sd->move_history_count;
1336         Mouse_Diff_Data *p;
1337         double endTime = ecore_time_get();
1338         double startTime = endTime;
1339         for( ; todo > 0; todo--) {
1340              p = sd->move_history + index; // get one sd->move_history
1341
1342              // get values
1343              startTime = p->time;
1344              totalDx += p->dx;
1345              totalDy += p->dy;
1346              nSamples++;
1347
1348              if ((endTime - startTime) > 0.2 && nSamples > 0)
1349                break;
1350
1351              index = (index > 0) ? (index - 1) : (MOVE_HISTORY_SIZE - 1); // set index
1352         }
1353         double totalTime = endTime - startTime;
1354         if (totalTime < DOUBLE_ERROR)
1355           totalTime = 0.001;
1356
1357         // calculate average pan_dx and pan_dy (per 1 / DEFAULT_FRAMERATE ms)
1358         double temp = totalTime * DEFAULT_FRAMERATE;
1359         if (temp <= 0)
1360           temp = 1;
1361
1362         Flick_Data *flick_data = &sd->flick_data;
1363         flick_data->avg_distance.x = totalDx / temp;
1364         flick_data->avg_distance.y = totalDy / temp;
1365
1366         // set max value for pan_dx and pan_dy
1367         int abs_pan_dx = abs(flick_data->avg_distance.x);
1368         int abs_pan_dy = abs(flick_data->avg_distance.y);
1369         if ((abs_pan_dx > MAX_MOVE_DISTANCE) && (abs_pan_dx > abs_pan_dy))
1370           {
1371              flick_data->avg_distance.x = (flick_data->avg_distance.x > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1372              flick_data->avg_distance.y = flick_data->avg_distance.y * MAX_MOVE_DISTANCE / abs_pan_dx;
1373
1374           }
1375         else if ((abs_pan_dy > MAX_MOVE_DISTANCE) && (abs_pan_dy > abs_pan_dx))
1376           {
1377              flick_data->avg_distance.y = (flick_data->avg_distance.y > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1378              flick_data->avg_distance.x = flick_data->avg_distance.x * MAX_MOVE_DISTANCE / abs_pan_dy;
1379           }
1380
1381         if (abs_pan_dx > FLICK_THRESHOLD || abs_pan_dy > FLICK_THRESHOLD)
1382           {
1383              // set flick_data and start flick
1384              flick_data->last.x = sd->last_drag[0].x;
1385              flick_data->last.y = sd->last_drag[0].y;
1386              flick_data->flick_index = 0;
1387              sd->animator_flick = ecore_animator_add(_smart_animation_flick, sd);
1388              DBG("<< sd->animator_flick >>\n");
1389           }
1390         else
1391           {
1392              Evas_Point point;
1393              point.x = sd->last_drag[0].x;
1394              point.y = sd->last_drag[0].y;
1395              evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1396              _smart_enter_none(sd);
1397           }
1398      }
1399    else
1400      {
1401         _smart_emit_release(sd);
1402         _smart_stop_all_timers(sd);
1403         _smart_enter_none(sd);
1404      }
1405 }
1406
1407 static void
1408 _smart_stop_animator_move(Smart_Data *sd)
1409 {
1410    if (sd->animator_move)
1411      {
1412         ecore_animator_del(sd->animator_move);
1413         DBG("<< stop_animator_move >>\n");
1414         sd->animator_move = NULL;
1415         Evas_Point point;
1416         point.x = sd->last_drag[0].x;
1417         point.y = sd->last_drag[0].y;
1418         evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1419      }
1420 }
1421
1422 static void
1423 _smart_stop_animator_flick(Smart_Data *sd)
1424 {
1425    if (sd->animator_flick)
1426      {
1427         ecore_animator_del(sd->animator_flick);
1428         DBG("<< stop_animator_flick >>\n");
1429         sd->animator_flick = NULL;
1430         Evas_Coord_Point point;
1431         point = sd->flick_data.last;
1432         evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1433      }
1434 }
1435
1436 static void
1437 _smart_stop_animator_two_move(Smart_Data *sd)
1438 {
1439    if (sd->animator_two_move)
1440      {
1441         ecore_animator_del(sd->animator_two_move);
1442         DBG("<< stop_animator_two_move >>\n");
1443         sd->animator_two_move = NULL;
1444         _smart_emit_two_move_end(sd);
1445      }
1446 }
1447
1448 static Two_Drag_Mode
1449 _smart_check_two_drag_mode(Smart_Data *sd)
1450 {
1451    // get distance from press to current position
1452    int dx0 = sd->last_drag[0].x - sd->first_down[0].x;
1453    int dy0 = sd->last_drag[0].y - sd->first_down[0].y;
1454    int dx1 = sd->last_drag[1].x - sd->first_down[1].x;
1455    int dy1 = sd->last_drag[1].y - sd->first_down[1].y;
1456    int dx = 0;
1457    int dy = 0;
1458
1459    // select dx and dy
1460    if ((abs(dx1) >= MOVE_THRESHOLD) || (abs(dy1) >= MOVE_THRESHOLD))
1461      {
1462         dx = dx1;
1463         dy = dy1;
1464      }
1465    else if ((abs(dx0) >= MOVE_THRESHOLD) || (abs(dy0) >= MOVE_THRESHOLD))
1466      {
1467         dx = dx0;
1468         dy = dy0;
1469      }
1470    else
1471      {
1472         return TWO_DRAG_NONE;
1473      }
1474
1475    // same x direction
1476    if ((abs(dx) > abs(dy)) && ((dx0 > 0 && dx1 > 0) || (dx0 < 0 && dx1 < 0)))
1477      {
1478         dy = (dy == 0) ? 1 : dy;
1479         // less than 30 degree (1024/root(3) = 591)
1480         if (((abs(dy) << 10) / abs(dx)) < 591)
1481           {
1482              return TWO_DRAG_HORIZONTAL;
1483           }
1484      }
1485
1486    // same y direction
1487    if ((abs(dy) > abs(dx)) && ((dy0 > 0 && dy1 > 0) || (dy0 < 0 && dy1 < 0)))
1488      {
1489         dx = (dx == 0) ? 1 : dx;
1490         // more than 60 degree (1024 * root(3)/1 = 1773)
1491         if (((abs(dy) << 10) / abs(dx)) > 1773)
1492           {
1493              return TWO_DRAG_VERTICAL;
1494           }
1495      }
1496
1497    // pinch direction
1498    int distanceX = abs(abs(sd->first_down[0].x - sd->first_down[1].x)
1499          - abs(sd->last_drag[0].x - sd->last_drag[1].x));
1500    int distanceY = abs(abs(sd->first_down[0].y - sd->first_down[1].y)
1501          - abs(sd->last_drag[0].y - sd->last_drag[1].y));
1502    if ((distanceX > FINGER_DISTANCE) || (distanceY > FINGER_DISTANCE))
1503      {
1504         return TWO_DRAG_PINCH;
1505      }
1506
1507    return TWO_DRAG_NONE;
1508 }
1509
1510 static void
1511 _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data)
1512 {
1513    if (index > N_FINGER)
1514      {
1515         return;
1516      }
1517
1518    if ((sd->screen_angle == 270) && (index > 0))
1519      {
1520         sd->first_down[index].x = data->y;
1521         sd->first_down[index].y = data->x;
1522         sd->first_down[index].time = data->time;
1523         sd->first_down[index].device = data->device;
1524      }
1525    else
1526      {
1527         sd->first_down[index].x = data->x;
1528         sd->first_down[index].y = data->y;
1529         sd->first_down[index].time = data->time;
1530         sd->first_down[index].device = data->device;
1531      }
1532 }
1533
1534 static void
1535 _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data)
1536 {
1537    if (index > N_FINGER)
1538      {
1539         return;
1540      }
1541
1542    if ((sd->screen_angle == 270) && (index > 0))
1543      {
1544         sd->last_down[index].x = data->y;
1545         sd->last_down[index].y = data->x;
1546         sd->last_down[index].time = data->time;
1547         sd->last_down[index].device = data->device;
1548      }
1549    else
1550      {
1551         sd->last_down[index].x = data->x;
1552         sd->last_down[index].y = data->y;
1553         sd->last_down[index].time = data->time;
1554         sd->last_down[index].device = data->device;
1555      }
1556 }
1557
1558 static void
1559 _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data)
1560 {
1561    if (index > N_FINGER)
1562      {
1563         return;
1564      }
1565
1566    if ((sd->screen_angle == 270) && (index > 0))
1567      {
1568         sd->last_drag[index].x = data->y;
1569         sd->last_drag[index].y = data->x;
1570         sd->last_drag[index].time = data->time;
1571         sd->last_drag[index].device = data->device;
1572      }
1573    else
1574      {
1575         sd->last_drag[index].x = data->x;
1576         sd->last_drag[index].y = data->y;
1577         sd->last_drag[index].time = data->time;
1578         sd->last_drag[index].device = data->device;
1579      }
1580 }
1581
1582 static void
1583 _smart_stop_all_timers(Smart_Data *sd)
1584 {
1585    if (sd->press_timer) // remove sd->press_timer
1586      {
1587         ecore_timer_del(sd->press_timer);
1588         sd->press_timer = NULL;
1589      }
1590
1591    if (sd->long_press_timer) // remove long press timer
1592      {
1593         ecore_timer_del(sd->long_press_timer);
1594         sd->long_press_timer = NULL;
1595      }
1596
1597    if (sd->release_timer) // remove release timer
1598      {
1599         ecore_timer_del(sd->release_timer);
1600         sd->release_timer = NULL;
1601      }
1602
1603    if (sd->press_release_timer) // remove pressRelease timer
1604      {
1605         ecore_timer_del(sd->press_release_timer);
1606         sd->press_release_timer = NULL;
1607      }
1608 }
1609
1610 static void
1611 _smart_add(Evas_Object *obj)
1612 {
1613    Smart_Data *sd;
1614
1615    sd = calloc(1, sizeof(Smart_Data));
1616    if (!sd) return;
1617    memset((void *)sd, 0x00, sizeof(Smart_Data));
1618
1619    sd->smart_obj = obj;
1620
1621    // set default framerate
1622    ecore_animator_frametime_set(1.0 / DEFAULT_FRAMERATE);
1623
1624    evas_object_smart_data_set(obj, sd);
1625 }
1626
1627 static void
1628 _smart_del(Evas_Object *obj)
1629 {
1630    INTERNAL_ENTRY;
1631    if (sd)
1632      {
1633         if (sd->press_timer)
1634           ecore_timer_del(sd->press_timer);
1635
1636         if (sd->long_press_timer)
1637           ecore_timer_del(sd->long_press_timer);
1638
1639         if (sd->release_timer)
1640           ecore_timer_del(sd->release_timer);
1641
1642         if (sd->press_release_timer)
1643           ecore_timer_del(sd->press_release_timer);
1644
1645         if (sd->animator_move)
1646           ecore_animator_del(sd->animator_move);
1647
1648         if (sd->animator_flick)
1649           ecore_animator_del(sd->animator_flick);
1650
1651         if (sd->animator_two_move)
1652           ecore_animator_del(sd->animator_two_move);
1653
1654         if (sd->child_obj)
1655           {
1656              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
1657              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
1658              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
1659              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
1660              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
1661              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
1662           }
1663
1664         free(sd);
1665      }
1666 }
1667
1668 static void
1669 _smart_init(void)
1670 {
1671    if (_smart) return;
1672
1673    static const Evas_Smart_Class sc = 
1674      {
1675         SMART_NAME,
1676         EVAS_SMART_CLASS_VERSION,
1677         _smart_add,
1678         _smart_del,
1679         NULL,
1680         NULL,
1681         NULL,
1682         NULL,
1683         NULL,
1684         NULL,
1685         NULL,
1686         NULL,
1687         NULL,
1688         NULL,
1689         NULL,
1690         NULL,
1691         NULL,
1692         NULL
1693      };
1694    _smart = evas_smart_class_new(&sc);
1695 }