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