95a1883fed1fbc3701b3b84c614acbf04787aec4
[framework/uifw/elementary.git] / src / lib / elm_gesture_layer.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 /** @defgroup Elm_Gesture_Layer Gesture Layer */
4
5 /* Some defaults */
6 #define ELM_MOUSE_DEVICE 0
7 /* ELM_GESTURE_NEGATIVE_ANGLE - magic number says we didn't compute this yet */
8 #define ELM_GESTURE_NEGATIVE_ANGLE (-1.0) /* Magic number */
9 #define ELM_GESTURE_MOMENTUM_DELAY 25
10 #define ELM_GESTURE_MOMENTUM_TIMEOUT 50
11 #define ELM_GESTURE_MULTI_TIMEOUT 50
12 #define ELM_GESTURE_MINIMUM_MOMENTUM 0.001
13
14 /* Some Trigo values */
15 #define RAD_90DEG  M_PI_2
16 #define RAD_180DEG M_PI
17 #define RAD_270DEG (M_PI_2 * 3)
18 #define RAD_360DEG (M_PI * 2)
19 /* #define DEBUG_GESTURE_LAYER 1 */
20
21 #define RAD2DEG(x) ((x) * 57.295779513)
22 #define DEG2RAD(x) ((x) / 57.295779513)
23
24 static void *
25 _glayer_bufdup(void *buf, size_t size)
26 {
27    void *p;
28    p = malloc(size);
29    memcpy(p, buf, size);
30    return p;
31 }
32 #define COPY_EVENT_INFO(EV) _glayer_bufdup(EV, sizeof(*EV))
33
34
35 #define SET_TEST_BIT(P) do { \
36    P->test = P->fn[ELM_GESTURE_STATE_START].cb || P->fn[ELM_GESTURE_STATE_MOVE].cb || P->fn[ELM_GESTURE_STATE_END].cb || P->fn[ELM_GESTURE_STATE_ABORT].cb; \
37 } while (0)
38
39 #define IS_TESTED(T) ((wd->gesture[T]) ? wd->gesture[T]->test : EINA_FALSE)
40
41 /**
42  * @internal
43  *
44  * @struct _Func_Data
45  * Struct holds callback information.
46  *
47  * @ingroup Elm_Gesture_Layer
48  */
49 struct _Func_Data
50 {
51    void *user_data; /**< Holds user data to CB (like sd) */
52    Elm_Gesture_Event_Cb cb;
53 };
54
55 /**
56  * @internal
57  *
58  * @typedef Func_Data
59  * type for callback information
60  *
61  * @ingroup Elm_Gesture_Layer
62  */
63 typedef struct _Func_Data Func_Data;
64
65 /**
66  * @internal
67  *
68  * @struct _Gesture_Info
69  * Struct holds gesture info
70  *
71  * @ingroup Elm_Gesture_Layer
72  */
73 struct _Gesture_Info
74 {
75   Evas_Object *obj;
76   void *data; /**< Holds gesture intemidiate processing data */
77   Func_Data fn[ELM_GESTURE_STATE_ABORT + 1]; /**< Callback info for states */
78 <<<<<<< HEAD
79   Elm_Gesture_Types g_type;  /**< gesture type */
80 =======
81   Elm_Gesture_Type g_type;  /**< gesture type */
82 >>>>>>> remotes/origin/upstream
83   Elm_Gesture_State state;  /**< gesture state */
84   void *info;                        /**< Data for the state callback */
85   Eina_Bool test; /**< if true this gesture should be tested on input */
86 };
87
88 /**
89  * @internal
90  *
91  * @typedef Gesture_Info
92  * Type for _Gesture_Info
93  *
94  * @ingroup Elm_Gesture_Layer
95  */
96 typedef struct _Gesture_Info Gesture_Info;
97
98 /**
99  * @internal
100  *
101  * @struct _Event_History
102  * Struct holds event history.
103  * These events are repeated if no gesture found.
104  *
105  * @ingroup Elm_Gesture_Layer
106  */
107 struct _Event_History
108 {
109    EINA_INLIST;
110    void *event;
111    Evas_Callback_Type event_type;
112 };
113
114 /**
115  * @internal
116  *
117  * @typedef Event_History
118  * Type for _Event_History
119  *
120  * @ingroup Elm_Gesture_Layer
121  */
122 typedef struct _Event_History Event_History;
123
124 /**
125  * @internal
126  *
127  * @struct _Pointer_Event
128  * Struct holds pointer-event info
129  * This is a generic pointer event structure
130  *
131  * @ingroup Elm_Gesture_Layer
132  */
133 struct _Pointer_Event
134 {
135    Evas_Coord x, y;
136    unsigned int timestamp;
137    int device;
138    Evas_Callback_Type event_type;
139 };
140
141 /**
142  * @internal
143  *
144  * @typedef Pointer_Event
145  * Type for generic pointer event structure
146  *
147  * @ingroup Elm_Gesture_Layer
148  */
149 typedef struct _Pointer_Event Pointer_Event;
150
151 /* All *Type structs hold result for the user in 'info' field
152  * The rest is gesture processing intermediate data.
153  * NOTE: info field must be FIRST in the struct.
154  * This is used when reporting ABORT in event_history_clear() */
155 struct _Taps_Type
156 {
157    Elm_Gesture_Taps_Info info;
158    unsigned int sum_x;
159    unsigned int sum_y;
160    unsigned int n_taps_needed;
161    unsigned int n_taps;
162    Eina_List *l;
163 };
164 typedef struct _Taps_Type Taps_Type;
165
166 struct _Long_Tap_Type
167 {
168    Elm_Gesture_Taps_Info info;
169    Evas_Coord center_x;
170    Evas_Coord center_y;
171    unsigned int max_touched;
172    Ecore_Timer *timeout; /* When this expires, long tap STARTed */
173    Eina_List *touched;
174 };
175 typedef struct _Long_Tap_Type Long_Tap_Type;
176
177 struct _Momentum_Type
178 {  /* Fields used by _line_test() */
179    Elm_Gesture_Momentum_Info info;
180    Evas_Coord_Point line_st;
181    Evas_Coord_Point line_end;
182    unsigned int t_st_x;  /* Time start on X */
183    unsigned int t_st_y;  /* Time start on Y */
184    unsigned int t_end;   /* Time end        */
185    unsigned int t_up; /* Recent up event time */
186    int xdir, ydir;
187 };
188 typedef struct _Momentum_Type Momentum_Type;
189
190 struct _Line_Data
191 {
192    Evas_Coord_Point line_st;
193    Evas_Coord_Point line_end;
194    Evas_Coord line_length;
195    unsigned int t_st;  /* Time start */
196    unsigned int t_end; /* Time end   */
197    int device;
198    double line_angle;  /* Current angle of line */
199 };
200 typedef struct _Line_Data Line_Data;
201
202 struct _Line_Type
203 {  /* Fields used by _line_test() */
204    Elm_Gesture_Line_Info info;
205    Eina_List *list; /* List of Line_Data */
206 };
207 typedef struct _Line_Type Line_Type;
208
209 struct _Zoom_Type
210 {  /* Fields used by _zoom_test() */
211    Elm_Gesture_Zoom_Info info;
212    Pointer_Event zoom_st;
213    Pointer_Event zoom_mv;
214    Pointer_Event zoom_st1;
215    Pointer_Event zoom_mv1;
216    Evas_Event_Mouse_Wheel *zoom_wheel;
217    Evas_Coord zoom_base;  /* Holds gap between fingers on zoom-start  */
218    Evas_Coord zoom_distance_tolerance;
219    unsigned int m_st_tm;      /* momentum start time */
220    unsigned int m_prev_tm;    /* momentum prev time  */
221    int dir;   /* Direction: 1=zoom-in, (-1)=zoom-out */
222    double m_base; /* zoom value when momentum starts */
223    double next_step;
224 };
225 typedef struct _Zoom_Type Zoom_Type;
226
227 struct _Rotate_Type
228 {  /* Fields used by _rotation_test() */
229    Elm_Gesture_Rotate_Info info;
230    Pointer_Event rotate_st;
231    Pointer_Event rotate_mv;
232    Pointer_Event rotate_st1;
233    Pointer_Event rotate_mv1;
234    unsigned int prev_momentum_tm; /* timestamp of prev_momentum */
235    double prev_momentum;   /* Snapshot of momentum 0.01 sec ago */
236    double accum_momentum;
237    double rotate_angular_tolerance;
238    double next_step;
239 };
240 typedef struct _Rotate_Type Rotate_Type;
241
242 struct _Widget_Data
243 {
244    Evas_Object *target;  /* Target Widget */
245    Event_History *event_history_list;
246
247    int line_min_length;
248    Evas_Coord zoom_distance_tolerance;
249    Evas_Coord line_distance_tolerance;
250    double line_angular_tolerance;
251    double zoom_wheel_factor; /* mouse wheel zoom steps */
252    double zoom_finger_factor; /* used for zoom factor */
253    double rotate_angular_tolerance;
254    unsigned int flick_time_limit_ms;
255    double long_tap_start_timeout;
256    Eina_Bool glayer_continues_enable;
257
258    double zoom_step;
259    double rotate_step;
260
261    Gesture_Info *gesture[ELM_GESTURE_LAST];
262    Ecore_Timer *dbl_timeout; /* When this expires, dbl click/taps ABORTed  */
263    Eina_List *pending; /* List of devices need to refeed *UP event */
264    Eina_List *touched;  /* Information  of touched devices   */
265
266    Eina_Bool repeat_events : 1;
267 };
268 typedef struct _Widget_Data Widget_Data;
269
270 static const char *widtype = NULL;
271 static void _del_hook(Evas_Object *obj);
272
273 static Eina_Bool _event_history_clear(Evas_Object *obj);
274 static void _reset_states(Widget_Data *wd);
275 static void _key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
276 static void _key_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
277 <<<<<<< HEAD
278 static void _zoom_with_wheel_test(Evas_Object *obj, void *event_info, Evas_Callback_Type event_type, Elm_Gesture_Types g_type);
279 =======
280 static void _zoom_with_wheel_test(Evas_Object *obj, void *event_info, Evas_Callback_Type event_type, Elm_Gesture_Type g_type);
281 >>>>>>> remotes/origin/upstream
282 static void _mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
283 static void _mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
284 static void _mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
285 static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
286
287 static void _multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
288 static void _multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
289 static void _multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
290
291 /* START - Functions to manage touched-device list */
292 /**
293  * @internal
294  * This function is used to find if device is touched
295  *
296  * @ingroup Elm_Gesture_Layer
297  */
298 static int
299 compare_device(const void *data1, const void *data2)
300 {  /* Compare the two device numbers */
301    return (((Pointer_Event *) data1)->device -((Pointer_Event *) data2)->device);
302 }
303
304 /**
305  * @internal
306  *
307  * Remove Pointer Event from touched device list
308  * @param list Pointer to touched device list.
309  * @param Pointer_Event Pointer to PE.
310  *
311  * @ingroup Elm_Gesture_Layer
312  */
313 static Eina_List *
314 _remove_touched_device(Eina_List *list, Pointer_Event *pe)
315 {
316    Eina_List *lst = NULL;
317    Pointer_Event *p = eina_list_search_unsorted(list, compare_device, pe);
318    if (p)
319      {
320         lst = eina_list_remove(list, p);
321         free(p);
322         return lst;
323      }
324
325    return list;
326 }
327
328 /**
329  * @internal
330  *
331  * Recoed Pointer Event in touched device list
332  * Note: This fuction allocates memory for PE event
333  * This memory is released in _remove_touched_device()
334  * @param list Pointer to touched device list.
335  * @param Pointer_Event Pointer to PE.
336  *
337  * @ingroup Elm_Gesture_Layer
338  */
339 static Eina_List *
340 _add_touched_device(Eina_List *list, Pointer_Event *pe)
341 {
342    Pointer_Event *p = eina_list_search_unsorted(list, compare_device, pe);
343    if (p)
344      {  /* We like to track device touch-position, overwrite info */
345         memcpy(p, pe, sizeof(Pointer_Event));
346         return list;
347      }
348
349    if ((pe->event_type == EVAS_CALLBACK_MOUSE_DOWN) ||
350          (pe->event_type == EVAS_CALLBACK_MULTI_DOWN))
351      {  /* Add touched device on DOWN event only */
352         p = malloc(sizeof(Pointer_Event));
353         /* Freed in _remove_touched_device()    */
354         memcpy(p, pe, sizeof(Pointer_Event));
355         return eina_list_append(list, p);
356      }
357
358    return list;
359 }
360 /* END   - Functions to manage touched-device list */
361
362 /**
363  * @internal
364  *
365  * Get event flag
366  * @param event_info pointer to event.
367  *
368  * @ingroup Elm_Gesture_Layer
369  */
370 static Evas_Event_Flags
371 _get_event_flag(void *event_info, Evas_Callback_Type event_type)
372 {
373    switch(event_type)
374      {
375       case EVAS_CALLBACK_MOUSE_IN:
376          return ((Evas_Event_Mouse_In *) event_info)->event_flags;
377       case EVAS_CALLBACK_MOUSE_OUT:
378          return ((Evas_Event_Mouse_Out *) event_info)->event_flags;
379       case EVAS_CALLBACK_MOUSE_DOWN:
380          return ((Evas_Event_Mouse_Down *) event_info)->event_flags;
381       case EVAS_CALLBACK_MOUSE_MOVE:
382          return ((Evas_Event_Mouse_Move *) event_info)->event_flags;
383       case EVAS_CALLBACK_MOUSE_UP:
384          return ((Evas_Event_Mouse_Up *) event_info)->event_flags;
385       case EVAS_CALLBACK_MOUSE_WHEEL:
386          return ((Evas_Event_Mouse_Wheel *) event_info)->event_flags;
387       case EVAS_CALLBACK_MULTI_DOWN:
388          return ((Evas_Event_Multi_Down *) event_info)->event_flags;
389       case EVAS_CALLBACK_MULTI_MOVE:
390          return ((Evas_Event_Multi_Move *) event_info)->event_flags;
391       case EVAS_CALLBACK_MULTI_UP:
392          return ((Evas_Event_Multi_Up *) event_info)->event_flags;
393       case EVAS_CALLBACK_KEY_DOWN:
394          return ((Evas_Event_Key_Down *) event_info)->event_flags;
395       case EVAS_CALLBACK_KEY_UP:
396          return ((Evas_Event_Key_Up *) event_info)->event_flags;
397       default:
398          return EVAS_EVENT_FLAG_NONE;
399      }
400 }
401
402 /**
403  * @internal
404  *
405  * Sets event flag to value returned from user callback
406  * @param wd Widget Data
407  * @param event_info pointer to event.
408  * @param event_type what type was ev (mouse down, etc...)
409  * @param ev_flags event flags
410  *
411  * @ingroup Elm_Gesture_Layer
412  */
413 static void
414 consume_event(Widget_Data *wd, void *event_info,
415       Evas_Callback_Type event_type, Evas_Event_Flags ev_flags)
416 {  /* Mark EVAS_EVENT_FLAG_ON_HOLD on events that are used by gesture layer */
417    /* ev_flags != EVAS_EVENT_FLAG_NONE means target used event and g-layer  */
418    /* should not refeed this event.                                         */
419    if(!event_info)
420      return;  /* This happens when restarting gestures  */
421
422    if ((ev_flags) || (!wd->repeat_events))
423      {
424         switch(event_type)
425           {
426            case EVAS_CALLBACK_MOUSE_DOWN:
427               ((Evas_Event_Mouse_Down *) event_info)->event_flags |= ev_flags;
428               break;
429            case EVAS_CALLBACK_MOUSE_MOVE:
430               ((Evas_Event_Mouse_Move *) event_info)->event_flags |= ev_flags;
431               break;
432            case EVAS_CALLBACK_MOUSE_UP:
433               ((Evas_Event_Mouse_Up *) event_info)->event_flags |= ev_flags;
434               break;
435            case EVAS_CALLBACK_MOUSE_WHEEL:
436               ((Evas_Event_Mouse_Wheel *) event_info)->event_flags |= ev_flags;
437               break;
438            case EVAS_CALLBACK_MULTI_DOWN:
439               ((Evas_Event_Multi_Down *) event_info)->event_flags |= ev_flags;
440               break;
441            case EVAS_CALLBACK_MULTI_MOVE:
442               ((Evas_Event_Multi_Move *) event_info)->event_flags |= ev_flags;
443               break;
444            case EVAS_CALLBACK_MULTI_UP:
445               ((Evas_Event_Multi_Up *) event_info)->event_flags |= ev_flags;
446               break;
447            case EVAS_CALLBACK_KEY_DOWN:
448               ((Evas_Event_Key_Down *) event_info)->event_flags |= ev_flags;
449               break;
450            case EVAS_CALLBACK_KEY_UP:
451               ((Evas_Event_Key_Up *) event_info)->event_flags |= ev_flags;
452               break;
453            default:
454               return;
455           }
456      }
457 }
458
459 /**
460  * @internal
461  *
462  * Report current state of a gesture by calling user callback.
463  * @param gesture what gesture state we report.
464  * @param info inforamtion for user callback
465  *
466  * @ingroup Elm_Gesture_Layer
467  */
468 static Evas_Event_Flags
469 _report_state(Gesture_Info *gesture, void *info)
470 {  /* We report current state (START, MOVE, END, ABORT), once */
471 #if defined(DEBUG_GESTURE_LAYER)
472    printf("%s reporting gesture=<%d> state=<%d>\n" , __func__, gesture->g_type,
473          gesture->state);
474 #endif
475    if ((gesture->state != ELM_GESTURE_STATE_UNDEFINED) &&
476          (gesture->fn[gesture->state].cb))
477      {  /* Fill state-info struct and send ptr to user callback */
478         return gesture->fn[gesture->state].cb(
479               gesture->fn[gesture->state].user_data, info);
480      }
481
482    return EVAS_EVENT_FLAG_NONE;
483 }
484
485 /**
486  * @internal
487  *
488  * Update state for a given gesture.
489  * We may update gesture state to:
490  * UNDEFINED - current input did not start gesure yet.
491  * START - gesture started according to input.
492  * MOVE - gusture in progress.
493  * END - gesture completed according to input.
494  * ABORT - input does not matches gesure.
495  * note that we may move from UNDEFINED to ABORT
496  * because we may detect that gesture will not START
497  * with a given input.
498  *
499  * @param g given gesture to change state.
500  * @param s gesure new state.
501  * @param info buffer to be sent to user callback on report_state.
502  * @param force makes report_state to report the new-state even
503  * if its same as current state. Works for MOVE - gesture in progress.
504  *
505  * @ingroup Elm_Gesture_Layer
506  */
507 static Evas_Event_Flags
508 _set_state(Gesture_Info *g, Elm_Gesture_State s,
509       void *info, Eina_Bool force)
510 {
511    Elm_Gesture_State old_state;
512    if ((g->state == s) && (!force))
513      return EVAS_EVENT_FLAG_NONE;
514
515    old_state = g->state;
516
517    g->state = s;
518    g->info = info;  /* Information for user callback */
519    if ((g->state == ELM_GESTURE_STATE_ABORT) ||
520          (g->state == ELM_GESTURE_STATE_END))
521      g->test = EINA_FALSE;
522
523    if ((g->state != ELM_GESTURE_STATE_UNDEFINED) &&
524          (!((old_state == ELM_GESTURE_STATE_UNDEFINED) &&
525             (s == ELM_GESTURE_STATE_ABORT))))
526      return _report_state(g, g->info);
527
528    return EVAS_EVENT_FLAG_NONE;
529 }
530
531 /**
532  * @internal
533  *
534  * This resets all gesture states and sets test-bit.
535  * this is used for restarting gestures to listen to input.
536  * happens after we complete a gesture or no gesture was detected.
537  * @param wd Widget data of the gesture-layer object.
538  *
539  * @ingroup Elm_Gesture_Layer
540  */
541 static void
542 _reset_states(Widget_Data *wd)
543 {
544    int i;
545    Gesture_Info *p;
546    for (i = ELM_GESTURE_FIRST; i < ELM_GESTURE_LAST; i++)
547      {
548         p = wd->gesture[i];
549         if (p)
550           {
551              _set_state(p, ELM_GESTURE_STATE_UNDEFINED, NULL, EINA_FALSE);
552              SET_TEST_BIT(p);
553           }
554      }
555 }
556
557 /**
558  * @internal
559  *
560  * if gesture was NOT detected AND we only have gestures in ABORT state
561  * we clear history immediately to be ready for input.
562  *
563  * @param obj The gesture-layer object.
564  * @return TRUE on event history_clear
565  *
566  * @ingroup Elm_Gesture_Layer
567  */
568 static Eina_Bool
569 _clear_if_finished(Evas_Object *obj)
570 {
571    Widget_Data *wd = elm_widget_data_get(obj);
572    if (!wd) return EINA_FALSE;
573    int i;
574
575    /* Clear history if all we have aborted gestures */
576    Eina_Bool reset_s = EINA_TRUE, all_undefined = EINA_TRUE;
577    for (i = ELM_GESTURE_FIRST; i < ELM_GESTURE_LAST; i++)
578      {  /* If no gesture started and all we have aborted gestures, reset all */
579         Gesture_Info *p = wd->gesture[i];
580         if ((p) && (p->state != ELM_GESTURE_STATE_UNDEFINED))
581           {
582              if ((p->state == ELM_GESTURE_STATE_START) ||
583                    (p->state == ELM_GESTURE_STATE_MOVE))
584                reset_s = EINA_FALSE;
585
586              all_undefined = EINA_FALSE;
587           }
588      }
589
590    if (reset_s && (!all_undefined))
591      return _event_history_clear(obj);
592
593    return EINA_FALSE;
594 }
595
596 static Eina_Bool
597 <<<<<<< HEAD
598 _inside(Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2)
599 {
600    int w = elm_finger_size_get() >> 1; /* Finger size devided by 2 */
601    if (x1 < (x2 - w))
602      return EINA_FALSE;
603
604    if (x1 > (x2 + w))
605      return EINA_FALSE;
606
607    if (y1 < (y2 - w))
608      return EINA_FALSE;
609
610    if (y1 > (y2 + w))
611 =======
612 _inside(Evas_Coord xx1, Evas_Coord yy1, Evas_Coord xx2, Evas_Coord yy2)
613 {
614    int w = _elm_config->finger_size >> 1; /* Finger size devided by 2 */
615    if (xx1 < (xx2 - w))
616      return EINA_FALSE;
617
618    if (xx1 > (xx2 + w))
619      return EINA_FALSE;
620
621    if (yy1 < (yy2 - w))
622      return EINA_FALSE;
623
624    if (yy1 > (yy2 + w))
625 >>>>>>> remotes/origin/upstream
626      return EINA_FALSE;
627
628    return EINA_TRUE;
629 }
630
631 /* All *test_reset() funcs are called to clear
632  * gesture intermediate data.
633  * This happens when we need to reset our tests.
634  * for example when gesture is detected or all ABORTed. */
635 static void
636 _tap_gestures_test_reset(Gesture_Info *gesture)
637 {
638    if (!gesture)
639      return;
640
641    Widget_Data *wd = elm_widget_data_get(gesture->obj);
642    wd->dbl_timeout = NULL;
643    Eina_List *data;
644    Pointer_Event *pe;
645
646    if (!gesture->data)
647      return;
648
649    EINA_LIST_FREE(((Taps_Type *) gesture->data)->l, data)
650       EINA_LIST_FREE(data, pe)
651          free(pe);
652
653   memset(gesture->data, 0, sizeof(Taps_Type));
654 }
655
656 /* All *test_reset() funcs are called to clear
657  * gesture intermediate data.
658  * This happens when we need to reset our tests.
659  * for example when gesture is detected or all ABORTed. */
660 static void
661 _n_long_tap_test_reset(Gesture_Info *gesture)
662 {
663    if (!gesture)
664      return;
665
666    if (!gesture->data)
667      return;
668
669    Long_Tap_Type *st = gesture->data;
670    Eina_List *l;
671    Pointer_Event *p;
672    EINA_LIST_FOREACH(st->touched, l, p)
673 <<<<<<< HEAD
674       free(p);
675
676    eina_list_free(st->touched);
677    if (st->timeout) ecore_timer_del(st->timeout);
678 =======
679      free(p);
680
681    eina_list_free(st->touched);
682    if (st->timeout)
683      {
684         ecore_timer_del(st->timeout);
685         st->timeout = NULL;
686      }
687 >>>>>>> remotes/origin/upstream
688    memset(gesture->data, 0, sizeof(Long_Tap_Type));
689 }
690
691 static void
692 _momentum_test_reset(Gesture_Info *gesture)
693 {
694    if (!gesture)
695      return;
696
697    if (!gesture->data)
698      return;
699
700    memset(gesture->data, 0, sizeof(Momentum_Type));
701 }
702
703 static void
704 _line_data_reset(Line_Data *st)
705 {
706    if (!st)
707      return;
708
709    memset(st, 0, sizeof(Line_Data));
710    st->line_angle = ELM_GESTURE_NEGATIVE_ANGLE;
711 }
712
713 static void
714 _line_test_reset(Gesture_Info *gesture)
715 {
716    if (!gesture)
717      return;
718
719    if (!gesture->data)
720      return;
721
722    Line_Type *st = gesture->data;
723    Eina_List *list = st->list;
724    Eina_List *l;
725    Line_Data *t_line;
726    EINA_LIST_FOREACH(list, l, t_line)
727       free(t_line);
728
729    eina_list_free(list);
730    st->list = NULL;
731 }
732
733 static void
734 _zoom_test_reset(Gesture_Info *gesture)
735 {
736    if (!gesture)
737      return;
738
739    if (!gesture->data)
740      return;
741
742    Widget_Data *wd = elm_widget_data_get(gesture->obj);
743    Zoom_Type *st = gesture->data;
744    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(
745          evas_object_evas_get(wd->target), "Control");
746    evas_object_key_ungrab(wd->target, "Control_L", mask, 0);
747    evas_object_key_ungrab(wd->target, "Control_R", mask, 0);
748
749    memset(st, 0, sizeof(Zoom_Type));
750    st->zoom_distance_tolerance = wd->zoom_distance_tolerance;
751    st->info.zoom = 1.0;
752 }
753
754 static void
755 _rotate_test_reset(Gesture_Info *gesture)
756 {
757    if (!gesture)
758      return;
759
760    if (!gesture->data)
761      return;
762
763    Widget_Data *wd = elm_widget_data_get(gesture->obj);
764    Rotate_Type *st = gesture->data;
765
766    memset(st, 0, sizeof(Rotate_Type));
767    st->info.base_angle = ELM_GESTURE_NEGATIVE_ANGLE;
768    st->rotate_angular_tolerance = wd->rotate_angular_tolerance;
769 }
770
771
772 /**
773  * @internal
774  *
775  * We register callbacks when gesture layer is attached to an object
776  * or when its enabled after disable.
777  *
778  * @param obj The gesture-layer object.
779  *
780  * @ingroup Elm_Gesture_Layer
781  */
782 static void
783 _register_callbacks(Evas_Object *obj)
784 {
785    Widget_Data *wd = elm_widget_data_get(obj);
786    if (!wd) return;
787
788    if (wd->target)
789      {
790         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOUSE_DOWN,
791               _mouse_down, obj);
792         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOUSE_MOVE,
793               _mouse_move, obj);
794         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOUSE_UP,
795               _mouse_up, obj);
796
797         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOUSE_WHEEL,
798               _mouse_wheel, obj);
799
800         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MULTI_DOWN,
801               _multi_down, obj);
802         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MULTI_MOVE,
803               _multi_move, obj);
804         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MULTI_UP,
805               _multi_up, obj);
806
807         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_KEY_DOWN,
808               _key_down_cb, obj);
809         evas_object_event_callback_add(wd->target, EVAS_CALLBACK_KEY_UP,
810               _key_up_cb, obj);
811      }
812 }
813
814 /**
815  * @internal
816  *
817  * We unregister callbacks when gesture layer is disabled.
818  *
819  * @param obj The gesture-layer object.
820  *
821  * @ingroup Elm_Gesture_Layer
822  */
823 static void
824 _unregister_callbacks(Evas_Object *obj)
825 {
826    Widget_Data *wd = elm_widget_data_get(obj);
827    if (!wd) return;
828
829    if (wd->target)
830      {
831         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MOUSE_DOWN,
832               _mouse_down);
833         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MOUSE_MOVE,
834               _mouse_move);
835         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MOUSE_UP,
836               _mouse_up);
837
838         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MOUSE_WHEEL,
839               _mouse_wheel);
840
841         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MULTI_DOWN,
842               _multi_down);
843
844         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MULTI_MOVE,
845               _multi_move);
846
847         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_MULTI_UP,
848               _multi_up);
849
850         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_KEY_DOWN,
851               _key_down_cb);
852         evas_object_event_callback_del(wd->target, EVAS_CALLBACK_KEY_UP,
853               _key_up_cb);
854      }
855 }
856
857 /* START - Event history list handling functions */
858 /**
859  * @internal
860  * This function is used to find if device number
861  * is found in a list of devices.
862  * The list contains devices for refeeding *UP event
863  *
864  * @ingroup Elm_Gesture_Layer
865  */
866 static int
867 device_in_pending_list(const void *data1, const void *data2)
868 {  /* Compare the two device numbers */
869    return (((intptr_t) data1) - ((intptr_t) data2));
870 }
871
872 /**
873  * @internal
874  *
875  * This functions adds device to refeed-pending device list
876  * @ingroup Elm_Gesture_Layer
877  */
878 static Eina_List *
879 _add_device_pending(Eina_List *list, void *event, Evas_Callback_Type event_type)
880 {
881    int device = ELM_MOUSE_DEVICE;
882    switch(event_type)
883      {
884       case EVAS_CALLBACK_MOUSE_DOWN:
885          break;
886       case EVAS_CALLBACK_MULTI_DOWN:
887          device = ((Evas_Event_Multi_Down *) event)->device;
888          break;
889       default:
890          return list;
891      }
892
893    if (!eina_list_search_unsorted_list(list, device_in_pending_list,
894 <<<<<<< HEAD
895             (intptr_t*) device))
896      {
897         return eina_list_append(list, (intptr_t*) device);
898 =======
899                                        (void *)(intptr_t)device))
900      {
901         return eina_list_append(list, (void *)(intptr_t)device);
902 >>>>>>> remotes/origin/upstream
903      }
904
905    return list;
906 }
907
908 /**
909  * @internal
910  *
911  * This functions returns pending-device node
912  * @ingroup Elm_Gesture_Layer
913  */
914 static Eina_List *
915 _device_is_pending(Eina_List *list, void *event, Evas_Callback_Type event_type)
916 {
917    int device = ELM_MOUSE_DEVICE;
918    switch(event_type)
919      {
920       case EVAS_CALLBACK_MOUSE_UP:
921          break;
922       case EVAS_CALLBACK_MULTI_UP:
923          device = ((Evas_Event_Multi_Up *) event)->device;
924          break;
925       default:
926         return NULL;
927      }
928
929    return eina_list_search_unsorted_list(list, device_in_pending_list,
930 <<<<<<< HEAD
931          (intptr_t *) device);
932 =======
933                                          (void *)(intptr_t)device);
934 >>>>>>> remotes/origin/upstream
935 }
936
937 /**
938  * @internal
939  *
940  * This function reports ABORT to all none-detected gestures
941  * Then resets test bits for all desired gesures
942  * and clears input-events history.
943  * note: if no gesture was detected, events from history list
944  * are streamed to the widget because it's unused by layer.
945  * user may cancel refeed of events by setting repeat events.
946  *
947  * @param obj The gesture-layer object.
948  *
949  * @ingroup Elm_Gesture_Layer
950  */
951 static Eina_Bool
952 _event_history_clear(Evas_Object *obj)
953 {
954    Widget_Data *wd = elm_widget_data_get(obj);
955    if (!wd) return EINA_FALSE;
956
957    int i;
958    Gesture_Info *p;
959    Evas *e = evas_object_evas_get(obj);
960    Eina_Bool gesture_found = EINA_FALSE;
961 <<<<<<< HEAD
962    for (i = ELM_GESTURE_FIRST ; i < ELM_GESTURE_LAST; i++)
963 =======
964    for (i = ELM_GESTURE_FIRST; i < ELM_GESTURE_LAST; i++)
965 >>>>>>> remotes/origin/upstream
966      {
967         p = wd->gesture[i];
968         if (p)
969           {
970              if (p->state == ELM_GESTURE_STATE_END)
971                gesture_found = EINA_TRUE;
972              else
973                {  /* Report ABORT to all gestures that still not finished */
974                   _set_state(p, ELM_GESTURE_STATE_ABORT, wd->gesture[i]->info,
975                         EINA_FALSE);
976                }
977           }
978      }
979
980    _reset_states(wd); /* we are ready to start testing for gestures again */
981
982    /* Clear all gestures intermediate data */
983    if (IS_TESTED(ELM_GESTURE_N_LONG_TAPS))
984      {  /* We do not clear a long-tap gesture if fingers still on surface */
985         /* and gesture timer still pending to test gesture state          */
986         Long_Tap_Type *st = wd->gesture[ELM_GESTURE_N_LONG_TAPS]->data;
987         if ((st) &&  /* st not allocated if clear occurs before 1st input */
988               ((!eina_list_count(st->touched)) || (!st->timeout)))
989           _n_long_tap_test_reset(wd->gesture[ELM_GESTURE_N_LONG_TAPS]);
990      }
991
992    if (wd->dbl_timeout)
993      {
994         ecore_timer_del(wd->dbl_timeout);
995         wd->dbl_timeout = NULL;
996      }
997
998    _tap_gestures_test_reset(wd->gesture[ELM_GESTURE_N_TAPS]);
999    _tap_gestures_test_reset(wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS]);
1000    _tap_gestures_test_reset(wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS]);
1001    _momentum_test_reset(wd->gesture[ELM_GESTURE_MOMENTUM]);
1002    _line_test_reset(wd->gesture[ELM_GESTURE_N_LINES]);
1003    _line_test_reset(wd->gesture[ELM_GESTURE_N_FLICKS]);
1004    _zoom_test_reset(wd->gesture[ELM_GESTURE_ZOOM]);
1005    _rotate_test_reset(wd->gesture[ELM_GESTURE_ROTATE]);
1006
1007    /* Disable gesture layer so refeeded events won't be consumed by it */
1008    _unregister_callbacks(obj);
1009    while (wd->event_history_list)
1010      {
1011         Event_History *t;
1012         t = wd->event_history_list;
1013         Eina_List *pending = _device_is_pending(wd->pending,
1014               wd->event_history_list->event,
1015               wd->event_history_list->event_type);
1016
1017         /* Refeed events if no gesture matched input */
1018         if (pending || ((!gesture_found) && (!wd->repeat_events)))
1019           {
1020              evas_event_refeed_event(e, wd->event_history_list->event,
1021                    wd->event_history_list->event_type);
1022
1023              if (pending)
1024                {
1025                   wd->pending = eina_list_remove_list(wd->pending, pending);
1026                }
1027              else
1028                {
1029                   wd->pending = _add_device_pending(wd->pending,
1030                         wd->event_history_list->event,
1031                         wd->event_history_list->event_type);
1032                }
1033           }
1034
1035         free(wd->event_history_list->event);
1036         wd->event_history_list = (Event_History *) eina_inlist_remove(
1037               EINA_INLIST_GET(wd->event_history_list),
1038               EINA_INLIST_GET(wd->event_history_list));
1039         free(t);
1040      }
1041    _register_callbacks(obj);
1042    return EINA_TRUE;
1043 }
1044
1045 /**
1046  * @internal
1047  *
1048  * This function copies input events.
1049  * We copy event info before adding it to history.
1050  * The memory is freed when we clear history.
1051  *
1052  * @param event the event to copy
1053  * @param event_type event type to copy
1054  *
1055  * @ingroup Elm_Gesture_Layer
1056  */
1057 static void *
1058 _copy_event_info(void *event, Evas_Callback_Type event_type)
1059 {
1060    switch(event_type)
1061      {
1062       case EVAS_CALLBACK_MOUSE_DOWN:
1063          return COPY_EVENT_INFO((Evas_Event_Mouse_Down *) event);
1064          break;
1065       case EVAS_CALLBACK_MOUSE_MOVE:
1066          return COPY_EVENT_INFO((Evas_Event_Mouse_Move *) event);
1067          break;
1068       case EVAS_CALLBACK_MOUSE_UP:
1069          return COPY_EVENT_INFO((Evas_Event_Mouse_Up *) event);
1070          break;
1071       case EVAS_CALLBACK_MOUSE_WHEEL:
1072          return COPY_EVENT_INFO((Evas_Event_Mouse_Wheel *) event);
1073          break;
1074       case EVAS_CALLBACK_MULTI_DOWN:
1075          return COPY_EVENT_INFO((Evas_Event_Multi_Down *) event);
1076          break;
1077       case EVAS_CALLBACK_MULTI_MOVE:
1078          return COPY_EVENT_INFO((Evas_Event_Multi_Move *) event);
1079          break;
1080       case EVAS_CALLBACK_MULTI_UP:
1081          return COPY_EVENT_INFO((Evas_Event_Multi_Up *) event);
1082          break;
1083       case EVAS_CALLBACK_KEY_DOWN:
1084          return COPY_EVENT_INFO((Evas_Event_Key_Down *) event);
1085          break;
1086       case EVAS_CALLBACK_KEY_UP:
1087          return COPY_EVENT_INFO((Evas_Event_Key_Up *) event);
1088          break;
1089       default:
1090          return NULL;
1091      }
1092 }
1093
1094 static Eina_Bool
1095 _event_history_add(Evas_Object *obj, void *event, Evas_Callback_Type event_type)
1096 {
1097    Widget_Data *wd = elm_widget_data_get(obj);
1098    Event_History *ev;
1099    if (!wd) return EINA_FALSE;
1100
1101    ev = malloc(sizeof(Event_History));
1102    ev->event = _copy_event_info(event, event_type);  /* Freed on event_history_clear */
1103    ev->event_type = event_type;
1104    wd->event_history_list = (Event_History *) eina_inlist_append(
1105          EINA_INLIST_GET(wd->event_history_list), EINA_INLIST_GET(ev));
1106
1107    return EINA_TRUE;
1108 }
1109 /* END - Event history list handling functions */
1110
1111 static void
1112 _del_hook(Evas_Object *obj)
1113 {
1114    Widget_Data *wd = elm_widget_data_get(obj);
1115    if (!wd) return;
1116
1117    _event_history_clear(obj);
1118    eina_list_free(wd->pending);
1119
1120    Pointer_Event *data;
1121    EINA_LIST_FREE(wd->touched, data)
1122 <<<<<<< HEAD
1123       free(data);
1124 =======
1125      free(data);
1126 >>>>>>> remotes/origin/upstream
1127
1128    if (!elm_widget_disabled_get(obj))
1129      _unregister_callbacks(obj);
1130
1131    /* Free all gestures internal data structures */
1132    int i;
1133    for (i = 0; i < ELM_GESTURE_LAST; i++)
1134      if (wd->gesture[i])
1135        {
1136           if (wd->gesture[i]->data)
1137             free(wd->gesture[i]->data);
1138
1139           free(wd->gesture[i]);
1140        }
1141
1142    free(wd);
1143 }
1144
1145 static int
1146 compare_match_fingers(const void *data1, const void *data2)
1147 {  /* Compare coords of first item in list to cur coords */
1148    const Pointer_Event *pe1 = eina_list_data_get(data1);
1149    const Pointer_Event *pe2 = data2;
1150
1151    if (_inside(pe1->x, pe1->y, pe2->x, pe2->y))
1152      return 0;
1153    else if (pe1->x < pe2->x)
1154      return -1;
1155    else
1156      {
1157         if (pe1->x == pe2->x)
1158           return pe1->y - pe2->y;
1159         else
1160           return 1;
1161      }
1162 }
1163
1164 static int
1165 compare_pe_device(const void *data1, const void *data2)
1166 {  /* Compare device of first item in list to our pe device */
1167    const Pointer_Event *pe1 = eina_list_data_get(data1);
1168    const Pointer_Event *pe2 = data2;
1169
1170    /* Only match if last was a down event */
1171    if ((pe1->event_type != EVAS_CALLBACK_MULTI_DOWN) &&
1172          (pe1->event_type != EVAS_CALLBACK_MOUSE_DOWN))
1173      return 1;
1174
1175 <<<<<<< HEAD
1176
1177 =======
1178 >>>>>>> remotes/origin/upstream
1179    if (pe1->device == pe2->device)
1180      return 0;
1181    else if (pe1->device < pe2->device)
1182      return -1;
1183    else
1184      return 1;
1185 }
1186
1187 static Eina_List*
1188 _record_pointer_event(Taps_Type *st, Eina_List *pe_list, Pointer_Event *pe,
1189       Widget_Data *wd, void *event_info, Evas_Callback_Type event_type)
1190 {  /* Keep copy of pe and record it in list */
1191    Pointer_Event *p = malloc(sizeof(Pointer_Event));
1192    memcpy(p, pe, sizeof(Pointer_Event));
1193    consume_event(wd, event_info, event_type, EVAS_EVENT_FLAG_NONE);
1194
1195    st->sum_x += pe->x;
1196    st->sum_y += pe->y;
1197    st->n_taps++;
1198
1199    /* This will also update middle-point to report to user later */
1200    st->info.x = st->sum_x / st->n_taps;
1201    st->info.y = st->sum_y / st->n_taps;
1202    st->info.timestamp = pe->timestamp;
1203
1204    if (!pe_list)
1205      {
1206         pe_list = eina_list_append(pe_list, p);
1207         st->l = eina_list_append(st->l, pe_list);
1208      }
1209    else
1210      pe_list = eina_list_append(pe_list, p);
1211
1212    return pe_list;
1213 }
1214
1215 /**
1216  * @internal
1217  *
1218  * This function sets state a tap-gesture to END or ABORT
1219  *
1220  * @param data gesture info pointer
1221  *
1222  * @ingroup Elm_Gesture_Layer
1223  */
1224 static void
1225 _tap_gesture_finish(void *data)
1226 {  /* This function will test each tap gesture when timer expires */
1227    Gesture_Info *gesture = data;
1228    Elm_Gesture_State s = ELM_GESTURE_STATE_END;
1229    /* Here we check if taps-gesture was completed successfuly */
1230    /* Count how many taps were recieved on each device then   */
1231    /* determine if it matches n_taps_needed defined on START  */
1232    Taps_Type *st = gesture->data;
1233    Eina_List *l;
1234    Eina_List *pe_list;
1235    EINA_LIST_FOREACH(st->l, l, pe_list)
1236      {
1237         if (eina_list_count(pe_list) != st->n_taps_needed)
1238           {  /* No match taps number on device, ABORT */
1239              s = ELM_GESTURE_STATE_ABORT;
1240              break;
1241           }
1242      }
1243
1244    st->info.n = eina_list_count(st->l);
1245    _set_state(gesture, s, gesture->info, EINA_FALSE);
1246    _tap_gestures_test_reset(gesture);
1247 }
1248
1249 /**
1250  * @internal
1251  *
1252  * when this timer expires we finish tap gestures.
1253  *
1254  * @param data The gesture-layer object.
1255  * @return cancles callback for this timer.
1256  *
1257  * @ingroup Elm_Gesture_Layer
1258  */
1259 static Eina_Bool
1260 _multi_tap_timeout(void *data)
1261 {
1262    Widget_Data *wd = elm_widget_data_get(data);
1263    if (!wd) return EINA_FALSE;
1264
1265    if (IS_TESTED(ELM_GESTURE_N_TAPS))
1266      _tap_gesture_finish(wd->gesture[ELM_GESTURE_N_TAPS]);
1267
1268    if (IS_TESTED(ELM_GESTURE_N_DOUBLE_TAPS))
1269    _tap_gesture_finish(wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS]);
1270
1271    if (IS_TESTED(ELM_GESTURE_N_TRIPLE_TAPS))
1272    _tap_gesture_finish(wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS]);
1273
1274    _clear_if_finished(data);
1275    wd->dbl_timeout = NULL;
1276    return ECORE_CALLBACK_CANCEL;
1277 }
1278
1279 /**
1280  * @internal
1281  *
1282  * when this timer expires we START long tap gesture
1283  *
1284  * @param data The gesture-layer object.
1285  * @return cancles callback for this timer.
1286  *
1287  * @ingroup Elm_Gesture_Layer
1288  */
1289 static Eina_Bool
1290 _long_tap_timeout(void *data)
1291 {
1292    Gesture_Info *gesture = data;
1293    Long_Tap_Type *st = gesture->data;
1294    st->timeout = NULL;
1295
1296    _set_state(gesture, ELM_GESTURE_STATE_START,
1297          gesture->data, EINA_FALSE);
1298
1299    return ECORE_CALLBACK_CANCEL;
1300 }
1301
1302
1303 /**
1304  * @internal
1305  *
1306  * This function checks if a tap gesture should start
1307  *
1308  * @param wd Gesture Layer Widget Data.
1309  * @param pe The recent input event as stored in pe struct.
1310  * @param event_info Original input event pointer.
1311  * @param event_type Type of original input event.
1312  * @param gesture what gesture is tested
1313  * @param how many taps for this gesture (1, 2 or 3)
1314  *
1315  * @return Flag to determine if we need to set a timer for finish
1316  *
1317  * @ingroup Elm_Gesture_Layer
1318  */
1319 static Eina_Bool
1320 _tap_gesture_start(Widget_Data *wd, Pointer_Event *pe,
1321       void *event_info, Evas_Callback_Type event_type,
1322       Gesture_Info *gesture, int taps)
1323 {  /* Here we fill Tap struct */
1324    Taps_Type *st = gesture->data;
1325    if (!st)
1326      {  /* Allocated once on first time */
1327         st = calloc(1, sizeof(Taps_Type));
1328         gesture->data = st;
1329         _tap_gestures_test_reset(gesture);
1330      }
1331
1332    Eina_List *pe_list = NULL;
1333    Pointer_Event *pe_down = NULL;
1334    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
1335    switch (pe->event_type)
1336      {
1337       case EVAS_CALLBACK_MULTI_DOWN:
1338       case EVAS_CALLBACK_MOUSE_DOWN:
1339          /* Check if got tap on same cord was tapped before */
1340          pe_list = eina_list_search_unsorted(st->l, compare_match_fingers, pe);
1341
1342          if ((!pe_list) &&
1343                eina_list_search_unsorted(st->l, compare_pe_device, pe))
1344            {  /* This device was touched in other cord before completion */
1345               ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
1346                     &st->info, EINA_FALSE);
1347               consume_event(wd, event_info, event_type, ev_flag);
1348
1349               return EINA_FALSE;
1350            }
1351
1352          pe_list = _record_pointer_event(st, pe_list, pe, wd, event_info, event_type);
1353          if ((pe->device == 0) && (eina_list_count(pe_list) == 1))
1354            {  /* This is the first mouse down we got */
1355               ev_flag = _set_state(gesture, ELM_GESTURE_STATE_START,
1356                     &st->info, EINA_FALSE);
1357               consume_event(wd, event_info, event_type, ev_flag);
1358
1359               st->n_taps_needed = taps * 2; /* count DOWN and UP */
1360
1361               return EINA_TRUE;
1362            }
1363
1364          break;
1365
1366       case EVAS_CALLBACK_MULTI_UP:
1367       case EVAS_CALLBACK_MOUSE_UP:
1368          pe_list = eina_list_search_unsorted(st->l, compare_pe_device, pe);
1369          if (!pe_list)
1370            return EINA_FALSE;
1371
1372          pe_list = _record_pointer_event(st, pe_list, pe, wd, event_info, event_type);
1373          break;
1374
1375       case EVAS_CALLBACK_MULTI_MOVE:
1376       case EVAS_CALLBACK_MOUSE_MOVE:
1377          /* Get first event in first list, this has to be a Mouse Down event  */
1378          /* and verify that user didn't move out of this area before next tap */
1379          pe_list = eina_list_search_unsorted(st->l, compare_pe_device, pe);
1380          if (pe_list)
1381            {
1382               pe_down = eina_list_data_get(pe_list);
1383               if (!_inside(pe_down->x, pe_down->y, pe->x, pe->y))
1384                 {
1385                    ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
1386                          &st->info, EINA_FALSE);
1387                    consume_event(wd, event_info, event_type, ev_flag);
1388                 }
1389            }
1390          break;
1391
1392       default:
1393          return EINA_FALSE;
1394      }
1395
1396    return EINA_FALSE;
1397 }
1398
1399
1400 /**
1401  * @internal
1402  *
1403  * This function checks all click/tap and double/triple taps
1404  *
1405  * @param obj The gesture-layer object.
1406  * @param pe The recent input event as stored in pe struct.
1407  * @param event_info Original input event pointer.
1408  * @param event_type Type of original input event.
1409  *
1410  * @ingroup Elm_Gesture_Layer
1411  */
1412 static void
1413 _tap_gestures_test(Evas_Object *obj, Pointer_Event *pe,
1414       void *event_info, Evas_Callback_Type event_type)
1415 {  /* Here we fill Recent_Taps struct and fire-up click/tap timers */
1416    Eina_Bool need_timer = EINA_FALSE;
1417    Widget_Data *wd = elm_widget_data_get(obj);
1418    if (!wd) return;
1419
1420    if (!pe)   /* this happens when unhandled event arrived */
1421      return;  /* see _make_pointer_event function */
1422
1423    if (IS_TESTED(ELM_GESTURE_N_TAPS))
1424      need_timer |= _tap_gesture_start(wd, pe, event_info, event_type,
1425            wd->gesture[ELM_GESTURE_N_TAPS], 1);
1426
1427    if (IS_TESTED(ELM_GESTURE_N_DOUBLE_TAPS))
1428      need_timer |= _tap_gesture_start(wd, pe, event_info, event_type,
1429            wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS], 2);
1430
1431    if (IS_TESTED(ELM_GESTURE_N_TRIPLE_TAPS))
1432      need_timer |= _tap_gesture_start(wd, pe, event_info, event_type,
1433            wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS], 3);
1434
1435    if ((need_timer) && (!wd->dbl_timeout))
1436      {  /* Set a timer to finish these gestures */
1437         wd->dbl_timeout = ecore_timer_add(0.4, _multi_tap_timeout,
1438               obj);
1439      }
1440 }
1441
1442 /**
1443  * @internal
1444  *
1445  * This function computes center-point for  long-tap gesture
1446  *
1447  * @param st Long Tap gesture info pointer
1448  * @param pe The recent input event as stored in pe struct.
1449  *
1450  * @ingroup Elm_Gesture_Layer
1451  */
1452 static void
1453 _compute_taps_center(Long_Tap_Type *st,
1454       Evas_Coord *x_out, Evas_Coord *y_out, Pointer_Event *pe)
1455 {
1456    if(!eina_list_count(st->touched))
1457      return;
1458
1459    Eina_List *l;
1460    Pointer_Event *p;
1461    Evas_Coord x = 0, y = 0;
1462    EINA_LIST_FOREACH(st->touched, l, p)
1463      {  /* Accumulate all then take avarage */
1464         if (p->device == pe->device)
1465           {  /* This will take care of values coming from MOVE event */
1466              x += pe->x;
1467              y += pe->y;
1468           }
1469         else
1470           {
1471              x += p->x;
1472              y += p->y;
1473           }
1474      }
1475
1476    *x_out = x / eina_list_count(st->touched);
1477    *y_out = y / eina_list_count(st->touched);
1478 }
1479
1480 /**
1481  * @internal
1482  *
1483  * This function checks N long-tap gesture.
1484  *
1485  * @param obj The gesture-layer object.
1486  * @param pe The recent input event as stored in pe struct.
1487  * @param event_info Original input event pointer.
1488  * @param event_type Type of original input event.
1489  * @param g_type what Gesture we are testing.
1490  * @param taps How many click/taps we test for.
1491  *
1492  * @ingroup Elm_Gesture_Layer
1493  */
1494 static void
1495 _n_long_tap_test(Evas_Object *obj, Pointer_Event *pe,
1496                  void *event_info, Evas_Callback_Type event_type,
1497 <<<<<<< HEAD
1498                  Elm_Gesture_Types g_type)
1499 =======
1500                  Elm_Gesture_Type g_type)
1501 >>>>>>> remotes/origin/upstream
1502 {  /* Here we fill Recent_Taps struct and fire-up click/tap timers */
1503    Widget_Data *wd = elm_widget_data_get(obj);
1504    if (!wd) return;
1505
1506    if (!pe)   /* this happens when unhandled event arrived */
1507      return;  /* see _make_pointer_event function */
1508    Gesture_Info *gesture = wd->gesture[g_type];
1509    if (!gesture) return;
1510
1511    Long_Tap_Type *st = gesture->data;
1512    if (!st)
1513      {  /* Allocated once on first time */
1514         st = calloc(1, sizeof(Long_Tap_Type));
1515         gesture->data = st;
1516         _n_long_tap_test_reset(gesture);
1517      }
1518
1519    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
1520    switch (pe->event_type)
1521      {
1522       case EVAS_CALLBACK_MULTI_DOWN:
1523       case EVAS_CALLBACK_MOUSE_DOWN:
1524         st->touched = _add_touched_device(st->touched, pe);
1525         st->info.n = eina_list_count(st->touched);
1526         if (st->info.n > st->max_touched)
1527           st->max_touched = st->info.n;
1528         else
1529           {  /* User removed finger from touch, then put back - ABORT */
1530              if ((gesture->state == ELM_GESTURE_STATE_START) ||
1531                  (gesture->state == ELM_GESTURE_STATE_MOVE))
1532                {
1533                   ev_flag =_set_state(gesture, ELM_GESTURE_STATE_ABORT,
1534                                       &st->info, EINA_FALSE);
1535                   consume_event(wd, event_info, event_type, ev_flag);
1536                }
1537           }
1538
1539         if ((pe->device == 0) && (eina_list_count(st->touched) == 1))
1540           {  /* This is the first mouse down we got */
1541              st->info.timestamp = pe->timestamp;
1542
1543              /* To test long tap */
1544              /* When this timer expires, gesture STARTED */
1545              if (!st->timeout)
1546                st->timeout = ecore_timer_add(wd->long_tap_start_timeout,
1547                                              _long_tap_timeout, gesture);
1548           }
1549
1550         consume_event(wd, event_info, event_type, ev_flag);
1551         _compute_taps_center(st, &st->info.x, &st->info.y, pe);
1552         st->center_x = st->info.x;
1553         st->center_y = st->info.y;
1554         break;
1555
1556       case EVAS_CALLBACK_MULTI_UP:
1557       case EVAS_CALLBACK_MOUSE_UP:
1558         st->touched = _remove_touched_device(st->touched, pe);
1559         _compute_taps_center(st, &st->center_x, &st->center_y, pe);
1560         if (st->info.n &&
1561             ((gesture->state == ELM_GESTURE_STATE_START) ||
1562                 (gesture->state == ELM_GESTURE_STATE_MOVE)))
1563           {  /* Report END only for gesture that STARTed */
1564              if (eina_list_count(st->touched) == 0)
1565                {  /* Report END only at last release event */
1566                   ev_flag =_set_state(gesture, ELM_GESTURE_STATE_END,
1567                                       &st->info, EINA_FALSE);
1568                   consume_event(wd, event_info, event_type, ev_flag);
1569                }
1570           }
1571         else
1572           {  /* Stop test, user lifts finger before long-start */
1573              if (st->timeout) ecore_timer_del(st->timeout);
1574              st->timeout = NULL;
1575              ev_flag =_set_state(gesture, ELM_GESTURE_STATE_ABORT,
1576                                  &st->info, EINA_FALSE);
1577              consume_event(wd, event_info, event_type, ev_flag);
1578           }
1579
1580         break;
1581
1582       case EVAS_CALLBACK_MULTI_MOVE:
1583       case EVAS_CALLBACK_MOUSE_MOVE:
1584         if(st->info.n &&
1585            ((gesture->state == ELM_GESTURE_STATE_START) ||
1586                (gesture->state == ELM_GESTURE_STATE_MOVE)))
1587           {  /* Report MOVE only if STARTED */
1588              Evas_Coord x = 0;
1589              Evas_Coord y = 0;
1590              Elm_Gesture_State state_to_report = ELM_GESTURE_STATE_MOVE;
1591
1592              _compute_taps_center(st, &x, &y, pe);
1593              /* ABORT if user moved fingers out of tap area */
1594 #if defined(DEBUG_GESTURE_LAYER)
1595              printf("%s x,y=(%d,%d) st->info.x,st->info.y=(%d,%d)\n",__func__,x,y,st->info.x,st->info.y);
1596 #endif
1597              if (!_inside(x, y, st->center_x, st->center_y))
1598                state_to_report = ELM_GESTURE_STATE_ABORT;
1599
1600              /* Report MOVE if gesture started */
1601              ev_flag = _set_state(gesture, state_to_report,
1602                                   &st->info, EINA_TRUE);
1603              consume_event(wd, event_info, event_type, ev_flag);
1604           }
1605         break;
1606
1607       default:
1608         return;
1609      }
1610 }
1611
1612 /**
1613  * @internal
1614  *
1615  * This function computes momentum for MOMENTUM, LINE and FLICK gestures
1616  * This momentum value will be sent to widget when gesture is completed.
1617  *
1618  * @param momentum pointer to buffer where we record momentum value.
1619  * @param x1 x coord where user started gesture.
1620  * @param y1 y coord where user started gesture.
1621  * @param x2 x coord where user completed gesture.
1622  * @param y2 y coord where user completed gesture.
1623  * @param t1x timestamp for X, when user started gesture.
1624  * @param t1y timestamp for Y, when user started gesture.
1625  * @param t2  timestamp when user completed gesture.
1626  *
1627  * @ingroup Elm_Gesture_Layer
1628  */
1629 static void
1630 <<<<<<< HEAD
1631 _set_momentum(Elm_Gesture_Momentum_Info *momentum, Evas_Coord x1, Evas_Coord y1,
1632       Evas_Coord x2, Evas_Coord y2, unsigned int t1x, unsigned int t1y,
1633       unsigned int t2)
1634 {
1635    Evas_Coord velx = 0, vely = 0, vel;
1636    Evas_Coord dx = x2 - x1;
1637    Evas_Coord dy = y2 - y1;
1638 =======
1639 _set_momentum(Elm_Gesture_Momentum_Info *momentum, 
1640               Evas_Coord xx1, Evas_Coord yy1,
1641               Evas_Coord xx2, Evas_Coord yy2, 
1642               unsigned int t1x, unsigned int t1y, unsigned int t2)
1643 {
1644    Evas_Coord velx = 0, vely = 0, vel;
1645    Evas_Coord dx = xx2 - xx1;
1646    Evas_Coord dy = yy2 - yy1;
1647 >>>>>>> remotes/origin/upstream
1648    int dtx = t2 - t1x;
1649    int dty = t2 - t1y;
1650    if (dtx > 0)
1651      velx = (dx * 1000) / dtx;
1652
1653    if (dty > 0)
1654      vely = (dy * 1000) / dty;
1655
1656    vel = sqrt((velx * velx) + (vely * vely));
1657
1658    if ((_elm_config->thumbscroll_friction > 0.0) &&
1659          (vel > _elm_config->thumbscroll_momentum_threshold))
1660      {  /* report momentum */
1661         momentum->mx = velx;
1662         momentum->my = vely;
1663      }
1664    else
1665      {
1666         momentum->mx = 0;
1667         momentum->my = 0;
1668      }
1669 }
1670
1671 /**
1672  * @internal
1673  *
1674  * This function is used for computing rotation angle (DEG).
1675  *
1676  * @param x1 first finger x location.
1677  * @param y1 first finger y location.
1678  * @param x2 second finger x location.
1679  * @param y2 second finger y location.
1680  *
1681  * @return angle of the line between (x1,y1), (x2,y2) in Deg.
1682  * Angles now are given in DEG, not RAD.
1683  * ZERO angle at 12-oclock, growing clockwise.
1684  *
1685  * @ingroup Elm_Gesture_Layer
1686  */
1687 static double
1688 <<<<<<< HEAD
1689 get_angle(Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2)
1690 {
1691    double a, xx, yy, rt = (-1);
1692    xx = fabs(x2 - x1);
1693    yy = fabs(y2 - y1);
1694
1695    if (((int) xx) && ((int) yy))
1696      {
1697         rt = a = RAD2DEG(atan(yy / xx));
1698         if (x1 < x2)
1699           {
1700              if (y1 < y2)
1701                {
1702                   rt = 360 - a;
1703                }
1704              else
1705                {
1706                   rt = (a);
1707                }
1708           }
1709         else
1710           {
1711              if (y1 < y2)
1712                {
1713                   rt = 180 + a;
1714                }
1715              else
1716                {
1717                   rt = 180 - a;
1718                }
1719 =======
1720 get_angle(Evas_Coord xx1, Evas_Coord yy1, Evas_Coord xx2, Evas_Coord yy2)
1721 {
1722    double a, xx, yy, rt = (-1);
1723    xx = fabs(xx2 - xx1);
1724    yy = fabs(yy2 - yy1);
1725
1726    if (((int)xx) && ((int)yy))
1727      {
1728         rt = a = RAD2DEG(atan(yy / xx));
1729         if (xx1 < xx2)
1730           {
1731              if (yy1 < yy2) rt = 360 - a;
1732              else rt = a;
1733           }
1734         else
1735           {
1736              if (yy1 < yy2) rt = 180 + a;
1737              else rt = 180 - a;
1738 >>>>>>> remotes/origin/upstream
1739           }
1740      }
1741
1742    if (rt < 0)
1743      {  /* Do this only if rt is not set */
1744 <<<<<<< HEAD
1745         if (((int) xx))
1746           {  /* Horizontal line */
1747              if (x2 < x1)
1748                {
1749                   rt = 180;
1750                }
1751              else
1752                {
1753                   rt = 0.0;
1754                }
1755           }
1756         else
1757           {  /* Vertical line */
1758              if (y2 < y1)
1759                {
1760                   rt = 90;
1761                }
1762              else
1763                {
1764                   rt = 270;
1765                }
1766 =======
1767         if (((int)xx))
1768           {  /* Horizontal line */
1769              if (xx2 < xx1) rt = 180;
1770              else rt = 0.0;
1771           }
1772         else
1773           {  /* Vertical line */
1774              if (yy2 < yy1) rt = 90;
1775              else rt = 270;
1776 >>>>>>> remotes/origin/upstream
1777           }
1778      }
1779
1780    /* Now we want to change from:
1781     *                      90                   0
1782     * original circle   180   0   We want:  270   90
1783     *                     270                 180
1784     */
1785 <<<<<<< HEAD
1786
1787    rt = 450 - rt;
1788    if (rt >= 360)
1789      rt -= 360;
1790 =======
1791    rt = 450 - rt;
1792    if (rt >= 360) rt -= 360;
1793 >>>>>>> remotes/origin/upstream
1794
1795    return rt;
1796 }
1797
1798 /**
1799  * @internal
1800  *
1801  * This function is used for computing the magnitude and direction
1802  * of vector between two points.
1803  *
1804  * @param x1 first finger x location.
1805  * @param y1 first finger y location.
1806  * @param x2 second finger x location.
1807  * @param y2 second finger y location.
1808  * @param l length computed (output)
1809  * @param a angle computed (output)
1810  *
1811  * @ingroup Elm_Gesture_Layer
1812  */
1813 static void
1814 <<<<<<< HEAD
1815 get_vector(Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2,
1816       Evas_Coord *l, double *a)
1817 {
1818    Evas_Coord xx, yy;
1819    xx = x2 - x1;
1820    yy = y2 - y1;
1821    *l = (Evas_Coord) sqrt(xx*xx + yy*yy);
1822    *a = get_angle(x1, y1, x2, y2);
1823 }
1824
1825 static int
1826 _get_direction(Evas_Coord x1, Evas_Coord x2)
1827 {
1828    if (x2 < x1)
1829      return -1;
1830
1831    if (x2 > x1)
1832      return 1;
1833
1834 =======
1835 get_vector(Evas_Coord xx1, Evas_Coord yy1, Evas_Coord xx2, Evas_Coord yy2,
1836            Evas_Coord *l, double *a)
1837 {
1838    Evas_Coord xx, yy;
1839    xx = xx2 - xx1;
1840    yy = yy2 - yy1;
1841    *l = (Evas_Coord) sqrt((xx * xx) + (yy * yy));
1842    *a = get_angle(xx1, yy1, xx2, yy2);
1843 }
1844
1845 static int
1846 _get_direction(Evas_Coord xx1, Evas_Coord xx2)
1847 {
1848    if (xx2 < xx1) return -1;
1849    if (xx2 > xx1) return 1;
1850 >>>>>>> remotes/origin/upstream
1851    return 0;
1852 }
1853 /**
1854  * @internal
1855  *
1856  * This function tests momentum gesture.
1857  * @param obj The gesture-layer object.
1858  * @param pe The recent input event as stored in pe struct.
1859  * @param event_info recent input event.
1860  * @param event_type recent event type.
1861  * @param g_type what Gesture we are testing.
1862  *
1863  * @ingroup Elm_Gesture_Layer
1864  */
1865 static void
1866 _momentum_test(Evas_Object *obj, Pointer_Event *pe,
1867 <<<<<<< HEAD
1868       void *event_info, Evas_Callback_Type event_type,
1869       Elm_Gesture_Types g_type)
1870 =======
1871                void *event_info, Evas_Callback_Type event_type,
1872                Elm_Gesture_Type g_type)
1873 >>>>>>> remotes/origin/upstream
1874 {
1875    Widget_Data *wd = elm_widget_data_get(obj);
1876    if (!wd) return;
1877    Gesture_Info *gesture = wd->gesture[g_type];
1878    if (!gesture ) return;
1879
1880    /* When continues enable = TRUE a gesture may START on MOVE event */
1881    /* We don't allow this to happen with the if-statement below.     */
1882    /* When continues enable = FALSE a gesture may START on DOWN only */
1883    /* Therefor it would NOT start on MOVE event.                     */
1884    /* NOTE that touched list is updated AFTER this function returns  */
1885    /* so (count == 0) when we get here on first touch on surface.    */
1886    if ((wd->glayer_continues_enable) && (!eina_list_count(wd->touched)))
1887      return; /* Got move on mouse-over move */
1888
1889    Momentum_Type *st = gesture->data;
1890    Elm_Gesture_State state_to_report = ELM_GESTURE_STATE_MOVE;
1891    if (!st)
1892      {  /* Allocated once on first time */
1893         st = calloc(1, sizeof(Momentum_Type));
1894         gesture->data = st;
1895         _momentum_test_reset(gesture);
1896      }
1897
1898    if (!pe)
1899      return;
1900
1901    /* First make avarage of all touched devices to determine center point */
1902    Eina_List *l;
1903    Pointer_Event *p;
1904    Pointer_Event pe_local = *pe;           /* Copy pe event info to local */
1905    unsigned int cnt = 1;    /* We start counter counting current pe event */
1906    EINA_LIST_FOREACH(wd->touched, l, p)
1907       if (p->device != pe_local.device)
1908         {
1909            pe_local.x += p->x;
1910            pe_local.y += p->y;
1911            cnt++;
1912         }
1913
1914
1915    /* Compute avarage to get center point */
1916    pe_local.x /= cnt;
1917    pe_local.y /= cnt;
1918
1919    /* If user added finger - reset gesture */
1920    if ((st->info.n) && (st->info.n < cnt))
1921      state_to_report = ELM_GESTURE_STATE_ABORT;
1922
1923
1924    if (st->info.n < cnt)
1925      st->info.n = cnt;
1926
1927    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
1928    switch (event_type)
1929      {
1930       case EVAS_CALLBACK_MOUSE_DOWN:
1931       case EVAS_CALLBACK_MULTI_DOWN:
1932       case EVAS_CALLBACK_MOUSE_MOVE:
1933       case EVAS_CALLBACK_MULTI_MOVE:
1934          if (!st->t_st_x)
1935            {
1936               if ((event_type == EVAS_CALLBACK_MOUSE_DOWN) ||
1937                     (event_type == EVAS_CALLBACK_MULTI_DOWN) ||
1938                     (wd->glayer_continues_enable)) /* start also on MOVE */
1939                 {  /* We start on MOVE when cont-enabled only */
1940                    st->line_st.x = st->line_end.x = pe_local.x;
1941                    st->line_st.y = st->line_end.y = pe_local.y;
1942                    st->t_st_x = st->t_st_y = st->t_end = pe_local.timestamp;
1943                    st->xdir = st->ydir = 0;
1944                    st->info.x2 = st->info.x1 = pe_local.x;
1945                    st->info.y2 = st->info.y1 = pe_local.y;
1946                    st->info.tx = st->info.ty = pe_local.timestamp;
1947                    ev_flag = _set_state(gesture, ELM_GESTURE_STATE_START,
1948                          &st->info, EINA_FALSE);
1949                    consume_event(wd, event_info, event_type, ev_flag);
1950                 }
1951
1952               return;
1953            }
1954
1955
1956          if (st->t_up)
1957            {
1958               Eina_Bool force = EINA_TRUE;  /* for move state */
1959               if ((st->t_up + ELM_GESTURE_MULTI_TIMEOUT) < pe_local.timestamp)
1960                 {  /* ABORT if got DOWN or MOVE event after UP+timeout */
1961                    state_to_report = ELM_GESTURE_STATE_ABORT;
1962                    force = EINA_FALSE;
1963                 }
1964
1965               /* We report state but don't compute momentum now */
1966               ev_flag = _set_state(gesture, state_to_report, &st->info,
1967                     force);
1968               consume_event(wd, event_info, event_type, ev_flag);
1969               return; /* Stop computing when user remove finger */
1970            }
1971
1972          if ((pe_local.timestamp - ELM_GESTURE_MOMENTUM_TIMEOUT) > st->t_end)
1973            {  /*  Too long of a wait, reset all values */
1974               st->line_st.x = pe_local.x;
1975               st->line_st.y = pe_local.y;
1976               st->t_st_y = st->t_st_x = pe_local.timestamp;
1977               st->info.tx = st->t_st_x;
1978               st->info.ty = st->t_st_y;
1979               st->xdir = st->ydir = 0;
1980            }
1981          else
1982            {
1983               int xdir, ydir;
1984               xdir = _get_direction(st->line_end.x, pe_local.x);
1985               ydir = _get_direction(st->line_end.y, pe_local.y);
1986               if (xdir && (xdir != st->xdir))
1987                 {
1988                    st->line_st.x = st->line_end.x;
1989                    st->info.tx = st->t_st_x = st->t_end;
1990                    st->xdir = xdir;
1991                 }
1992
1993               if (ydir && (ydir != st->ydir))
1994                 {
1995                    st->line_st.y = st->line_end.y;
1996                    st->info.ty = st->t_st_y = st->t_end;
1997                    st->ydir = ydir;
1998                 }
1999            }
2000
2001          st->info.x2 = st->line_end.x = pe_local.x;
2002          st->info.y2 = st->line_end.y = pe_local.y;
2003          st->t_end = pe_local.timestamp;
2004          _set_momentum(&st->info, st->line_st.x, st->line_st.y,
2005                pe_local.x, pe_local.y, st->t_st_x, st->t_st_y,
2006                pe_local.timestamp);
2007
2008          ev_flag = _set_state(gesture, state_to_report, &st->info,
2009                EINA_TRUE);
2010          consume_event(wd, event_info, event_type, ev_flag);
2011          break;
2012
2013
2014       case EVAS_CALLBACK_MOUSE_UP:
2015       case EVAS_CALLBACK_MULTI_UP:
2016          st->t_up = pe_local.timestamp;       /* Record recent up event time */
2017          if ((cnt > 1) ||     /* Ignore if more fingers touch surface        */
2018                (!st->t_st_x)) /* IGNORE if info was cleared, long press,move */
2019            return;
2020
2021          if ((pe_local.timestamp - ELM_GESTURE_MOMENTUM_TIMEOUT) > st->t_end)
2022            {  /* Too long of a wait, reset all values */
2023               st->line_st.x = pe_local.x;
2024               st->line_st.y = pe_local.y;
2025               st->t_st_y = st->t_st_x = pe_local.timestamp;
2026               st->xdir = st->ydir = 0;
2027            }
2028
2029          st->info.x2 = pe_local.x;
2030          st->info.y2 = pe_local.y;
2031          st->line_end.x = pe_local.x;
2032          st->line_end.y = pe_local.y;
2033          st->t_end = pe_local.timestamp;
2034
2035          if ((fabs(st->info.mx) > ELM_GESTURE_MINIMUM_MOMENTUM) ||
2036                (fabs(st->info.my) > ELM_GESTURE_MINIMUM_MOMENTUM))
2037            state_to_report = ELM_GESTURE_STATE_END;
2038          else
2039            state_to_report = ELM_GESTURE_STATE_ABORT;
2040
2041          ev_flag = _set_state(gesture, state_to_report, &st->info,
2042                EINA_FALSE);
2043          consume_event(wd, event_info, event_type, ev_flag);
2044          return;
2045
2046       default:
2047          return;
2048      }
2049 }
2050
2051 static int
2052 compare_line_device(const void *data1, const void *data2)
2053 {  /* Compare device component of line struct */
2054    const Line_Data *ln1 = data1;
2055    const int *device = data2;
2056
2057    if (ln1->t_st) /* Compare only with lines that started */
2058      return (ln1->device - (*device));
2059
2060    return (-1);
2061 }
2062
2063 /**
2064  * @internal
2065  *
2066  * This function construct line struct from input.
2067  * @param info pointer to store line momentum.
2068  * @param st line info to store input data.
2069  * @param pe The recent input event as stored in pe struct.
2070  *
2071  * @ingroup Elm_Gesture_Layer
2072  */
2073 static Eina_Bool
2074 _single_line_process(Elm_Gesture_Line_Info *info, Line_Data *st,
2075       Pointer_Event *pe, Evas_Callback_Type event_type)
2076 {  /* Record events and set momentum for line pointed by st */
2077    if (!pe)
2078      return EINA_FALSE;
2079
2080    switch (event_type)
2081      {
2082       case EVAS_CALLBACK_MOUSE_DOWN:
2083       case EVAS_CALLBACK_MOUSE_MOVE:
2084       case EVAS_CALLBACK_MULTI_DOWN:
2085       case EVAS_CALLBACK_MULTI_MOVE:
2086          if (!st->t_st)
2087            {  /* This happens only when line starts */
2088               st->line_st.x = pe->x;
2089               st->line_st.y = pe->y;
2090               st->t_st = pe->timestamp;
2091               st->device = pe->device;
2092               info->momentum.x1 = pe->x;
2093               info->momentum.y1 = pe->y;
2094               info->momentum.tx = pe->timestamp;
2095               info->momentum.ty = pe->timestamp;
2096
2097               return EINA_TRUE;
2098            }
2099
2100          break;
2101
2102       case EVAS_CALLBACK_MOUSE_UP:
2103       case EVAS_CALLBACK_MULTI_UP:
2104          /* IGNORE if line info was cleared, like long press, move */
2105          if (!st->t_st)
2106            return EINA_FALSE;
2107
2108          st->line_end.x = pe->x;
2109          st->line_end.y = pe->y;
2110          st->t_end = pe->timestamp;
2111          break;
2112
2113       default:
2114          return EINA_FALSE;
2115      }
2116
2117    if (!st->t_st)
2118      {
2119         _line_data_reset(st);
2120         return EINA_FALSE;
2121      }
2122
2123    info->momentum.x2 = pe->x;
2124    info->momentum.y2 = pe->y;
2125    _set_momentum(&info->momentum, st->line_st.x, st->line_st.y, pe->x, pe->y,
2126          st->t_st, st->t_st, pe->timestamp);
2127
2128    return EINA_TRUE;
2129 }
2130
2131 /**
2132  * @internal
2133  *
2134  * This function test for (n) line gesture.
2135  * @param obj The gesture-layer object.
2136  * @param pe The recent input event as stored in pe struct.
2137  * @param event_info Original input event pointer.
2138  * @param event_type Type of original input event.
2139  * @param g_type what Gesture we are testing.
2140  *
2141  * @ingroup Elm_Gesture_Layer
2142  */
2143 static void
2144 _n_line_test(Evas_Object *obj, Pointer_Event *pe, void *event_info,
2145 <<<<<<< HEAD
2146       Evas_Callback_Type event_type, Elm_Gesture_Types g_type)
2147 =======
2148       Evas_Callback_Type event_type, Elm_Gesture_Type g_type)
2149 >>>>>>> remotes/origin/upstream
2150 {
2151    if (!pe)
2152      return;
2153    Widget_Data *wd = elm_widget_data_get(obj);
2154    if (!wd) return;
2155    Gesture_Info *gesture = wd->gesture[g_type];
2156    if (!gesture ) return;
2157
2158    /* When continues enable = TRUE a gesture may START on MOVE event */
2159    /* We don't allow this to happen with the if-statement below.     */
2160    /* When continues enable = FALSE a gesture may START on DOWN only */
2161    /* Therefor it would NOT start on MOVE event.                     */
2162    /* NOTE that touched list is updated AFTER this function returns  */
2163    /* so (count == 0) when we get here on first touch on surface.    */
2164    if ((wd->glayer_continues_enable) && (!eina_list_count(wd->touched)))
2165      return; /* Got move on mouse-over move */
2166
2167    Line_Type *st = gesture->data;
2168    if (!st)
2169      {
2170         st = calloc(1, sizeof(Line_Type));
2171         gesture->data = st;
2172      }
2173
2174    Line_Data *line = NULL;
2175    Eina_List *list = st->list;
2176    unsigned cnt = eina_list_count(list);
2177
2178    if (cnt)
2179      {  /* list is not empty, locate this device on list */
2180         line = (Line_Data *) eina_list_search_unsorted(st->list,
2181               compare_line_device, &pe->device);
2182      }
2183
2184    if (!line)
2185      {  /* List is empty or device not found, new line-struct on START only */
2186         if ((event_type == EVAS_CALLBACK_MOUSE_DOWN) ||
2187               (event_type == EVAS_CALLBACK_MULTI_DOWN) ||
2188               ((wd->glayer_continues_enable) && /* START on MOVE also */
2189                ((event_type == EVAS_CALLBACK_MOUSE_MOVE) ||
2190                 (event_type == EVAS_CALLBACK_MULTI_MOVE))))
2191           {  /* Allocate new item on START only */
2192              line = calloc(1, sizeof(Line_Data));
2193              _line_data_reset(line);
2194              list = eina_list_append(list, line);
2195              st->list = list;
2196           }
2197      }
2198
2199    if (!line)  /* This may happen on MOVE that comes before DOWN      */
2200      return;   /* No line-struct to work with, can't continue testing */
2201
2202    if (_single_line_process(&st->info, line, pe, event_type)) /* update st with input */
2203      consume_event(wd, event_info, event_type, EVAS_EVENT_FLAG_NONE);
2204
2205    /* Get direction and magnitude of the line */
2206    double angle;
2207    get_vector(line->line_st.x, line->line_st.y, pe->x, pe->y,
2208          &line->line_length, &angle);
2209
2210    /* These are used later to compare lines length */
2211    Evas_Coord shortest_line_len = line->line_length;
2212    Evas_Coord longest_line_len = line->line_length;
2213    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
2214
2215    /* Now update line-state */
2216    if (line->t_st)
2217      {  /* Analyze line only if line started */
2218         if (line->line_angle >= 0.0)
2219           {  /* if line direction was set, we test if broke tolerance */
2220              double a = fabs(angle - line->line_angle);
2221
2222              double d = (tan(DEG2RAD(a))) * line->line_length; /* Distance from line */
2223 #if defined(DEBUG_GESTURE_LAYER)
2224              printf("%s a=<%f> d=<%f>\n", __func__, a, d);
2225 #endif
2226              if ((d > wd->line_distance_tolerance) || (a > wd->line_angular_tolerance))
2227                {  /* Broke tolerance: abort line and start a new one */
2228                   ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
2229                         &st->info, EINA_FALSE);
2230                   consume_event(wd, event_info, event_type, ev_flag);
2231                   return;
2232                }
2233
2234              if (wd->glayer_continues_enable)
2235                {  /* We may finish line if momentum is zero */
2236                   /* This is for continues-gesture */
2237                   if ((!st->info.momentum.mx) && (!st->info.momentum.my))
2238                     {  /* Finish line on zero momentum for continues gesture */
2239                        line->line_end.x = pe->x;
2240                        line->line_end.y = pe->y;
2241                        line->t_end = pe->timestamp;
2242                     }
2243                }
2244           }
2245         else
2246           {  /* Record the line angle as it broke minimum length for line */
2247              if (line->line_length >= wd->line_min_length)
2248                st->info.angle = line->line_angle = angle;
2249           }
2250
2251
2252         if (line->t_end)
2253           {
2254              if (line->line_angle < 0.0)
2255                { /* it's not a line, too short more close to a tap */
2256                   ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
2257                         &st->info, EINA_FALSE);
2258                   consume_event(wd, event_info, event_type, ev_flag);
2259                   return;
2260                }
2261           }
2262      }
2263
2264    /* Count how many lines already started / ended */
2265    int started = 0;
2266    int ended = 0;
2267    unsigned int tm_start = pe->timestamp;
2268    unsigned int tm_end = pe->timestamp;
2269    Eina_List *l;
2270    Line_Data *t_line;
2271    double base_angle = ELM_GESTURE_NEGATIVE_ANGLE;
2272    Eina_Bool lines_parallel = EINA_TRUE;
2273    EINA_LIST_FOREACH(list, l, t_line)
2274      {
2275         if (base_angle < 0)
2276           base_angle = t_line->line_angle;
2277         else
2278           {
2279              if (t_line->line_angle >= 0)
2280                {  /* Compare angle only with lines with direction defined */
2281                   if (fabs(base_angle - t_line->line_angle) >
2282                         wd->line_angular_tolerance)
2283                     lines_parallel = EINA_FALSE;
2284                }
2285           }
2286
2287         if (t_line->line_length)
2288           {  /* update only if this line is used */
2289              if (shortest_line_len > t_line->line_length)
2290                shortest_line_len = t_line->line_length;
2291
2292              if (longest_line_len < t_line->line_length)
2293                longest_line_len = t_line->line_length;
2294           }
2295
2296         if (t_line->t_st)
2297           {
2298              started++;
2299              if (t_line->t_st < tm_start)
2300                tm_start = t_line->t_st;
2301           }
2302
2303         if (t_line->t_end)
2304           {
2305              ended++;
2306              if (t_line->t_end < tm_end)
2307                tm_end = t_line->t_end;
2308           }
2309      }
2310
2311    st->info.momentum.n = started;
2312
2313
2314    if (ended &&
2315          ((event_type == EVAS_CALLBACK_MOUSE_DOWN) ||
2316           (event_type == EVAS_CALLBACK_MULTI_DOWN)))
2317      {  /* user lift one finger then starts again without line-end - ABORT */
2318         ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT, &st->info,
2319               EINA_FALSE);
2320         consume_event(wd, event_info, event_type, ev_flag);
2321         return;
2322      }
2323
2324    if (!lines_parallel)
2325      { /* Lines are NOT at same direction, abort this gesture */
2326         ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT, &st->info,
2327               EINA_FALSE);
2328         consume_event(wd, event_info, event_type, ev_flag);
2329         return;
2330      }
2331
2332
2333    /* We report ABORT if lines length are NOT matching when fingers are up */
2334 <<<<<<< HEAD
2335    if ((longest_line_len - shortest_line_len) > (elm_finger_size_get()*2))
2336 =======
2337    if ((longest_line_len - shortest_line_len) > (_elm_config->finger_size * 2))
2338 >>>>>>> remotes/origin/upstream
2339      {
2340         ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT, &st->info,
2341               EINA_FALSE);
2342         consume_event(wd, event_info, event_type, ev_flag);
2343         return;
2344      }
2345
2346    if ((g_type == ELM_GESTURE_N_FLICKS) && ((tm_end - tm_start) > wd->flick_time_limit_ms))
2347      {  /* We consider FLICK as a fast line.ABORT if take too long to finish */
2348         ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT, &st->info,
2349               EINA_FALSE);
2350         consume_event(wd, event_info, event_type, ev_flag);
2351         return;
2352      }
2353
2354    switch (event_type)
2355      {
2356       case EVAS_CALLBACK_MOUSE_UP:
2357       case EVAS_CALLBACK_MULTI_UP:
2358          if ((started) && (started == ended))
2359            {
2360               ev_flag = _set_state(gesture, ELM_GESTURE_STATE_END,
2361                     &st->info, EINA_FALSE);
2362               consume_event(wd, event_info, event_type, ev_flag);
2363            }
2364
2365          return;
2366
2367       case EVAS_CALLBACK_MOUSE_DOWN:
2368       case EVAS_CALLBACK_MULTI_DOWN:
2369       case EVAS_CALLBACK_MOUSE_MOVE:
2370       case EVAS_CALLBACK_MULTI_MOVE:
2371          if (started)
2372            {
2373               if (wd->glayer_continues_enable && (started == ended))
2374                 {  /* For continues gesture */
2375                    ev_flag = _set_state(gesture, ELM_GESTURE_STATE_END,
2376                          &st->info, EINA_FALSE);
2377                    consume_event(wd, event_info, event_type, ev_flag);
2378                 }
2379               else
2380                 {  /* When continues, may START on MOVE event too */
2381                    Elm_Gesture_State s = ELM_GESTURE_STATE_MOVE;
2382
2383                    /* This happens when: on n > 1 lines then one finger up */
2384                    /* caused abort, then put finger down.                  */
2385                    /* This will stop line from starting again.             */
2386                    /* Number of lines, MUST match touched-device in list   */
2387                    if ((!wd->glayer_continues_enable) &&
2388                          (eina_list_count(st->list) < eina_list_count(wd->touched)))
2389                      s = ELM_GESTURE_STATE_ABORT;
2390
2391                    if (gesture->state == ELM_GESTURE_STATE_UNDEFINED)
2392                      s = ELM_GESTURE_STATE_START;
2393
2394                    ev_flag = _set_state(gesture, s, &st->info, EINA_TRUE);
2395                    consume_event(wd, event_info, event_type, ev_flag);
2396                 }
2397            }
2398          break;
2399
2400       default:
2401          return;  /* Unhandeld event type */
2402      }
2403 }
2404
2405 /**
2406  * @internal
2407  *
2408  * This function is used to check if rotation gesture started.
2409  * @param st Contains current rotation values from user input.
2410  * @return TRUE/FALSE if we need to set rotation START.
2411  *
2412  * @ingroup Elm_Gesture_Layer
2413  */
2414 static Eina_Bool
2415 rotation_broke_tolerance(Rotate_Type *st)
2416 {
2417    if (st->info.base_angle < 0)
2418      return EINA_FALSE; /* Angle has to be computed first */
2419
2420    if (st->rotate_angular_tolerance < 0)
2421      return EINA_TRUE;
2422
2423    double low  = st->info.base_angle - st->rotate_angular_tolerance;
2424    double high = st->info.base_angle + st->rotate_angular_tolerance;
2425    double t = st->info.angle;
2426
2427    if (low < 0)
2428      {
2429         low += 180;
2430         high += 180;
2431
2432         if (t < 180)
2433           t += 180;
2434         else
2435           t -= 180;
2436      }
2437
2438    if (high > 360)
2439      {
2440         low -= 180;
2441         high -= 180;
2442
2443         if (t < 180)
2444           t += 180;
2445         else
2446           t -= 180;
2447      }
2448
2449 #if defined(DEBUG_GESTURE_LAYER)
2450    printf("%s angle=<%f> low=<%f> high=<%f>\n", __func__, t, low, high);
2451 #endif
2452    if ((t < low) || (t > high))
2453      {  /* This marks that roation action has started */
2454         st->rotate_angular_tolerance = ELM_GESTURE_NEGATIVE_ANGLE;
2455         st->info.base_angle = st->info.angle; /* Avoid jump in angle value */
2456         return EINA_TRUE;
2457      }
2458
2459    return EINA_FALSE;
2460 }
2461
2462 /**
2463  * @internal
2464  *
2465  * This function is used for computing the gap between fingers.
2466  * It returns the length and center point between fingers.
2467  *
2468  * @param x1 first finger x location.
2469  * @param y1 first finger y location.
2470  * @param x2 second finger x location.
2471  * @param y2 second finger y location.
2472  * @param x  Gets center point x cord (output)
2473  * @param y  Gets center point y cord (output)
2474  *
2475  * @return length of the line between (x1,y1), (x2,y2) in pixels.
2476  *
2477  * @ingroup Elm_Gesture_Layer
2478  */
2479 static Evas_Coord
2480 <<<<<<< HEAD
2481 get_finger_gap_length(Evas_Coord x1, Evas_Coord y1, Evas_Coord x2,
2482       Evas_Coord y2, Evas_Coord *x, Evas_Coord *y)
2483 {
2484    double a, b, xx, yy, gap;
2485    xx = fabs(x2 - x1);
2486    yy = fabs(y2 - y1);
2487    gap = sqrt(xx*xx + yy*yy);
2488 =======
2489 get_finger_gap_length(Evas_Coord xx1, Evas_Coord yy1,
2490                       Evas_Coord xx2, Evas_Coord yy2,
2491                       Evas_Coord *x, Evas_Coord *y)
2492 {
2493    double a, b, xx, yy, gap;
2494    xx = fabs(xx2 - xx1);
2495    yy = fabs(yy2 - yy1);
2496    gap = sqrt((xx * xx) + (yy * yy));
2497 >>>>>>> remotes/origin/upstream
2498
2499    /* START - Compute zoom center point */
2500    /* The triangle defined as follows:
2501     *             B
2502     *           / |
2503     *          /  |
2504     *     gap /   | a
2505     *        /    |
2506     *       A-----C
2507     *          b
2508     * http://en.wikipedia.org/wiki/Trigonometric_functions
2509     *************************************/
2510 <<<<<<< HEAD
2511    if (((int) xx) && ((int) yy))
2512 =======
2513    if (((int)xx) && ((int)yy))
2514 >>>>>>> remotes/origin/upstream
2515      {
2516         double A = atan((yy / xx));
2517 #if defined(DEBUG_GESTURE_LAYER)
2518         printf("xx=<%f> yy=<%f> A=<%f>\n", xx, yy, A);
2519 #endif
2520         a = (Evas_Coord) ((gap / 2) * sin(A));
2521         b = (Evas_Coord) ((gap / 2) * cos(A));
2522 <<<<<<< HEAD
2523         *x = (Evas_Coord) ((x2 > x1) ? (x1 + b) : (x2 + b));
2524         *y = (Evas_Coord) ((y2 > y1) ? (y1 + a) : (y2 + a));
2525      }
2526    else
2527      {
2528         if ((int) xx)
2529 =======
2530         *x = (Evas_Coord) ((xx2 > xx1) ? (xx1 + b) : (xx2 + b));
2531         *y = (Evas_Coord) ((yy2 > yy1) ? (yy1 + a) : (yy2 + a));
2532      }
2533    else
2534      {
2535         if ((int)xx)
2536 >>>>>>> remotes/origin/upstream
2537           {  /* horiz line, take half width */
2538 #if defined(DEBUG_GESTURE_LAYER)
2539              printf("==== HORIZ ====\n");
2540 #endif
2541 <<<<<<< HEAD
2542              *x = (Evas_Coord) (xx / 2);
2543              *y = (Evas_Coord) (y1);
2544           }
2545
2546         if ((int) yy)
2547 =======
2548              *x = (Evas_Coord) ((xx1 + xx2) / 2);
2549              *y = (Evas_Coord) (yy1);
2550           }
2551
2552         if ((int)yy)
2553 >>>>>>> remotes/origin/upstream
2554           {  /* vert line, take half width */
2555 #if defined(DEBUG_GESTURE_LAYER)
2556              printf("==== VERT ====\n");
2557 #endif
2558 <<<<<<< HEAD
2559              *x = (Evas_Coord) (x1);
2560              *y = (Evas_Coord) (yy / 2);
2561 =======
2562              *x = (Evas_Coord) (xx1);
2563              *y = (Evas_Coord) ((yy1 + yy2) / 2);
2564 >>>>>>> remotes/origin/upstream
2565           }
2566      }
2567    /* END   - Compute zoom center point */
2568
2569    return (Evas_Coord) gap;
2570 }
2571
2572 /**
2573  * @internal
2574  *
2575  * This function is used for computing zoom value.
2576  *
2577  * @param st Pointer to zoom data based on user input.
2578  * @param tm_end Recent input event timestamp.
2579  * @param zoom_val Current computed zoom value.
2580  *
2581  * @return zoom momentum
2582  *
2583  * @ingroup Elm_Gesture_Layer
2584  */
2585 static double
2586 _zoom_momentum_get(Zoom_Type *st, unsigned int tm_end, double zoom_val)
2587 {
2588    unsigned int tm_total;
2589    if (!st->m_st_tm)
2590      {  /* Init, and we don't start computing momentum yet */
2591         st->m_st_tm = st->m_prev_tm = tm_end;
2592         st->m_base = zoom_val;
2593         return 0.0;
2594      }
2595
2596    if ((tm_end - ELM_GESTURE_MOMENTUM_DELAY) < st->m_st_tm)
2597      return 0.0; /* we don't start to compute momentum yet */
2598
2599    if (st->dir)
2600      {  /* if direction was already defined, check if changed */
2601         if (((st->dir < 0) && (zoom_val > st->info.zoom)) ||
2602               ((st->dir > 0) && (zoom_val < st->info.zoom)))
2603           {  /* Direction changed, reset momentum */
2604              st->m_st_tm = 0;
2605              st->dir = (-st->dir);
2606              return 0.0;
2607           }
2608      }
2609    else
2610      st->dir = (zoom_val > st->info.zoom) ? 1 : -1;  /* init */
2611
2612    if ((tm_end - ELM_GESTURE_MOMENTUM_TIMEOUT) > st->m_prev_tm)
2613      {
2614         st->m_st_tm = 0; /* Rest momentum when waiting too long */
2615         return 0.0;
2616      }
2617
2618    st->m_prev_tm = tm_end;
2619    tm_total = tm_end - st->m_st_tm;
2620
2621    if (tm_total)
2622      return ((zoom_val - st->m_base)  * 1000) / tm_total;
2623    else
2624      return 0.0;
2625 }
2626
2627 /**
2628  * @internal
2629  *
2630  * This function is used for computing zoom value.
2631  *
2632  * @param st Pointer to zoom data based on user input.
2633  * @param x1 first finger x location.
2634  * @param y1 first finger y location.
2635  * @param x2 second finger x location.
2636  * @param y2 second finger y location.
2637  * @param factor zoom-factor, used to determine how fast zoom works.
2638  *
2639  * @return zoom value, when 1.0 means no zoom, 0.5 half size...
2640  *
2641  * @ingroup Elm_Gesture_Layer
2642  */
2643 static double
2644 <<<<<<< HEAD
2645 compute_zoom(Zoom_Type *st, Evas_Coord x1, Evas_Coord y1,
2646       Evas_Coord x2, Evas_Coord y2, double zoom_finger_factor)
2647 {
2648    double rt = 1.0;
2649    unsigned int tm_end = (st->zoom_mv.timestamp > st->zoom_mv1.timestamp) ?
2650       st->zoom_mv.timestamp : st->zoom_mv1.timestamp;
2651
2652    Evas_Coord diam = get_finger_gap_length(x1, y1, x2, y2,
2653          &st->info.x, &st->info.y);
2654 =======
2655 compute_zoom(Zoom_Type *st,
2656              Evas_Coord xx1, Evas_Coord yy1,
2657              Evas_Coord xx2, Evas_Coord yy2,
2658              double zoom_finger_factor)
2659 {
2660    double rt = 1.0;
2661    unsigned int tm_end = (st->zoom_mv.timestamp > st->zoom_mv1.timestamp) ?
2662      st->zoom_mv.timestamp : st->zoom_mv1.timestamp;
2663
2664    Evas_Coord diam = get_finger_gap_length(xx1, yy1, xx2, yy2,
2665                                            &st->info.x, &st->info.y);
2666 >>>>>>> remotes/origin/upstream
2667
2668    st->info.radius = diam / 2;
2669
2670    if (!st->zoom_base)
2671      {
2672         st->zoom_base = diam;
2673         return st->info.zoom;
2674      }
2675
2676    if (st->zoom_distance_tolerance)
2677      {  /* zoom tolerance <> ZERO, means zoom action NOT started yet */
2678         if (diam < (st->zoom_base - st->zoom_distance_tolerance))
2679           {  /* avoid jump with zoom value when break tolerance */
2680              st->zoom_base -= st->zoom_distance_tolerance;
2681              st->zoom_distance_tolerance = 0;
2682           }
2683
2684         if (diam > (st->zoom_base + st->zoom_distance_tolerance))
2685           {  /* avoid jump with zoom value when break tolerance */
2686              st->zoom_base += st->zoom_distance_tolerance;
2687              st->zoom_distance_tolerance = 0;
2688           }
2689
2690         return rt;
2691      }
2692
2693    /* We use factor only on the difference between gap-base   */
2694    /* if gap=120, base=100, we get ((120-100)/100)=0.2*factor */
2695    rt = ((1.0) + ((((float) diam - (float) st->zoom_base) /
2696 <<<<<<< HEAD
2697                (float) st->zoom_base) * zoom_finger_factor));
2698 =======
2699                    (float) st->zoom_base) * zoom_finger_factor));
2700 >>>>>>> remotes/origin/upstream
2701
2702    /* Momentum: zoom per second: */
2703    st->info.momentum = _zoom_momentum_get(st, tm_end, rt);
2704
2705    return rt;
2706 }
2707
2708 /**
2709  * @internal
2710  *
2711  * This function handles zoom with mouse wheel.
2712  * thats a combination of wheel + CTRL key.
2713  * @param obj The gesture-layer object.
2714  * @param event_info Original input event pointer.
2715  * @param event_type Type of original input event.
2716  * @param g_type what Gesture we are testing.
2717  *
2718  * @ingroup Elm_Gesture_Layer
2719  */
2720 static void
2721 _zoom_with_wheel_test(Evas_Object *obj, void *event_info,
2722 <<<<<<< HEAD
2723       Evas_Callback_Type event_type, Elm_Gesture_Types g_type)
2724 =======
2725       Evas_Callback_Type event_type, Elm_Gesture_Type g_type)
2726 >>>>>>> remotes/origin/upstream
2727 {
2728    Widget_Data *wd = elm_widget_data_get(obj);
2729    if (!wd) return;
2730    if (!wd->gesture[g_type]) return;
2731
2732    Gesture_Info *gesture_zoom = wd->gesture[g_type];
2733    Zoom_Type *st = gesture_zoom->data;
2734    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
2735    if (!st)
2736      {  /* Allocated once on first time, used for zoom intermediate data */
2737         st = calloc(1, sizeof(Zoom_Type));
2738         gesture_zoom->data = st;
2739         _zoom_test_reset(gesture_zoom);
2740      }
2741
2742    switch (event_type)
2743      {
2744       case EVAS_CALLBACK_KEY_UP:
2745            {
2746               Evas_Event_Key_Up *p = event_info;
2747               if ((!strcmp(p->keyname, "Control_L")) ||
2748                     (!strcmp(p->keyname, "Control_R")))
2749                 {  /* Test if we ended a zoom gesture when releasing CTRL */
2750                    if ((st->zoom_wheel) &&
2751                          ((gesture_zoom->state == ELM_GESTURE_STATE_START) ||
2752                           (gesture_zoom->state == ELM_GESTURE_STATE_MOVE)))
2753                      {  /* User released CTRL after zooming */
2754                         st->info.momentum = _zoom_momentum_get(st,
2755                               p->timestamp, st->info.zoom);
2756
2757                         ev_flag = _set_state(gesture_zoom,
2758                               ELM_GESTURE_STATE_END, &st->info, EINA_FALSE);
2759                         consume_event(wd, event_info, event_type, ev_flag);
2760
2761                         return;
2762                      }
2763                 }
2764               break;
2765            }
2766
2767       case EVAS_CALLBACK_MOUSE_WHEEL:
2768            {
2769               Eina_Bool force;
2770               Elm_Gesture_State s;
2771               if (!evas_key_modifier_is_set(
2772                        ((Evas_Event_Mouse_Wheel *) event_info)->modifiers,
2773                        "Control"))
2774                 {  /* if using wheel witout CTRL after starting zoom */
2775                    if ((st->zoom_wheel) &&
2776                          ((gesture_zoom->state == ELM_GESTURE_STATE_START) ||
2777                           (gesture_zoom->state == ELM_GESTURE_STATE_MOVE)))
2778                      {
2779                         ev_flag = _set_state(gesture_zoom,
2780                               ELM_GESTURE_STATE_END, &st->info, EINA_FALSE);
2781                         consume_event(wd, event_info, event_type, ev_flag);
2782
2783                         return;
2784                      }
2785                    else
2786                      return; /* Ignore mouse-wheel without control */
2787                 }
2788
2789               /* Using mouse wheel with CTRL for zoom */
2790               if (st->zoom_wheel || (st->zoom_distance_tolerance == 0))
2791                 {  /* (zoom_wheel == NULL) and (zoom_distance_tolerance == 0)
2792                       we continue a zoom gesture */
2793                    force = EINA_TRUE;
2794                    s = ELM_GESTURE_STATE_MOVE;
2795                 }
2796               else
2797                 {  /* On first wheel event, report START */
2798                    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(
2799                             evas_object_evas_get(wd->target), "Control");
2800                    force = EINA_FALSE;
2801                    s = ELM_GESTURE_STATE_START;
2802                    if (!evas_object_key_grab(wd->target, "Control_L", mask, 0, EINA_FALSE))
2803                      ERR("Failed to Grabbed CTRL_L");
2804                    if (!evas_object_key_grab(wd->target, "Control_R", mask, 0, EINA_FALSE))
2805                      ERR("Failed to Grabbed CTRL_R");
2806                 }
2807
2808               st->zoom_distance_tolerance = 0; /* Cancel tolerance */
2809               st->zoom_wheel = (Evas_Event_Mouse_Wheel *) event_info;
2810               st->info.x  = st->zoom_wheel->canvas.x;
2811               st->info.y  = st->zoom_wheel->canvas.y;
2812
2813               if (st->zoom_wheel->z < 0) /* zoom in */
2814                 st->info.zoom += (wd->zoom_finger_factor * wd->zoom_wheel_factor);
2815
2816               if (st->zoom_wheel->z > 0) /* zoom out */
2817                 st->info.zoom -= (wd->zoom_finger_factor * wd->zoom_wheel_factor);
2818
2819               if (st->info.zoom < 0.0)
2820                 st->info.zoom = 0.0;
2821
2822               st->info.momentum = _zoom_momentum_get(st,
2823                     st->zoom_wheel->timestamp, st->info.zoom);
2824
2825               ev_flag = _set_state(gesture_zoom, s, &st->info, force);
2826               consume_event(wd, event_info, event_type, ev_flag);
2827               break;
2828            }
2829
2830       default:
2831            return;
2832      }
2833 }
2834
2835 /**
2836  * @internal
2837  *
2838  * This function is used to test zoom gesture.
2839  * user may combine zoom, rotation together.
2840  * so its possible that both will be detected from input.
2841  * (both are two-finger movement-oriented gestures)
2842  *
2843  * @param obj The gesture-layer object.
2844  * @param event_info Pointer to recent input event.
2845  * @param event_type Recent input event type.
2846  * @param g_type what Gesture we are testing.
2847  *
2848  * @ingroup Elm_Gesture_Layer
2849  */
2850 static void
2851 _zoom_test(Evas_Object *obj, Pointer_Event *pe, void *event_info,
2852 <<<<<<< HEAD
2853       Evas_Callback_Type event_type, Elm_Gesture_Types g_type)
2854 =======
2855       Evas_Callback_Type event_type, Elm_Gesture_Type g_type)
2856 >>>>>>> remotes/origin/upstream
2857 {
2858    if (!pe)
2859      return;
2860    Widget_Data *wd = elm_widget_data_get(obj);
2861    if (!wd) return;
2862    if (!wd->gesture[g_type]) return;
2863
2864    Gesture_Info *gesture_zoom = wd->gesture[g_type];
2865    Zoom_Type *st = gesture_zoom->data;
2866
2867    if (!st)
2868      {  /* Allocated once on first time, used for zoom data */
2869         st = calloc(1, sizeof(Zoom_Type));
2870         gesture_zoom->data = st;
2871         _zoom_test_reset(gesture_zoom);
2872      }
2873
2874
2875    /* Start - new zoom testing, letting all fingers start */
2876    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
2877    switch (event_type)
2878      {
2879       case EVAS_CALLBACK_MOUSE_MOVE:
2880       case EVAS_CALLBACK_MULTI_MOVE:
2881          /* if non-continues mode and gesture NOT started, ignore MOVE */
2882          if ((!wd->glayer_continues_enable) &&
2883                (!st->zoom_st.timestamp))
2884            return;
2885
2886       case EVAS_CALLBACK_MOUSE_DOWN:
2887       case EVAS_CALLBACK_MULTI_DOWN:
2888            {  /* Here we take care of zoom-start and zoom move */
2889               Eina_List *l;
2890               Pointer_Event *p;
2891
2892               if(eina_list_count(wd->touched) > 2)
2893                 {  /* Process zoom only when 2 fingers on surface */
2894                    ev_flag = _set_state(gesture_zoom,
2895                          ELM_GESTURE_STATE_ABORT, &st->info, EINA_FALSE);
2896                    consume_event(wd, event_info, event_type, ev_flag);
2897
2898                    return;
2899                 }
2900
2901               if (!st->zoom_st.timestamp)
2902                 {  /* Now scan touched-devices list and find other finger */
2903                    EINA_LIST_FOREACH(wd->touched, l, p)
2904                      {  /* Device of other finger <> pe device */
2905                         if (p->device != pe->device)
2906                           break;
2907                      }
2908
2909                    if (!p)  /* Single finger on touch */
2910                         return;
2911
2912                    /* Record down fingers */
2913                    consume_event(wd, event_info, event_type, ev_flag);
2914                    memcpy(&st->zoom_st, pe, sizeof(Pointer_Event));
2915                    memcpy(&st->zoom_st1, p, sizeof(Pointer_Event));
2916
2917                    /* Set mv field as well to be ready for MOVE events  */
2918                    memcpy(&st->zoom_mv, pe, sizeof(Pointer_Event));
2919                    memcpy(&st->zoom_mv1, p, sizeof(Pointer_Event));
2920
2921                    /* Here we have zoom_st, zoom_st1 set, report START  */
2922                    /* Set zoom-base after BOTH down events  recorded    */
2923                    /* Compute length of line between fingers zoom start */
2924                    st->info.zoom = 1.0;
2925                    st->zoom_base = get_finger_gap_length(st->zoom_st1.x,
2926                          st->zoom_st1.y, st->zoom_st.x,  st->zoom_st.y,
2927                          &st->info.x, &st->info.y);
2928
2929                    st->info.radius = st->zoom_base / 2;
2930
2931                    if ((gesture_zoom->state != ELM_GESTURE_STATE_START) &&
2932                          (gesture_zoom->state != ELM_GESTURE_STATE_MOVE))
2933                      {  /* zoom started with mouse-wheel, don't report twice */
2934                         ev_flag = _set_state(gesture_zoom,
2935                               ELM_GESTURE_STATE_START, &st->info, EINA_FALSE);
2936                         consume_event(wd, event_info, event_type, ev_flag);
2937                      }
2938
2939                    return;  /* Zoom started */
2940                 }  /* End of ZOOM_START handling */
2941
2942
2943               /* if we got here, we have (exacally) two fingers on surfce */
2944               /* we also after START, report MOVE */
2945               /* First detect which finger moved  */
2946               if (pe->device == st->zoom_mv.device)
2947                 memcpy(&st->zoom_mv, pe, sizeof(Pointer_Event));
2948               else if (pe->device == st->zoom_mv1.device)
2949                 memcpy(&st->zoom_mv1, pe, sizeof(Pointer_Event));
2950
2951               /* Compute change in zoom as fingers move */
2952               st->info.zoom = compute_zoom(st,
2953                     st->zoom_mv.x, st->zoom_mv.y,
2954                     st->zoom_mv1.x, st->zoom_mv1.y,
2955                     wd->zoom_finger_factor);
2956
2957               if (!st->zoom_distance_tolerance)
2958                 {  /* Zoom broke tolerance, report move */
2959                    double d = st->info.zoom - st->next_step;
2960                    if (d < 0.0)
2961                      d = (-d);
2962
2963                    if (d >= wd->zoom_step)
2964                      {  /* Report move in steps */
2965                         st->next_step = st->info.zoom;
2966
2967                         ev_flag = _set_state(gesture_zoom,
2968                               ELM_GESTURE_STATE_MOVE,
2969                               &st->info, EINA_TRUE);
2970                         consume_event(wd, event_info, event_type, ev_flag);
2971                      }
2972                 }  /* End of ZOOM_MOVE handling */
2973
2974               return;
2975            }
2976
2977       case EVAS_CALLBACK_MOUSE_UP:
2978       case EVAS_CALLBACK_MULTI_UP:
2979          /* Reset timestamp of finger-up.This is used later
2980             by _zoom_test_reset() to retain finger-down data */
2981          consume_event(wd, event_info, event_type, ev_flag);
2982          if (((st->zoom_wheel) || (st->zoom_base)) &&
2983                (st->zoom_distance_tolerance == 0))
2984            {
2985               ev_flag = _set_state(gesture_zoom, ELM_GESTURE_STATE_END,
2986                     &st->info, EINA_FALSE);
2987               consume_event(wd, event_info, event_type, ev_flag);
2988
2989               return;
2990            }
2991
2992          /* if we got here not a ZOOM */
2993          if (gesture_zoom->state != ELM_GESTURE_STATE_UNDEFINED)
2994            {  /* Must be != undefined, if gesture started */
2995               ev_flag = _set_state(gesture_zoom,
2996                     ELM_GESTURE_STATE_ABORT, &st->info, EINA_FALSE);
2997               consume_event(wd, event_info, event_type, ev_flag);
2998            }
2999
3000          _zoom_test_reset(gesture_zoom);
3001
3002          return;
3003
3004       default:
3005          return;
3006        }
3007 }
3008
3009 static void
3010 _get_rotate_properties(Rotate_Type *st,
3011 <<<<<<< HEAD
3012       Evas_Coord x1, Evas_Coord y1,
3013       Evas_Coord x2, Evas_Coord y2,
3014       double *angle)
3015 {  /* FIXME: Fix momentum computation, it's wrong */
3016    double prev_angle = *angle;
3017    st->info.radius = get_finger_gap_length(x1, y1, x2, y2,
3018          &st->info.x, &st->info.y) / 2;
3019
3020    *angle = get_angle(x1, y1, x2, y2);
3021
3022 =======
3023                        Evas_Coord xx1, Evas_Coord yy1,
3024                        Evas_Coord xx2, Evas_Coord yy2,
3025                        double *angle)
3026 {  /* FIXME: Fix momentum computation, it's wrong */
3027    double prev_angle = *angle;
3028    st->info.radius = get_finger_gap_length(xx1, yy1, xx2, yy2,
3029                                            &st->info.x, &st->info.y) / 2;
3030
3031    *angle = get_angle(xx1, yy1, xx2, yy2);
3032    
3033 >>>>>>> remotes/origin/upstream
3034    if (angle == &st->info.angle)
3035      {  /* Fingers are moving, compute momentum */
3036         unsigned int tm_start =
3037            (st->rotate_st.timestamp > st->rotate_st1.timestamp)
3038            ?  st->rotate_st.timestamp : st->rotate_st1.timestamp;
3039         unsigned int tm_end =
3040            (st->rotate_mv.timestamp > st->rotate_mv1.timestamp)
3041            ? st->rotate_mv.timestamp : st->rotate_mv1.timestamp;
3042
3043         unsigned int tm_total = tm_end - tm_start;
3044         if (tm_total)
3045           {  /* Momentum computed as:
3046                 accumulated roation angle (deg) divided by time */
3047              double m = 0;;
3048              if (((prev_angle < 90) && ((*angle) > 270)) ||
3049                    ((prev_angle > 270) && ((*angle) < 90)))
3050                {  /* We circle passing ZERO point */
3051                   prev_angle = (*angle);
3052                }
3053              else m = prev_angle - (*angle);
3054
3055              st->accum_momentum += m;
3056
3057              if ((tm_end - st->prev_momentum_tm) < 100)
3058                st->prev_momentum += m;
3059              else
3060                {
3061                   if (fabs(st->prev_momentum) < 0.002)
3062                     st->accum_momentum = 0.0;  /* reset momentum */
3063
3064                   st->prev_momentum = 0.0;     /* Start again    */
3065                }
3066
3067              st->prev_momentum_tm = tm_end;
3068              st->info.momentum = (st->accum_momentum * 1000) / tm_total;
3069           }
3070      }
3071    else
3072      st->info.momentum = 0;
3073 }
3074
3075 /**
3076  * @internal
3077  *
3078  * This function is used to test rotation gesture.
3079  * user may combine zoom, rotation together.
3080  * so its possible that both will be detected from input.
3081  * (both are two-finger movement-oriented gestures)
3082  *
3083  * @param obj The gesture-layer object.
3084  * @param event_info Pointer to recent input event.
3085  * @param event_type Recent input event type.
3086  * @param g_type what Gesture we are testing.
3087  *
3088  * @ingroup Elm_Gesture_Layer
3089  */
3090 static void
3091 _rotate_test(Evas_Object *obj, Pointer_Event *pe, void *event_info,
3092 <<<<<<< HEAD
3093       Evas_Callback_Type event_type, Elm_Gesture_Types g_type)
3094 =======
3095       Evas_Callback_Type event_type, Elm_Gesture_Type g_type)
3096 >>>>>>> remotes/origin/upstream
3097 {
3098    if (!pe)
3099      return;
3100
3101    Widget_Data *wd = elm_widget_data_get(obj);
3102    if (!wd) return;
3103    if (!wd->gesture[g_type]) return;
3104
3105    Gesture_Info *gesture = wd->gesture[g_type];
3106    Rotate_Type *st;
3107    if (gesture)
3108    {
3109       st = gesture->data;
3110       if (!st)
3111         {  /* Allocated once on first time */
3112            st = calloc(1, sizeof(Rotate_Type));
3113            gesture->data = st;
3114            _rotate_test_reset(gesture);
3115         }
3116    }
3117
3118    Evas_Event_Flags ev_flag = EVAS_EVENT_FLAG_NONE;
3119    switch (event_type)
3120      {
3121       case EVAS_CALLBACK_MOUSE_MOVE:
3122       case EVAS_CALLBACK_MULTI_MOVE:
3123          /* if non-continues mode and gesture NOT started, ignore MOVE */
3124          if ((!wd->glayer_continues_enable) &&
3125                (!st->rotate_st.timestamp))
3126            return;
3127
3128       case EVAS_CALLBACK_MOUSE_DOWN:
3129       case EVAS_CALLBACK_MULTI_DOWN:
3130            {  /* Here we take care of rotate-start and rotate move */
3131               Eina_List *l;
3132               Pointer_Event *p;
3133
3134               if(eina_list_count(wd->touched) > 2)
3135                 {  /* Process rotate only when 2 fingers on surface */
3136                    ev_flag = _set_state(gesture,
3137                          ELM_GESTURE_STATE_ABORT, &st->info, EINA_FALSE);
3138                    consume_event(wd, event_info, event_type, ev_flag);
3139
3140                    return;
3141                 }
3142
3143               if (!st->rotate_st.timestamp)
3144                 {  /* Now scan touched-devices list and find other finger */
3145                    EINA_LIST_FOREACH(wd->touched, l, p)
3146                      {  /* Device of other finger <> pe device */
3147                         if (p->device != pe->device)
3148                           break;
3149                      }
3150
3151                    if (!p)
3152                         return;  /* Single finger on touch */
3153
3154                    /* Record down fingers */
3155                    consume_event(wd, event_info, event_type, ev_flag);
3156                    memcpy(&st->rotate_st, pe, sizeof(Pointer_Event));
3157                    memcpy(&st->rotate_st1, p, sizeof(Pointer_Event));
3158
3159                    /* Set mv field as well to be ready for MOVE events  */
3160                    memcpy(&st->rotate_mv, pe, sizeof(Pointer_Event));
3161                    memcpy(&st->rotate_mv1, p, sizeof(Pointer_Event));
3162
3163                    /* Here we have rotate_st, rotate_st1 set, report START  */
3164                    /* Set rotate-base after BOTH down events  recorded    */
3165                    /* Compute length of line between fingers rotate start */
3166                    _get_rotate_properties(st,
3167                          st->rotate_st.x, st->rotate_st.y,
3168                          st->rotate_st1.x, st->rotate_st1.y,
3169                          &st->info.base_angle);
3170
3171                    ev_flag = _set_state(gesture, ELM_GESTURE_STATE_START,
3172                          &st->info, EINA_FALSE);
3173                    consume_event(wd, event_info, event_type, ev_flag);
3174
3175                    return;  /* Rotate started */
3176                 }  /* End of ROTATE_START handling */
3177
3178
3179               /* if we got here, we have (exacally) two fingers on surfce */
3180               /* we also after START, report MOVE */
3181               /* First detect which finger moved  */
3182               if (pe->device == st->rotate_mv.device)
3183                 memcpy(&st->rotate_mv, pe, sizeof(Pointer_Event));
3184               else if (pe->device == st->rotate_mv1.device)
3185                 memcpy(&st->rotate_mv1, pe, sizeof(Pointer_Event));
3186
3187               /* Compute change in rotate as fingers move */
3188               _get_rotate_properties(st,
3189                     st->rotate_mv.x, st->rotate_mv.y,
3190                     st->rotate_mv1.x, st->rotate_mv1.y,
3191                     &st->info.angle);
3192
3193               if (rotation_broke_tolerance(st))
3194                 {  /* Rotation broke tolerance, report move */
3195                    double d = st->info.angle - st->next_step;
3196 <<<<<<< HEAD
3197                    if (d < 0.0)
3198 =======
3199                    if (d < 0)
3200 >>>>>>> remotes/origin/upstream
3201                      d = (-d);
3202
3203                    if (d >= wd->rotate_step)
3204                      {  /* Report move in steps */
3205                         st->next_step = st->info.angle;
3206
3207                         ev_flag = _set_state(gesture,
3208                               ELM_GESTURE_STATE_MOVE, &st->info, EINA_TRUE);
3209                         consume_event(wd, event_info, event_type, ev_flag);
3210                      }
3211                 }  /* End of ROTATE_MOVE handling */
3212
3213               return;
3214            }
3215
3216       case EVAS_CALLBACK_MOUSE_UP:
3217       case EVAS_CALLBACK_MULTI_UP:
3218            consume_event(wd, event_info, event_type, ev_flag);
3219            /* Reset timestamp of finger-up.This is used later
3220               by rotate_test_reset() to retain finger-down data */
3221            if (st->rotate_angular_tolerance < 0)
3222              {
3223                 ev_flag = _set_state(gesture, ELM_GESTURE_STATE_END,
3224                       &st->info, EINA_FALSE);
3225                 consume_event(wd, event_info, event_type, ev_flag);
3226
3227                 return;
3228              }
3229
3230            if (gesture->state != ELM_GESTURE_STATE_UNDEFINED)
3231              {  /* Must be != undefined, if gesture started */
3232                 ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
3233                       &st->info, EINA_FALSE);
3234                 consume_event(wd, event_info, event_type, ev_flag);
3235              }
3236
3237            _rotate_test_reset(gesture);
3238            return;
3239
3240       default:
3241          return;
3242        }
3243 }
3244
3245 /**
3246  * @internal
3247  *
3248  * This function is used to save input events in an abstract struct
3249  * to be used later by getsure-testing functions.
3250  *
3251  * @param data The gesture-layer object.
3252  * @param event_info Pointer to recent input event.
3253  * @param event_type Recent input event type.
3254  * @param pe The abstract data-struct (output).
3255  *
3256  * @ingroup Elm_Gesture_Layer
3257  */
3258 static Eina_Bool
3259 _make_pointer_event(void *data, void *event_info,
3260       Evas_Callback_Type event_type, Pointer_Event *pe)
3261 {
3262    Widget_Data *wd = elm_widget_data_get(data);
3263    if (!wd) return EINA_FALSE;
3264
3265    memset(pe, '\0', sizeof(*pe));
3266    switch (event_type)
3267      {
3268       case EVAS_CALLBACK_MOUSE_DOWN:
3269            pe->x = ((Evas_Event_Mouse_Down *) event_info)->canvas.x;
3270            pe->y = ((Evas_Event_Mouse_Down *) event_info)->canvas.y;
3271            pe->timestamp = ((Evas_Event_Mouse_Down *) event_info)->timestamp;
3272            pe->device = ELM_MOUSE_DEVICE;
3273            break;
3274
3275       case EVAS_CALLBACK_MOUSE_UP:
3276            pe->x = ((Evas_Event_Mouse_Up *) event_info)->canvas.x;
3277            pe->y = ((Evas_Event_Mouse_Up *) event_info)->canvas.y;
3278            pe->timestamp = ((Evas_Event_Mouse_Up *) event_info)->timestamp;
3279            pe->device = ELM_MOUSE_DEVICE;
3280            break;
3281
3282       case EVAS_CALLBACK_MOUSE_MOVE:
3283            pe->x = ((Evas_Event_Mouse_Move *) event_info)->cur.canvas.x;
3284            pe->y = ((Evas_Event_Mouse_Move *) event_info)->cur.canvas.y;
3285            pe->timestamp = ((Evas_Event_Mouse_Move *) event_info)->timestamp;
3286            pe->device = ELM_MOUSE_DEVICE;
3287            break;
3288
3289       case EVAS_CALLBACK_MULTI_DOWN:
3290            pe->x = ((Evas_Event_Multi_Down *) event_info)->canvas.x;
3291            pe->y = ((Evas_Event_Multi_Down *) event_info)->canvas.y;
3292            pe->timestamp = ((Evas_Event_Multi_Down *) event_info)->timestamp;
3293            pe->device = ((Evas_Event_Multi_Down *) event_info)->device;
3294            break;
3295
3296       case EVAS_CALLBACK_MULTI_UP:
3297            pe->x = ((Evas_Event_Multi_Up *) event_info)->canvas.x;
3298            pe->y = ((Evas_Event_Multi_Up *) event_info)->canvas.y;
3299            pe->timestamp = ((Evas_Event_Multi_Up *) event_info)->timestamp;
3300            pe->device = ((Evas_Event_Multi_Up *) event_info)->device;
3301            break;
3302
3303       case EVAS_CALLBACK_MULTI_MOVE:
3304            pe->x = ((Evas_Event_Multi_Move *) event_info)->cur.canvas.x;
3305            pe->y = ((Evas_Event_Multi_Move *) event_info)->cur.canvas.y;
3306            pe->timestamp = ((Evas_Event_Multi_Move *) event_info)->timestamp;
3307            pe->device = ((Evas_Event_Multi_Move *) event_info)->device;
3308            break;
3309
3310       default:
3311            return EINA_FALSE;
3312      }
3313
3314    pe->event_type = event_type;
3315    return EINA_TRUE;
3316 }
3317
3318 /**
3319  * @internal
3320  *
3321  * This function restartes line, flick, zoom and rotate gestures
3322  * when gesture-layer continues-gestures enabled.
3323  * Example of continues-gesture:
3324  * When doing a line, user stops moving finger but keeps fingers on touch.
3325  * This will cause line-end, then as user continues moving his finger
3326  * it re-starts line gesture.
3327  * When continue mode is disabled, user has to lift finger from touch
3328  * to end a gesture. Them touch-again to start a new one.
3329  *
3330  * @param data The gesture-layer object.
3331  * @param wd gesture layer widget data.
3332  * @param states_reset flag that marks gestures were reset in history clear.
3333  *
3334  * @ingroup Elm_Gesture_Layer
3335  */
3336 <<<<<<< HEAD
3337 void continues_gestures_restart(void *data, Eina_Bool states_reset)
3338 =======
3339 static void
3340 continues_gestures_restart(void *data, Eina_Bool states_reset)
3341 >>>>>>> remotes/origin/upstream
3342 {
3343    Widget_Data *wd = elm_widget_data_get(data);
3344    if (!wd) return;
3345
3346    /* Run through events to restart gestures */
3347    Gesture_Info *g;
3348    Eina_Bool n_momentum, n_lines, n_flicks, zoom, rotate;
3349    /* We turn-on flag for finished, aborted, not-started gestures */
3350    g = wd->gesture[ELM_GESTURE_MOMENTUM];
3351    n_momentum = (g) ? ((states_reset) | ((g->state != ELM_GESTURE_STATE_START)
3352          && (g->state != ELM_GESTURE_STATE_MOVE))) : EINA_FALSE;
3353    if (n_momentum)
3354      {
3355         _momentum_test_reset(wd->gesture[ELM_GESTURE_MOMENTUM]);
3356         _set_state(g, ELM_GESTURE_STATE_UNDEFINED, NULL, EINA_FALSE);
3357         SET_TEST_BIT(g);
3358      }
3359
3360    g = wd->gesture[ELM_GESTURE_N_LINES];
3361    n_lines = (g) ? ((states_reset) | ((g->state != ELM_GESTURE_STATE_START)
3362          && (g->state != ELM_GESTURE_STATE_MOVE))) : EINA_FALSE;
3363    if (n_lines)
3364      {
3365         _line_test_reset(wd->gesture[ELM_GESTURE_N_LINES]);
3366         _set_state(g, ELM_GESTURE_STATE_UNDEFINED, NULL, EINA_FALSE);
3367         SET_TEST_BIT(g);
3368      }
3369
3370    g = wd->gesture[ELM_GESTURE_N_FLICKS];
3371    n_flicks = (g) ? ((states_reset) | ((g->state != ELM_GESTURE_STATE_START)
3372          && (g->state != ELM_GESTURE_STATE_MOVE))) : EINA_FALSE;
3373    if (n_flicks)
3374      {
3375         _line_test_reset(wd->gesture[ELM_GESTURE_N_FLICKS]);
3376         _set_state(g, ELM_GESTURE_STATE_UNDEFINED, NULL, EINA_FALSE);
3377         SET_TEST_BIT(g);
3378      }
3379
3380    g = wd->gesture[ELM_GESTURE_ZOOM];
3381    zoom = (g) ? ((states_reset) | ((g->state != ELM_GESTURE_STATE_START)
3382          && (g->state != ELM_GESTURE_STATE_MOVE))) : EINA_FALSE;
3383    if (zoom)
3384      {
3385         _zoom_test_reset(wd->gesture[ELM_GESTURE_ZOOM]);
3386         _set_state(g, ELM_GESTURE_STATE_UNDEFINED, NULL, EINA_FALSE);
3387         SET_TEST_BIT(g);
3388      }
3389
3390    g = wd->gesture[ELM_GESTURE_ROTATE];
3391    rotate = (g) ? ((states_reset) | ((g->state != ELM_GESTURE_STATE_START)
3392          && (g->state != ELM_GESTURE_STATE_MOVE))) : EINA_FALSE;
3393    if (rotate)
3394      {
3395         _rotate_test_reset(wd->gesture[ELM_GESTURE_ROTATE]);
3396         _set_state(g, ELM_GESTURE_STATE_UNDEFINED, NULL, EINA_FALSE);
3397         SET_TEST_BIT(g);
3398      }
3399 }
3400
3401 /**
3402  * @internal
3403  *
3404  * This function the core-function where input handling is done.
3405  * Here we get user input and stream it to gesture testing.
3406  * We notify user about any gestures with new state:
3407  * Valid states are:
3408  * START - gesture started.
3409  * MOVE - gesture is ongoing.
3410  * END - gesture was completed.
3411  * ABORT - gesture was aborted after START, MOVE (will NOT be completed)
3412  *
3413  * We also check if a gesture was detected, then reset event history
3414  * If no gestures were found we reset gesture test flag
3415  * after streaming event-history to widget.
3416  * (stream to the widget all events not consumed as a gesture)
3417  *
3418  * @param data The gesture-layer object.
3419  * @param event_info Pointer to recent input event.
3420  * @param event_type Recent input event type.
3421  *
3422  * @ingroup Elm_Gesture_Layer
3423  */
3424 static void
3425 _event_process(void *data, Evas_Object *obj __UNUSED__,
3426       void *event_info, Evas_Callback_Type event_type)
3427 {
3428    Pointer_Event _pe;
3429    Pointer_Event *pe = NULL;
3430    Widget_Data *wd = elm_widget_data_get(data);
3431 <<<<<<< HEAD
3432    if (!wd) return;
3433 =======
3434 >>>>>>> remotes/origin/upstream
3435
3436 #if defined(DEBUG_GESTURE_LAYER)
3437    int i;
3438    Gesture_Info *g;
3439    printf("Gesture | State | is tested\n");
3440    for(i = ELM_GESTURE_N_TAPS; i < ELM_GESTURE_LAST; i++)
3441      {
3442         g = wd->gesture[i];
3443         if(g)
3444           printf("   %d       %d       %d\n", i, g->state, g->test);
3445      }
3446 #endif
3447
3448    /* Start testing candidate gesture from here */
3449    if (_make_pointer_event(data, event_info, event_type, &_pe))
3450      pe = &_pe;
3451
3452    if (IS_TESTED(ELM_GESTURE_N_LONG_TAPS))
3453      _n_long_tap_test(data, pe, event_info, event_type,
3454            ELM_GESTURE_N_LONG_TAPS);
3455
3456    /* This takes care of single, double and tripple tap */
3457    _tap_gestures_test(data, pe, event_info, event_type);
3458
3459    if (IS_TESTED(ELM_GESTURE_MOMENTUM))
3460      _momentum_test(data, pe, event_info, event_type,
3461            ELM_GESTURE_MOMENTUM);
3462
3463    if (IS_TESTED(ELM_GESTURE_N_LINES))
3464      _n_line_test(data, pe, event_info, event_type, ELM_GESTURE_N_LINES);
3465
3466    if (IS_TESTED(ELM_GESTURE_N_FLICKS))
3467      _n_line_test(data, pe, event_info, event_type, ELM_GESTURE_N_FLICKS);
3468
3469    if (_elm_config->glayer_zoom_finger_enable && IS_TESTED(ELM_GESTURE_ZOOM))
3470      _zoom_test(data, pe, event_info, event_type, ELM_GESTURE_ZOOM);
3471
3472    if (IS_TESTED(ELM_GESTURE_ZOOM))
3473      _zoom_with_wheel_test(data, event_info, event_type, ELM_GESTURE_ZOOM);
3474
3475    if (_elm_config->glayer_rotate_finger_enable && IS_TESTED(ELM_GESTURE_ROTATE))
3476      _rotate_test(data, pe, event_info, event_type, ELM_GESTURE_ROTATE);
3477
3478    if (_get_event_flag(event_info, event_type) & EVAS_EVENT_FLAG_ON_HOLD)
3479      _event_history_add(data, event_info, event_type);
3480    else if ((event_type == EVAS_CALLBACK_MOUSE_UP) ||
3481          (event_type == EVAS_CALLBACK_MULTI_UP))
3482      {
3483         Eina_List *pending = _device_is_pending(wd->pending, event_info, event_type);
3484         if (pending)
3485           {
3486              consume_event(wd, event_info, event_type, EVAS_EVENT_FLAG_ON_HOLD);
3487              _event_history_add(data, event_info, event_type);
3488           }
3489      }
3490
3491    /* we maintain list of touched devices              */
3492    /* We also use move to track current device x.y pos */
3493    if ((event_type == EVAS_CALLBACK_MOUSE_DOWN) ||
3494          (event_type == EVAS_CALLBACK_MULTI_DOWN) ||
3495          (event_type == EVAS_CALLBACK_MOUSE_MOVE) ||
3496          (event_type == EVAS_CALLBACK_MULTI_MOVE))
3497      {
3498         wd->touched = _add_touched_device(wd->touched, pe);
3499      }
3500    else if ((event_type == EVAS_CALLBACK_MOUSE_UP) ||
3501          (event_type == EVAS_CALLBACK_MULTI_UP))
3502      {
3503         wd->touched = _remove_touched_device(wd->touched, pe);
3504      }
3505
3506    /* Report current states and clear history if needed */
3507    Eina_Bool states_reset = _clear_if_finished(data);
3508    if (wd->glayer_continues_enable)
3509      continues_gestures_restart(data, states_reset);
3510 }
3511
3512
3513 /**
3514  * For all _mouse_* / multi_* functions wethen send this event to
3515  * _event_process function.
3516  *
3517  * @param data The gesture-layer object.
3518  * @param event_info Pointer to recent input event.
3519  *
3520  * @ingroup Elm_Gesture_Layer
3521  */
3522 static void
3523 _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3524       void *event_info)
3525 {
3526    Widget_Data *wd = elm_widget_data_get(data);
3527    if (!wd) return;
3528    if (((Evas_Event_Mouse_Down *) event_info)->button != 1)
3529      return; /* We only process left-click at the moment */
3530
3531    _event_process(data, obj, event_info, EVAS_CALLBACK_MOUSE_DOWN);
3532 }
3533
3534 static void
3535 _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3536       void *event_info)
3537 {
3538    Widget_Data *wd = elm_widget_data_get(data);
3539    if (!wd) return;
3540
3541    _event_process(data, obj, event_info, EVAS_CALLBACK_MOUSE_MOVE);
3542 }
3543
3544 static void
3545 _key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3546       void *event_info)
3547 {
3548    Widget_Data *wd = elm_widget_data_get(data);
3549    if (!wd) return;
3550
3551    _event_process(data, obj, event_info, EVAS_CALLBACK_KEY_DOWN);
3552 }
3553
3554 static void
3555 _key_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3556       void *event_info)
3557 {
3558    Widget_Data *wd = elm_widget_data_get(data);
3559    if (!wd) return;
3560
3561    _event_process(data, obj, event_info, EVAS_CALLBACK_KEY_UP);
3562 }
3563
3564 static void
3565 _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3566       void *event_info)
3567 {
3568    Widget_Data *wd = elm_widget_data_get(data);
3569    if (!wd) return;
3570
3571    if (((Evas_Event_Mouse_Up *) event_info)->button != 1)
3572      return; /* We only process left-click at the moment */
3573
3574    _event_process(data, obj, event_info, EVAS_CALLBACK_MOUSE_UP);
3575 }
3576
3577 static void
3578 _mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3579       void *event_info)
3580 {
3581    Widget_Data *wd = elm_widget_data_get(data);
3582    if (!wd) return;
3583
3584    _event_process(data, obj, event_info, EVAS_CALLBACK_MOUSE_WHEEL);
3585 }
3586
3587 static void
3588 _multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3589       void *event_info)
3590 {
3591    Widget_Data *wd = elm_widget_data_get(data);
3592    if (!wd) return;
3593
3594    _event_process(data, obj, event_info, EVAS_CALLBACK_MULTI_DOWN);
3595 }
3596
3597 static void
3598 _multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3599       void *event_info)
3600 {
3601    Widget_Data *wd = elm_widget_data_get(data);
3602    if (!wd) return;
3603
3604    _event_process(data, obj, event_info, EVAS_CALLBACK_MULTI_MOVE);
3605 }
3606
3607 static void
3608 _multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
3609       void *event_info)
3610 {
3611    Widget_Data *wd = elm_widget_data_get(data);
3612    if (!wd) return;
3613
3614    _event_process(data, obj, event_info, EVAS_CALLBACK_MULTI_UP);
3615 }
3616
3617 EAPI Eina_Bool
3618 <<<<<<< HEAD
3619 elm_gesture_layer_hold_events_get(Evas_Object *obj)
3620 {
3621 =======
3622 elm_gesture_layer_hold_events_get(const Evas_Object *obj)
3623 {
3624    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3625
3626 >>>>>>> remotes/origin/upstream
3627    Widget_Data *wd = elm_widget_data_get(obj);
3628    if (!wd) return EINA_FALSE;
3629
3630    return !wd->repeat_events;
3631 }
3632
3633 EAPI void
3634 <<<<<<< HEAD
3635 elm_gesture_layer_hold_events_set(Evas_Object *obj, Eina_Bool r)
3636 {
3637    Widget_Data *wd = elm_widget_data_get(obj);
3638    if (!wd) return;
3639
3640    wd->repeat_events = !r;
3641 }
3642
3643 EAPI void
3644 elm_gesture_layer_zoom_step_set(Evas_Object *obj, double s)
3645 {
3646    Widget_Data *wd = elm_widget_data_get(obj);
3647    if (!wd) return;
3648
3649    if (s < 0.0)
3650      return;
3651
3652    wd->zoom_step = s;
3653 }
3654
3655 EAPI void
3656 elm_gesture_layer_rotate_step_set(Evas_Object *obj, double s)
3657 {
3658    Widget_Data *wd = elm_widget_data_get(obj);
3659    if (!wd) return;
3660
3661    if (s < 0.0)
3662      return;
3663
3664    wd->rotate_step = s;
3665 }
3666
3667 EAPI Eina_Bool
3668 elm_gesture_layer_attach(Evas_Object *obj, Evas_Object *t)
3669 {
3670    Widget_Data *wd = elm_widget_data_get(obj);
3671    if (!wd) return EINA_FALSE;
3672
3673    if (!t)
3674      return EINA_FALSE;
3675 =======
3676 elm_gesture_layer_hold_events_set(Evas_Object *obj, Eina_Bool hold_events)
3677 {
3678    ELM_CHECK_WIDTYPE(obj, widtype);
3679
3680    Widget_Data *wd = elm_widget_data_get(obj);
3681    if (!wd) return;
3682
3683    wd->repeat_events = !(!!hold_events);
3684 }
3685
3686 EAPI double
3687 elm_gesture_layer_zoom_step_get(const Evas_Object *obj)
3688 {
3689    ELM_CHECK_WIDTYPE(obj, widtype) 0;
3690
3691    Widget_Data *wd = elm_widget_data_get(obj);
3692    if (!wd) return 0;
3693
3694    return wd->zoom_step;
3695 }
3696
3697 EAPI void
3698 elm_gesture_layer_zoom_step_set(Evas_Object *obj, double step)
3699 {
3700    ELM_CHECK_WIDTYPE(obj, widtype);
3701
3702    Widget_Data *wd = elm_widget_data_get(obj);
3703    if (!wd) return;
3704
3705    if (step < 0) return;
3706
3707    wd->zoom_step = step;
3708 }
3709
3710 EAPI double
3711 elm_gesture_layer_rotate_step_get(const Evas_Object *obj)
3712 {
3713    ELM_CHECK_WIDTYPE(obj, widtype) 0;
3714
3715    Widget_Data *wd = elm_widget_data_get(obj);
3716    if (!wd) return 0;
3717
3718    return wd->rotate_step;
3719 }
3720
3721 EAPI void
3722 elm_gesture_layer_rotate_step_set(Evas_Object *obj, double step)
3723 {
3724    ELM_CHECK_WIDTYPE(obj, widtype);
3725
3726    Widget_Data *wd = elm_widget_data_get(obj);
3727    if (!wd) return;
3728
3729    if (step < 0) return;
3730
3731    wd->rotate_step = step;
3732 }
3733
3734 EAPI Eina_Bool
3735 elm_gesture_layer_attach(Evas_Object *obj, Evas_Object *target)
3736 {
3737    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3738
3739    Widget_Data *wd = elm_widget_data_get(obj);
3740    if (!wd) return EINA_FALSE;
3741
3742    if (!target) return EINA_FALSE;
3743 >>>>>>> remotes/origin/upstream
3744
3745    /* if was attached before, unregister callbacks first */
3746    if (wd->target)
3747      _unregister_callbacks(obj);
3748
3749 <<<<<<< HEAD
3750    wd->target = t;
3751 =======
3752    wd->target = target;
3753 >>>>>>> remotes/origin/upstream
3754
3755    _register_callbacks(obj);
3756    return EINA_TRUE;
3757 }
3758
3759 EAPI void
3760 <<<<<<< HEAD
3761 elm_gesture_layer_cb_set(Evas_Object *obj, Elm_Gesture_Types idx,
3762       Elm_Gesture_State cb_type, Elm_Gesture_Event_Cb cb, void *data)
3763 {
3764 =======
3765 elm_gesture_layer_cb_set(Evas_Object *obj, Elm_Gesture_Type idx,
3766       Elm_Gesture_State cb_type, Elm_Gesture_Event_Cb cb, void *data)
3767 {
3768    ELM_CHECK_WIDTYPE(obj, widtype);
3769
3770 >>>>>>> remotes/origin/upstream
3771    Widget_Data *wd = elm_widget_data_get(obj);
3772    Gesture_Info *p;
3773    if (!wd) return;
3774
3775    if (!wd->gesture[idx])
3776      wd->gesture[idx] = calloc(1, sizeof(Gesture_Info));
3777    if (!wd->gesture[idx]) return;
3778
3779    p = wd->gesture[idx];
3780    p->obj = obj;
3781    p->g_type = idx;
3782    p->fn[cb_type].cb = cb;
3783    p->fn[cb_type].user_data = data;
3784    p->state = ELM_GESTURE_STATE_UNDEFINED;
3785    SET_TEST_BIT(p);
3786 }
3787
3788 static void
3789 _disable_hook(Evas_Object *obj)
3790 {
3791    if (elm_widget_disabled_get(obj))
3792      _unregister_callbacks(obj);
3793    else
3794      _register_callbacks(obj);
3795 }
3796
3797 EAPI Evas_Object *
3798 elm_gesture_layer_add(Evas_Object *parent)
3799 {
3800    Evas_Object *obj;
3801    Evas *e;
3802    Widget_Data *wd;
3803
3804    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3805
3806    ELM_SET_WIDTYPE(widtype, "gesture_layer");
3807    elm_widget_type_set(obj, "gesture_layer");
3808    elm_widget_sub_object_add(parent, obj);
3809    elm_widget_data_set(obj, wd);
3810    elm_widget_del_hook_set(obj, _del_hook);
3811    elm_widget_disable_hook_set(obj, _disable_hook);
3812
3813    wd->target = NULL;
3814 <<<<<<< HEAD
3815    wd->line_min_length =_elm_config->glayer_line_min_length * elm_finger_size_get();
3816    wd->zoom_distance_tolerance = _elm_config->glayer_zoom_distance_tolerance * elm_finger_size_get();
3817    wd->line_distance_tolerance = _elm_config->glayer_line_distance_tolerance * elm_finger_size_get();
3818 =======
3819    wd->line_min_length =_elm_config->glayer_line_min_length * _elm_config->finger_size;
3820    wd->zoom_distance_tolerance = _elm_config->glayer_zoom_distance_tolerance * _elm_config->finger_size;
3821    wd->line_distance_tolerance = _elm_config->glayer_line_distance_tolerance * _elm_config->finger_size;
3822 >>>>>>> remotes/origin/upstream
3823    wd->zoom_finger_factor = _elm_config->glayer_zoom_finger_factor;
3824    wd->zoom_wheel_factor = _elm_config->glayer_zoom_wheel_factor; /* mouse wheel zoom steps */
3825    wd->rotate_angular_tolerance = _elm_config->glayer_rotate_angular_tolerance;
3826    wd->line_angular_tolerance = _elm_config->glayer_line_angular_tolerance;
3827    wd->flick_time_limit_ms = _elm_config->glayer_flick_time_limit_ms;
3828    wd->long_tap_start_timeout = _elm_config->glayer_long_tap_start_timeout;
3829    wd->repeat_events = EINA_TRUE;
3830    wd->glayer_continues_enable = _elm_config->glayer_continues_enable;
3831
3832 #if defined(DEBUG_GESTURE_LAYER)
3833    printf("size of Gestures = <%d>\n", sizeof(wd->gesture));
3834    printf("initial values:\n\tzoom_finger_factor=<%f>\n\tzoom_distance_tolerance=<%d>\n\tline_min_length=<%d>\n\tline_distance_tolerance=<%d>\n\tzoom_wheel_factor=<%f>\n\trotate_angular_tolerance=<%f>\n\twd->line_angular_tolerance=<%f>\n\twd->flick_time_limit_ms=<%d>\n\twd->long_tap_start_timeout=<%f>\n\twd->zoom_step=<%f>\n\twd->rotate_step=<%f>\n\twd->glayer_continues_enable=<%d>\n ", wd->zoom_finger_factor, wd->zoom_distance_tolerance, wd->line_min_length, wd->line_distance_tolerance, wd->zoom_wheel_factor, wd->rotate_angular_tolerance, wd->line_angular_tolerance, wd->flick_time_limit_ms, wd->long_tap_start_timeout, wd->zoom_step, wd->rotate_step, wd->glayer_continues_enable);
3835 #endif
3836    memset(wd->gesture, 0, sizeof(wd->gesture));
3837
3838    return obj;
3839 }