Merge branch 'master' of 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_FALSE;
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              if (sd->state == TOUCH_STATE_DRAG)
730                _smart_enter_none(sd);
731              return ECORE_CALLBACK_CANCEL;
732           }
733         else
734           {
735              Evas_Coord_Point point;
736              point = flick_data->last;
737              if (sd->is_one_drag_mode)
738                {
739                   if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
740                     {
741                        point.x = sd->first_down[0].x;
742                     }
743                   else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
744                     {
745                        point.y = sd->first_down[0].y;
746                     }
747                }
748              evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
749              return ECORE_CALLBACK_RENEW;
750           }
751      }
752    else
753      {
754         _smart_stop_animator_flick(sd);
755         _smart_enter_none(sd);
756         return ECORE_CALLBACK_CANCEL;
757      }
758 }
759
760 static int
761 _smart_animation_two_move(void *data)
762 {
763    Smart_Data *sd;
764
765    sd = data;
766
767    if (sd->child_obj)
768      {
769         _smart_emit_two_move(sd);
770         return ECORE_CALLBACK_RENEW;
771      }
772    else
773      {
774         _smart_stop_animator_two_move(sd);
775         _smart_enter_none(sd);
776         return ECORE_CALLBACK_CANCEL;
777      }
778
779 }
780
781 /* state switching */
782 static void
783 _smart_enter_none(Smart_Data *sd)
784 {
785    sd->numOfTouch = 0;
786    sd->two_drag_mode = TWO_DRAG_NONE;
787    sd->state = TOUCH_STATE_NONE;
788    DBG("\nTOUCH_STATE_NONE\n");
789 }
790
791 static void
792 _smart_enter_down(Smart_Data *sd)
793 {
794    // set press timer
795    sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
796
797    // set long press timer
798    sd->long_press_timer = ecore_timer_add(((double)LONG_HOLD_TIME)/1000.0, _smart_long_press_timer_handler, sd);
799
800    sd->state = TOUCH_STATE_DOWN;
801    DBG("\nTOUCH_STATE_DOWN\n");
802 }
803
804 static void
805 _smart_enter_down_up(Smart_Data *sd, int downTime, int time)
806 {
807    // remove sd->press_timer and set new timer
808    int timerTime = RELEASE_TIME - (downTime - PRESS_TIME);
809    if (sd->press_timer)
810      {
811         ecore_timer_del(sd->press_timer);
812         sd->press_timer = NULL;
813         sd->press_release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_press_release_timer_handler, sd);
814
815      }
816    else
817      {
818         sd->release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_release_timer_handler, sd);
819      }
820
821    if (sd->long_press_timer) // remove long press timer
822      {
823         ecore_timer_del(sd->long_press_timer);
824         sd->long_press_timer = NULL;
825      }
826
827    sd->state = TOUCH_STATE_DOWN_UP;
828    DBG("\nTOUCH_STATE_DOWN_UP\n");
829 }
830
831 static void
832 _smart_enter_down_up_down(Smart_Data *sd)
833 {
834    if (sd->press_release_timer) // remove press_release_timer
835      {
836         ecore_timer_del(sd->press_release_timer);
837         sd->press_release_timer = NULL;
838      }
839
840    if (sd->release_timer) // remove ReleaseTimer
841      {
842         ecore_timer_del(sd->release_timer);
843         sd->release_timer = NULL;
844      }
845
846    sd->state = TOUCH_STATE_DOWN_UP_DOWN;
847    DBG("\nTOUCH_STATE_DOWN_UP_DOWN\n");
848 }
849
850 static void
851 _smart_enter_hold(Smart_Data *sd)
852 {
853    sd->state = TOUCH_STATE_HOLD;
854    DBG("\nTOUCH_STATE_HOLD\n");
855 }
856
857 static void
858 _smart_enter_drag(Smart_Data *sd)
859 {
860    if (sd->press_timer) // remove press_timer
861      {
862         ecore_timer_del(sd->press_timer);
863         sd->press_timer = NULL;
864      }
865
866    if (sd->press_release_timer) // remove press_release_timer
867      {
868         ecore_timer_del(sd->press_release_timer);
869         sd->press_release_timer = NULL;
870      }
871
872    if (sd->release_timer) // remove ReleaseTimer
873      {
874         ecore_timer_del(sd->release_timer);
875         sd->release_timer = NULL;
876      }
877
878    if (sd->long_press_timer) // remove long press timer
879      {
880         ecore_timer_del(sd->long_press_timer);
881         sd->long_press_timer = NULL;
882      }
883
884    if (sd->child_obj)
885      {
886         if (sd->is_one_drag_mode)
887           {
888              sd->one_drag_mode = ONE_DRAG_NONE;
889              int abs_dx = abs(sd->first_down[0].x - sd->last_drag[0].x);
890              int abs_dy = abs(sd->first_down[0].y - sd->last_drag[0].y);
891              abs_dx = (abs_dx == 0) ? 1 : abs_dx;
892              DBG("<< abs_dx[%d], abs_dy[%d] >>\n\n", abs_dx, abs_dy);
893              float degree = (float)abs_dy / (float)abs_dx;
894              // more than 70 degree
895              if (degree > tan(70 * M_PI / 180))
896                {
897                   sd->one_drag_mode = ONE_DRAG_VERTICAL;
898                }
899              // less than 20 degree
900              else if (degree < tan(20 * M_PI / 180))
901                {
902                   sd->one_drag_mode = ONE_DRAG_HORIZONTAL;
903                }
904           }
905         Evas_Point point;
906         point.x = sd->last_down[0].x;
907         point.y = sd->last_down[0].y;
908         evas_object_smart_callback_call(sd->child_obj, "one,move,start", &point);
909
910         // initialize flick variables
911         sd->last_move_history_index = -1;
912         sd->move_history_count = 0;
913
914         sd->animator_move = ecore_animator_add(_smart_animation_move, sd);
915         DBG("<< sd->animator_move >>\n");
916         sd->state = TOUCH_STATE_DRAG;
917         DBG("\nTOUCH_STATE_DRAG\n");
918      }
919    else
920      {
921         sd->state = TOUCH_STATE_NONE;
922      }
923 }
924
925 static void
926 _smart_enter_two_down(Smart_Data *sd)
927 {
928    _smart_stop_all_timers(sd);
929
930    if (sd->child_obj)
931      {
932         DBG("<< enter two down >>\n");
933         sd->state = TOUCH_STATE_TWO_DOWN;
934         _smart_emit_two_press(sd);
935      }
936 }
937
938 static void
939 _smart_enter_two_drag(Smart_Data *sd)
940 {
941    if (sd->child_obj)
942      {
943         DBG("<< sd->animator_two_move >>\n");
944         sd->state = TOUCH_STATE_TWO_DRAG;
945         _smart_emit_two_move_start(sd);
946         sd->animator_two_move = ecore_animator_add(_smart_animation_two_move, sd);
947      }
948    else
949      {
950         sd->state = TOUCH_STATE_NONE;
951      }
952 }
953
954 static void
955 _smart_enter_three_down(Smart_Data *sd)
956 {
957    if (sd->child_obj)
958      {
959         sd->state = TOUCH_STATE_THREE_DOWN;
960         _smart_emit_three_press(sd);
961      }
962 }
963
964 /* producing output events */
965 static void
966 _smart_emit_press(Smart_Data *sd)
967 {
968    if (sd->child_obj)
969      {
970         DBG("<< emit_press >>\n");
971         Evas_Point point;
972         point.x = sd->last_down[0].x;
973         point.y = sd->last_down[0].y;
974         evas_object_smart_callback_call(sd->child_obj, "one,press", &point);
975      }
976 }
977
978 static void
979 _smart_emit_tap(Smart_Data *sd)
980 {
981    if (sd->child_obj)
982      {
983         DBG("<< emit_tap >>\n");
984         Evas_Point point;
985         point.x = sd->last_down[0].x;
986         point.y = sd->last_down[0].y;
987         evas_object_smart_callback_call(sd->child_obj, "one,single,tap", &point);
988      }
989 }
990
991 static void
992 _smart_emit_double_tap(Smart_Data *sd)
993 {
994    if (sd->child_obj)
995      {
996         DBG("<< emit_double_tap >>\n");
997         Evas_Point point;
998         point.x = sd->last_down[0].x;
999         point.y = sd->last_down[0].y;
1000         evas_object_smart_callback_call(sd->child_obj, "one,double,tap", &point);
1001      }
1002 }
1003
1004 static void
1005 _smart_emit_long_hold(Smart_Data *sd)
1006 {
1007    if (sd->child_obj)
1008      {
1009         DBG("<< emit_long_hold >>\n");
1010         Evas_Point point;
1011         point.x = sd->last_down[0].x;
1012         point.y = sd->last_down[0].y;
1013         evas_object_smart_callback_call(sd->child_obj, "one,long,press", &point);
1014      }
1015 }
1016
1017 static void
1018 _smart_emit_release(Smart_Data *sd)
1019 {
1020    if (sd->child_obj)
1021      {
1022         DBG("<< emit_release >>\n");
1023         Evas_Point point;
1024         point.x = sd->last_down[0].x;
1025         point.y = sd->last_down[0].y;
1026         evas_object_smart_callback_call(sd->child_obj, "one,release", &point);
1027      }
1028 }
1029
1030 static void
1031 _smart_emit_two_press(Smart_Data *sd)
1032 {
1033    if (sd->child_obj)
1034      {
1035         DBG("<< emit_two_press >>\n");
1036         Two_Mouse_Data two_mouse_data;
1037         two_mouse_data.first.x = sd->last_down[0].x;
1038         two_mouse_data.first.y = sd->last_down[0].y;
1039         two_mouse_data.second.x = sd->last_down[1].x;
1040         two_mouse_data.second.y = sd->last_down[1].y;
1041         two_mouse_data.mode = sd->two_drag_mode;
1042         evas_object_smart_callback_call(sd->child_obj, "two,press", &two_mouse_data);
1043      }
1044 }
1045
1046 static void
1047 _smart_emit_two_tap(Smart_Data *sd)
1048 {
1049    if (sd->child_obj)
1050      {
1051         DBG("<< emit_two_tap >>\n");
1052         Two_Mouse_Data two_mouse_data;
1053         two_mouse_data.first.x = sd->last_down[0].x;
1054         two_mouse_data.first.y = sd->last_down[0].y;
1055         two_mouse_data.second.x = sd->last_down[1].x;
1056         two_mouse_data.second.y = sd->last_down[1].y;
1057         two_mouse_data.mode = sd->two_drag_mode;
1058         evas_object_smart_callback_call(sd->child_obj, "two,tap", &two_mouse_data);
1059      }
1060 }
1061
1062 static void
1063 _smart_emit_two_move_start(Smart_Data *sd)
1064 {
1065    if (sd->child_obj)
1066      {
1067         DBG("<< emit_two_move_start >>\n");
1068         Two_Mouse_Data two_mouse_data;
1069         two_mouse_data.first.x = sd->last_drag[0].x;
1070         two_mouse_data.first.y = sd->last_drag[0].y;
1071         two_mouse_data.second.x = sd->last_drag[1].x;
1072         two_mouse_data.second.y = sd->last_drag[1].y;
1073         two_mouse_data.mode = sd->two_drag_mode;
1074         evas_object_smart_callback_call(sd->child_obj, "two,move,start", &two_mouse_data);
1075      }
1076 }
1077
1078 static void
1079 _smart_emit_two_move(Smart_Data *sd)
1080 {
1081    if (sd->child_obj)
1082      {
1083         Two_Mouse_Data two_mouse_data;
1084         two_mouse_data.first.x = sd->last_drag[0].x;
1085         two_mouse_data.first.y = sd->last_drag[0].y;
1086         two_mouse_data.second.x = sd->last_drag[1].x;
1087         two_mouse_data.second.y = sd->last_drag[1].y;
1088         two_mouse_data.mode = sd->two_drag_mode;
1089         evas_object_smart_callback_call(sd->child_obj, "two,move", &two_mouse_data);
1090      }
1091 }
1092
1093 static void
1094 _smart_emit_two_move_end(Smart_Data *sd)
1095 {
1096    if (sd->child_obj)
1097      {
1098         DBG("<< emit_two_move_end >>\n");
1099         Two_Mouse_Data two_mouse_data;
1100         two_mouse_data.first.x = sd->last_drag[0].x;
1101         two_mouse_data.first.y = sd->last_drag[0].y;
1102         two_mouse_data.second.x = sd->last_drag[1].x;
1103         two_mouse_data.second.y = sd->last_drag[1].y;
1104         two_mouse_data.mode = sd->two_drag_mode;
1105         evas_object_smart_callback_call(sd->child_obj, "two,move,end", &two_mouse_data);
1106      }
1107 }
1108
1109 static void
1110 _smart_emit_three_press(Smart_Data *sd)
1111 {
1112    if (sd->child_obj)
1113      {
1114         DBG("<< emit_three_press >>\n");
1115         Three_Mouse_Data three_mouse_data;
1116         three_mouse_data.first.x = sd->last_drag[0].x;
1117         three_mouse_data.first.y = sd->last_drag[0].y;
1118         three_mouse_data.second.x = sd->last_drag[1].x;
1119         three_mouse_data.second.y = sd->last_drag[1].y;
1120         three_mouse_data.third.x = sd->last_drag[2].x;
1121         three_mouse_data.third.y = sd->last_drag[2].y;
1122         evas_object_smart_callback_call(sd->child_obj, "three,press", &three_mouse_data);
1123      }
1124 }
1125
1126 static void
1127 _smart_emit_three_tap(Smart_Data *sd)
1128 {
1129    if (sd->child_obj)
1130      {
1131         DBG("<< emit_three_tap >>\n");
1132         Three_Mouse_Data three_mouse_data;
1133         three_mouse_data.first.x = sd->last_drag[0].x;
1134         three_mouse_data.first.y = sd->last_drag[0].y;
1135         three_mouse_data.second.x = sd->last_drag[1].x;
1136         three_mouse_data.second.y = sd->last_drag[1].y;
1137         three_mouse_data.third.x = sd->last_drag[2].x;
1138         three_mouse_data.third.y = sd->last_drag[2].y;
1139         evas_object_smart_callback_call(sd->child_obj, "three,tap", &three_mouse_data);
1140      }
1141 }
1142
1143 /* timer event handling */
1144 static int
1145 _smart_press_timer_handler(void *data)
1146 {
1147    Smart_Data *sd;
1148
1149    sd = data;
1150    _smart_emit_press(sd);
1151    sd->press_timer = NULL;
1152    return ECORE_CALLBACK_CANCEL;
1153 }
1154
1155 static int
1156 _smart_long_press_timer_handler(void *data)
1157 {
1158    Smart_Data *sd;
1159
1160    sd = data;
1161    _smart_emit_long_hold(sd);
1162    _smart_enter_hold(sd);
1163    sd->long_press_timer = NULL;
1164    return ECORE_CALLBACK_CANCEL;
1165 }
1166
1167 static int
1168 _smart_release_timer_handler(void *data)
1169 {
1170    Smart_Data *sd;
1171
1172    sd = data;
1173    _smart_emit_tap(sd);
1174    _smart_stop_all_timers(sd);
1175    _smart_enter_none(sd);
1176    sd->release_timer = NULL;
1177    return ECORE_CALLBACK_CANCEL;
1178 }
1179
1180 static int
1181 _smart_press_release_timer_handler(void *data)
1182 {
1183    static int prevent_handler = 0;
1184    if (prevent_handler != 0) return ECORE_CALLBACK_CANCEL;
1185    prevent_handler = 1;
1186    Smart_Data *sd;
1187
1188    sd = data;
1189    _smart_emit_press(sd);
1190    _smart_emit_tap(sd);
1191    _smart_stop_all_timers(sd);
1192    _smart_enter_none(sd);
1193    sd->press_release_timer = NULL;
1194    prevent_handler = 0;
1195    return ECORE_CALLBACK_CANCEL;
1196 }
1197
1198 /* other functions */
1199 static void
1200 _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy)
1201 {
1202    // save pan information to the pan history
1203    int index = (sd->last_move_history_index + 1) % MOVE_HISTORY_SIZE;
1204    sd->last_move_history_index = index;
1205    sd->move_history[index].dx = dx;
1206    sd->move_history[index].dy = dy;
1207    sd->move_history[index].time = ecore_time_get();
1208    sd->move_history_count++;
1209 }
1210
1211 static void
1212 _smart_start_flick(Smart_Data *sd)
1213 {
1214    if (sd->animator_move)
1215      {
1216         ecore_animator_del(sd->animator_move);
1217         DBG("<< stop_animator_move >>\n");
1218         sd->animator_move = NULL;
1219
1220         // start flick
1221         // accumulate sd->move_history data
1222         int nSamples = 0;
1223         int totalDx = 0;
1224         int totalDy = 0;
1225         int index = sd->last_move_history_index;
1226         int todo = sd->move_history_count > MOVE_HISTORY_SIZE ? MOVE_HISTORY_SIZE : sd->move_history_count;
1227         Mouse_Diff_Data *p;
1228         double endTime = (sd->move_history + index)->time;
1229         double startTime = endTime;
1230         for( ; todo > 0; todo--) {
1231              p = sd->move_history + index; // get one sd->move_history
1232
1233              // get values
1234              startTime = p->time;
1235              totalDx += p->dx;
1236              totalDy += p->dy;
1237              nSamples++;
1238
1239              if ((endTime - startTime) > 0.2 && nSamples > 0)
1240                break;
1241
1242              index = (index > 0) ? (index - 1) : (MOVE_HISTORY_SIZE - 1); // set index
1243         }
1244         double totalTime = endTime - startTime;
1245         if (totalTime < DOUBLE_ERROR)
1246           totalTime = 0.001;
1247
1248         // calculate average pan_dx and pan_dy (per 1 / DEFAULT_FRAMERATE ms)
1249         double temp = totalTime * DEFAULT_FRAMERATE;
1250         if (temp <= 0)
1251           temp = 1;
1252
1253         Flick_Data *flick_data = &sd->flick_data;
1254         flick_data->avg_distance.x = totalDx / temp;
1255         flick_data->avg_distance.y = totalDy / temp;
1256
1257         // set max value for pan_dx and pan_dy
1258         int abs_pan_dx = abs(flick_data->avg_distance.x);
1259         int abs_pan_dy = abs(flick_data->avg_distance.y);
1260         if ((abs_pan_dx > MAX_MOVE_DISTANCE) && (abs_pan_dx > abs_pan_dy))
1261           {
1262              flick_data->avg_distance.x = (flick_data->avg_distance.x > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1263              flick_data->avg_distance.y = flick_data->avg_distance.y * MAX_MOVE_DISTANCE / abs_pan_dx;
1264
1265           }
1266         else if ((abs_pan_dy > MAX_MOVE_DISTANCE) && (abs_pan_dy > abs_pan_dx))
1267           {
1268              flick_data->avg_distance.y = (flick_data->avg_distance.y > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1269              flick_data->avg_distance.x = flick_data->avg_distance.x * MAX_MOVE_DISTANCE / abs_pan_dy;
1270           }
1271
1272         if (abs_pan_dx > FLICK_THRESHOLD || abs_pan_dy > FLICK_THRESHOLD)
1273           {
1274              // set flick_data and start flick
1275              flick_data->last.x = sd->last_drag[0].x;
1276              flick_data->last.y = sd->last_drag[0].y;
1277              flick_data->flick_index = 0;
1278              sd->animator_flick = ecore_animator_add(_smart_animation_flick, sd);
1279              DBG("<< sd->animator_flick >>\n");
1280           }
1281         else
1282           {
1283              Evas_Point point;
1284              point.x = sd->last_drag[0].x;
1285              point.y = sd->last_drag[0].y;
1286              evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1287              _smart_enter_none(sd);
1288           }
1289      }
1290    else
1291      {
1292         _smart_emit_release(sd);
1293         _smart_stop_all_timers(sd);
1294         _smart_enter_none(sd);
1295      }
1296 }
1297
1298 static void
1299 _smart_stop_animator_move(Smart_Data *sd)
1300 {
1301    if (sd->animator_move)
1302      {
1303         ecore_animator_del(sd->animator_move);
1304         DBG("<< stop_animator_move >>\n");
1305         sd->animator_move = NULL;
1306         Evas_Point point;
1307         point.x = sd->last_drag[0].x;
1308         point.y = sd->last_drag[0].y;
1309         evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1310      }
1311 }
1312
1313 static void
1314 _smart_stop_animator_flick(Smart_Data *sd)
1315 {
1316    if (sd->animator_flick)
1317      {
1318         ecore_animator_del(sd->animator_flick);
1319         DBG("<< stop_animator_flick >>\n");
1320         sd->animator_flick = NULL;
1321         Evas_Coord_Point point;
1322         point = sd->flick_data.last;
1323         evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1324      }
1325 }
1326
1327 static void
1328 _smart_stop_animator_two_move(Smart_Data *sd)
1329 {
1330    if (sd->animator_two_move)
1331      {
1332         ecore_animator_del(sd->animator_two_move);
1333         DBG("<< stop_animator_two_move >>\n");
1334         sd->animator_two_move = NULL;
1335         _smart_emit_two_move_end(sd);
1336      }
1337 }
1338
1339 static Two_Drag_Mode
1340 _smart_check_two_drag_mode(Smart_Data *sd)
1341 {
1342    // get distance from press to current position
1343    int dx0 = sd->last_drag[0].x - sd->first_down[0].x;
1344    int dy0 = sd->last_drag[0].y - sd->first_down[0].y;
1345    int dx1 = sd->last_drag[1].x - sd->first_down[1].x;
1346    int dy1 = sd->last_drag[1].y - sd->first_down[1].y;
1347    int dx = 0;
1348    int dy = 0;
1349
1350    // select dx and dy
1351    if ((abs(dx1) >= MOVE_THRESHOLD) || (abs(dy1) >= MOVE_THRESHOLD))
1352      {
1353         dx = dx1;
1354         dy = dy1;
1355      }
1356    else if ((abs(dx0) >= MOVE_THRESHOLD) || (abs(dy0) >= MOVE_THRESHOLD))
1357      {
1358         dx = dx0;
1359         dy = dy0;
1360      }
1361    else
1362      {
1363         return TWO_DRAG_NONE;
1364      }
1365
1366    // same x direction
1367    if ((abs(dx) > abs(dy)) && ((dx0 > 0 && dx1 > 0) || (dx0 < 0 && dx1 < 0)))
1368      {
1369         dy = (dy == 0) ? 1 : dy;
1370         // less than 30 degree (1024/root(3) = 591)
1371         if (((abs(dy) << 10) / abs(dx)) < 591)
1372           {
1373              return TWO_DRAG_HORIZONTAL;
1374           }
1375      }
1376
1377    // same y direction
1378    if ((abs(dy) > abs(dx)) && ((dy0 > 0 && dy1 > 0) || (dy0 < 0 && dy1 < 0)))
1379      {
1380         dx = (dx == 0) ? 1 : dx;
1381         // more than 60 degree (1024 * root(3)/1 = 1773)
1382         if (((abs(dy) << 10) / abs(dx)) > 1773)
1383           {
1384              return TWO_DRAG_VERTICAL;
1385           }
1386      }
1387
1388    // pinch direction
1389    int distanceX = abs(abs(sd->first_down[0].x - sd->first_down[1].x)
1390          - abs(sd->last_drag[0].x - sd->last_drag[1].x));
1391    int distanceY = abs(abs(sd->first_down[0].y - sd->first_down[1].y)
1392          - abs(sd->last_drag[0].y - sd->last_drag[1].y));
1393    if ((distanceX > FINGER_DISTANCE) || (distanceY > FINGER_DISTANCE))
1394      {
1395         return TWO_DRAG_PINCH;
1396      }
1397
1398    return TWO_DRAG_NONE;
1399 }
1400
1401 static void
1402 _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data)
1403 {
1404    if (index > N_FINGER)
1405      {
1406         return;
1407      }
1408
1409    if ((sd->screen_angle == 270) && (index > 0))
1410      {
1411         sd->first_down[index].x = data->y;
1412         sd->first_down[index].y = data->x;
1413         sd->first_down[index].time = data->time;
1414         sd->first_down[index].device = data->device;
1415      }
1416    else
1417      {
1418         sd->first_down[index].x = data->x;
1419         sd->first_down[index].y = data->y;
1420         sd->first_down[index].time = data->time;
1421         sd->first_down[index].device = data->device;
1422      }
1423 }
1424
1425 static void
1426 _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data)
1427 {
1428    if (index > N_FINGER)
1429      {
1430         return;
1431      }
1432
1433    if ((sd->screen_angle == 270) && (index > 0))
1434      {
1435         sd->last_down[index].x = data->y;
1436         sd->last_down[index].y = data->x;
1437         sd->last_down[index].time = data->time;
1438         sd->last_down[index].device = data->device;
1439      }
1440    else
1441      {
1442         sd->last_down[index].x = data->x;
1443         sd->last_down[index].y = data->y;
1444         sd->last_down[index].time = data->time;
1445         sd->last_down[index].device = data->device;
1446      }
1447 }
1448
1449 static void
1450 _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data)
1451 {
1452    if (index > N_FINGER)
1453      {
1454         return;
1455      }
1456
1457    if ((sd->screen_angle == 270) && (index > 0))
1458      {
1459         sd->last_drag[index].x = data->y;
1460         sd->last_drag[index].y = data->x;
1461         sd->last_drag[index].time = data->time;
1462         sd->last_drag[index].device = data->device;
1463      }
1464    else
1465      {
1466         sd->last_drag[index].x = data->x;
1467         sd->last_drag[index].y = data->y;
1468         sd->last_drag[index].time = data->time;
1469         sd->last_drag[index].device = data->device;
1470      }
1471 }
1472
1473 static void
1474 _smart_stop_all_timers(Smart_Data *sd)
1475 {
1476    if (sd->press_timer) // remove sd->press_timer
1477      {
1478         ecore_timer_del(sd->press_timer);
1479         sd->press_timer = NULL;
1480      }
1481
1482    if (sd->long_press_timer) // remove long press timer
1483      {
1484         ecore_timer_del(sd->long_press_timer);
1485         sd->long_press_timer = NULL;
1486      }
1487
1488    if (sd->release_timer) // remove release timer
1489      {
1490         ecore_timer_del(sd->release_timer);
1491         sd->release_timer = NULL;
1492      }
1493
1494    if (sd->press_release_timer) // remove pressRelease timer
1495      {
1496         ecore_timer_del(sd->press_release_timer);
1497         sd->press_release_timer = NULL;
1498      }
1499 }
1500
1501 static void
1502 _smart_add(Evas_Object *obj)
1503 {
1504    Smart_Data *sd;
1505
1506    sd = calloc(1, sizeof(Smart_Data));
1507    if (!sd) return;
1508    memset((void *)sd, 0x00, sizeof(Smart_Data));
1509
1510    sd->smart_obj = obj;
1511
1512    // set default framerate
1513    ecore_animator_frametime_set(1.0 / DEFAULT_FRAMERATE);
1514
1515    evas_object_smart_data_set(obj, sd);
1516 }
1517
1518 static void
1519 _smart_del(Evas_Object *obj)
1520 {
1521    INTERNAL_ENTRY;
1522    if (sd)
1523      {
1524         if (sd->press_timer)
1525           ecore_timer_del(sd->press_timer);
1526
1527         if (sd->long_press_timer)
1528           ecore_timer_del(sd->long_press_timer);
1529
1530         if (sd->release_timer)
1531           ecore_timer_del(sd->release_timer);
1532
1533         if (sd->press_release_timer)
1534           ecore_timer_del(sd->press_release_timer);
1535
1536         if (sd->animator_move)
1537           ecore_animator_del(sd->animator_move);
1538
1539         if (sd->animator_flick)
1540           ecore_animator_del(sd->animator_flick);
1541
1542         if (sd->animator_two_move)
1543           ecore_animator_del(sd->animator_two_move);
1544
1545         if (sd->child_obj)
1546           {
1547              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
1548              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
1549              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
1550              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
1551              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
1552              evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
1553           }
1554
1555         free(sd);
1556      }
1557 }
1558
1559 static void
1560 _smart_init(void)
1561 {
1562    if (_smart) return;
1563
1564    static const Evas_Smart_Class sc = 
1565      {
1566         SMART_NAME,
1567         EVAS_SMART_CLASS_VERSION,
1568         _smart_add,
1569         _smart_del,
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         NULL
1584      };
1585    _smart = evas_smart_class_new(&sc);
1586 }