mobile-lua: add additional LABELLED_BY relation
[profile/tv/apps/native/screen-reader.git] / src / screen_reader_gestures.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "screen_reader_gestures.h"
18 #include "logger.h"
19
20 #include <Ecore.h>
21 #include <Ecore_Input.h>
22 #ifdef X11_ENABLED
23 #include <Ecore_X.h>
24 #else
25 #include <Ecore_Wayland.h>
26 #endif
27
28 static GestureCB _global_cb;
29 static void *_global_data;
30
31 #ifdef X11_ENABLED
32 static Ecore_X_Window win;
33 #else
34 static Ecore_Wl_Window *win;
35 #endif
36
37 static Ecore_Event_Handler *property_changed_hld;
38
39 struct _Gestures_Config {
40         // minimal required length of flick gesture (in pixels)
41         int one_finger_flick_min_length;
42         // maximal time of gesture
43         int one_finger_flick_max_time;
44         // timeout period to activate hover gesture (first longpress timeout)
45         double one_finger_hover_longpress_timeout;
46         // to activate flick gesture by 2 fingers (it is hotfix - gestures need serious refactoring)
47         int two_finger_flick_to_scroll_timeout;
48         // after mowing this pixels flick two finger flick to scroll gesture is started
49         int two_finger_flick_to_scroll_min_length;
50         // tap timeout - maximal ammount of time allowed between seqiential taps
51         double one_finger_tap_timeout;
52         // tap radius(in pixels)
53         int one_finger_tap_radius;
54 };
55 typedef struct _Gestures_Config Gestures_Config;
56
57 typedef enum {
58         FLICK_DIRECTION_UNDEFINED,
59         FLICK_DIRECTION_DOWN,
60         FLICK_DIRECTION_UP,
61         FLICK_DIRECTION_LEFT,
62         FLICK_DIRECTION_RIGHT,
63         FLICK_DIRECTION_DOWN_RETURN,
64         FLICK_DIRECTION_UP_RETURN,
65         FLICK_DIRECTION_LEFT_RETURN,
66         FLICK_DIRECTION_RIGHT_RETURN,
67 } flick_direction_e;
68
69 typedef enum {
70         GESTURE_NOT_STARTED = 0,        // Gesture is ready to start
71         GESTURE_ONGOING,                        // Gesture in progress.
72         GESTURE_FINISHED,                       // Gesture finished - should be emited
73         GESTURE_ABORTED                         // Gesture aborted
74 } gesture_state_e;
75
76 typedef enum {
77         ONE_FINGER_GESTURE = 1,
78         TWO_FINGERS_GESTURE,
79         THREE_FINGERS_GESTURE
80 } gesture_type_e;
81
82 struct _Cover {
83 #ifdef X11_ENABLED
84         Ecore_X_Window win;      /**< Input window covering given zone */
85 #else
86         Ecore_Wl_Window *win;    /**< Input window covering given zone */
87 #endif
88         unsigned int n_taps;   /**< Number of fingers touching screen */
89         unsigned int event_time;
90
91         struct {
92                 gesture_state_e state;  // current state of gesture
93                 unsigned int timestamp[3];      // time of gesture;
94                 int finger[3];                  // finger number which initiates gesture
95                 int x_org[3], y_org[3]; // coorinates of finger down event
96                 int x_end[3], y_end[3]; // coorinates of finger up event
97                 flick_direction_e dir;  // direction of flick
98                 int n_fingers;                  // number of fingers in gesture
99                 int n_fingers_left;             // number of fingers in gesture
100                 //         still touching screen
101                 Eina_Bool finger_out[3];        // finger is out of the finger boundary
102                 Eina_Bool return_flick[3];
103                 Eina_Bool flick_to_scroll;
104                 int flick_to_scroll_last_x;
105                 int flick_to_scroll_last_y;
106         } flick_gesture;
107
108         struct {
109                 gesture_state_e state;  // currest gesture state
110                 int x[2], y[2];
111                 int n_fingers;
112                 int finger[2];
113                 unsigned int timestamp; // time of gesture;
114                 unsigned int last_emission_time;        // last time of gesture emission
115                 Ecore_Timer *timer;
116                 Eina_Bool longpressed;
117         } hover_gesture;
118
119         struct {
120                 Eina_Bool started;              // indicates if taps recognition process has started
121                 Eina_Bool pressed;              // indicates if finger is down
122                 int n_taps;                             // number of taps captures in sequence
123                 int finger[3];                  // device id of finget
124                 Ecore_Timer *timer;             // sequence expiration timer
125                 int x_org[3], y_org[3]; // coordinates of first tap
126                 gesture_type_e tap_type;
127         } tap_gesture_data;
128 };
129 typedef struct _Cover Cover;
130
131 Gestures_Config *_e_mod_config;
132 #ifdef X11_ENABLED
133 static Ecore_X_Window scrolled_win;
134 static int rx, ry;
135 #endif
136 static Eina_List *handlers;
137 static Cover *cov;
138 static int win_angle;
139
140 static void _hover_event_emit(Cover * cov, int state);
141 static unsigned int _win_angle_get(void);
142
143 void __transform_coordinates(int *ax, int *ay)
144 {
145         int w;
146         int h;
147         int tmp;
148 #ifdef X11_ENABLED
149         ecore_x_window_geometry_get(ecore_x_window_root_first_get(), NULL, NULL, &w, &h);
150 #else
151         ecore_wl_screen_size_get(&w, &h);
152 #endif
153
154         win_angle = _win_angle_get();
155
156         switch (win_angle) {
157         case 90:
158                 tmp = *ax;
159                 *ax = h - *ay;
160                 *ay = tmp;
161                 break;
162         case 270:
163
164                 tmp = *ax;
165                 *ax = *ay;
166                 *ay = w - tmp;
167                 break;
168         }
169 }
170
171 static void _event_emit(Gesture g, int x, int y, int x_e, int y_e, int state, int event_time)
172 {
173         Gesture_Info *info = calloc(sizeof(Gesture_Info), 1);
174         EINA_SAFETY_ON_NULL_RETURN(info);
175
176         __transform_coordinates(&x, &y);
177         __transform_coordinates(&x_e, &y_e);
178
179         info->type = g;
180         info->x_beg = x;
181         info->x_end = x_e;
182         info->y_beg = y;
183         info->y_end = y_e;
184         info->state = state;
185         info->event_time = event_time;
186
187         if (_global_cb)
188                 _global_cb(_global_data, info);
189         free(info);
190 }
191
192 static void _flick_gesture_mouse_down(Ecore_Event_Mouse_Button * ev, Cover * cov)
193 {
194         if (cov->flick_gesture.state == GESTURE_NOT_STARTED) {
195                 cov->flick_gesture.state = GESTURE_ONGOING;
196                 cov->flick_gesture.finger[0] = ev->multi.device;
197                 cov->flick_gesture.x_org[0] = ev->root.x;
198                 cov->flick_gesture.y_org[0] = ev->root.y;
199                 cov->flick_gesture.timestamp[0] = ev->timestamp;
200                 cov->flick_gesture.flick_to_scroll = EINA_FALSE;
201                 cov->flick_gesture.n_fingers = 1;
202                 cov->flick_gesture.n_fingers_left = 1;
203                 cov->flick_gesture.dir = FLICK_DIRECTION_UNDEFINED;
204                 cov->flick_gesture.finger_out[0] = EINA_FALSE;
205                 cov->flick_gesture.return_flick[0] = EINA_FALSE;
206         } else if (cov->flick_gesture.state == GESTURE_ONGOING) {
207                 // abort gesture if too many fingers touched screen
208                 if ((cov->n_taps > 3) || (cov->flick_gesture.n_fingers > 2)) {
209                         cov->flick_gesture.state = GESTURE_ABORTED;
210                         return;
211                 }
212
213                 cov->flick_gesture.x_org[cov->flick_gesture.n_fingers] = ev->root.x;
214                 cov->flick_gesture.y_org[cov->flick_gesture.n_fingers] = ev->root.y;
215                 cov->flick_gesture.timestamp[cov->flick_gesture.n_fingers] = ev->timestamp;
216                 cov->flick_gesture.finger[cov->flick_gesture.n_fingers] = ev->multi.device;
217                 cov->flick_gesture.n_fingers++;
218                 cov->flick_gesture.n_fingers_left++;
219                 if (cov->flick_gesture.n_fingers < 3) { /* n_fingers == 3 makes out of bounds write */
220                         cov->flick_gesture.finger_out[cov->flick_gesture.n_fingers] = EINA_FALSE;
221                         cov->flick_gesture.return_flick[cov->flick_gesture.n_fingers] = EINA_FALSE;
222                 }
223         }
224 }
225
226 static Eina_Bool _flick_gesture_time_check(unsigned int event_time, unsigned int gesture_time)
227 {
228         DEBUG("Flick time: %d", event_time - gesture_time);
229         if ((event_time - gesture_time) < _e_mod_config->one_finger_flick_max_time * 2) //Double time because of the possible of return flick
230                 return EINA_TRUE;
231         else
232                 return EINA_FALSE;
233 }
234
235 static Eina_Bool _flick_gesture_length_check(int x, int y, int x_org, int y_org)
236 {
237         int dx = x - x_org;
238         int dy = y - y_org;
239
240         if ((dx * dx + dy * dy) > (_e_mod_config->one_finger_flick_min_length * _e_mod_config->one_finger_flick_min_length))
241                 return EINA_TRUE;
242         else
243                 return EINA_FALSE;
244 }
245
246 static flick_direction_e _flick_gesture_direction_get(int x, int y, int x_org, int y_org)
247 {
248         int dx = x - x_org;
249         int dy = y - y_org;
250         int tmp;
251
252         switch (win_angle) {
253         case 90:
254                 tmp = dx;
255                 dx = -dy;
256                 dy = tmp;
257                 break;
258         case 270:
259                 tmp = dx;
260                 dx = dy;
261                 dy = -tmp;
262                 break;
263         }
264
265         if ((dy < 0) && (abs(dx) < -dy))
266                 return FLICK_DIRECTION_UP;
267         if ((dy > 0) && (abs(dx) < dy))
268                 return FLICK_DIRECTION_DOWN;
269         if ((dx > 0) && (dx > abs(dy)))
270                 return FLICK_DIRECTION_RIGHT;
271         if ((dx < 0) && (-dx > abs(dy)))
272                 return FLICK_DIRECTION_LEFT;
273
274         return FLICK_DIRECTION_UNDEFINED;
275 }
276
277 static void _flick_event_emit(Cover * cov)
278 {
279         int ax, ay, axe, aye, i, type = -1;
280         ax = ay = axe = aye = 0;
281
282         for (i = 0; i < cov->flick_gesture.n_fingers; i++) {
283                 ax += cov->flick_gesture.x_org[i];
284                 ay += cov->flick_gesture.y_org[i];
285                 axe += cov->flick_gesture.x_end[i];
286                 aye += cov->flick_gesture.y_end[i];
287         }
288
289         ax /= cov->flick_gesture.n_fingers;
290         ay /= cov->flick_gesture.n_fingers;
291         axe /= cov->flick_gesture.n_fingers;
292         aye /= cov->flick_gesture.n_fingers;
293
294         if (cov->flick_gesture.dir == FLICK_DIRECTION_LEFT) {
295                 if (cov->flick_gesture.n_fingers == 1)
296                         type = ONE_FINGER_FLICK_LEFT;
297                 if (cov->flick_gesture.n_fingers == 2)
298                         type = TWO_FINGERS_FLICK_LEFT;
299                 if (cov->flick_gesture.n_fingers == 3)
300                         type = THREE_FINGERS_FLICK_LEFT;
301         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_RIGHT) {
302                 if (cov->flick_gesture.n_fingers == 1)
303                         type = ONE_FINGER_FLICK_RIGHT;
304                 if (cov->flick_gesture.n_fingers == 2)
305                         type = TWO_FINGERS_FLICK_RIGHT;
306                 if (cov->flick_gesture.n_fingers == 3)
307                         type = THREE_FINGERS_FLICK_RIGHT;
308         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_UP) {
309                 if (cov->flick_gesture.n_fingers == 1)
310                         type = ONE_FINGER_FLICK_UP;
311                 if (cov->flick_gesture.n_fingers == 2)
312                         type = TWO_FINGERS_FLICK_UP;
313                 if (cov->flick_gesture.n_fingers == 3)
314                         type = THREE_FINGERS_FLICK_UP;
315         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_DOWN) {
316                 if (cov->flick_gesture.n_fingers == 1)
317                         type = ONE_FINGER_FLICK_DOWN;
318                 if (cov->flick_gesture.n_fingers == 2)
319                         type = TWO_FINGERS_FLICK_DOWN;
320                 if (cov->flick_gesture.n_fingers == 3)
321                         type = THREE_FINGERS_FLICK_DOWN;
322         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_DOWN_RETURN) {
323                 if (cov->flick_gesture.n_fingers == 1)
324                         type = ONE_FINGER_FLICK_DOWN_RETURN;
325                 if (cov->flick_gesture.n_fingers == 2)
326                         type = TWO_FINGERS_FLICK_DOWN_RETURN;
327                 if (cov->flick_gesture.n_fingers == 3)
328                         type = THREE_FINGERS_FLICK_DOWN_RETURN;
329         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_UP_RETURN) {
330                 if (cov->flick_gesture.n_fingers == 1)
331                         type = ONE_FINGER_FLICK_UP_RETURN;
332                 if (cov->flick_gesture.n_fingers == 2)
333                         type = TWO_FINGERS_FLICK_UP_RETURN;
334                 if (cov->flick_gesture.n_fingers == 3)
335                         type = THREE_FINGERS_FLICK_UP_RETURN;
336         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_LEFT_RETURN) {
337                 if (cov->flick_gesture.n_fingers == 1)
338                         type = ONE_FINGER_FLICK_LEFT_RETURN;
339                 if (cov->flick_gesture.n_fingers == 2)
340                         type = TWO_FINGERS_FLICK_LEFT_RETURN;
341                 if (cov->flick_gesture.n_fingers == 3)
342                         type = THREE_FINGERS_FLICK_LEFT_RETURN;
343         } else if (cov->flick_gesture.dir == FLICK_DIRECTION_RIGHT_RETURN) {
344                 if (cov->flick_gesture.n_fingers == 1)
345                         type = ONE_FINGER_FLICK_RIGHT_RETURN;
346                 if (cov->flick_gesture.n_fingers == 2)
347                         type = TWO_FINGERS_FLICK_RIGHT_RETURN;
348                 if (cov->flick_gesture.n_fingers == 3)
349                         type = THREE_FINGERS_FLICK_RIGHT_RETURN;
350         }
351         DEBUG("FLICK GESTURE: N: %d F: %d", cov->flick_gesture.n_fingers, cov->flick_gesture.dir);
352         _event_emit(type, ax, ay, axe, aye, 2, cov->event_time);
353 }
354
355 static void _flick_gesture_mouse_up(Ecore_Event_Mouse_Button * ev, Cover * cov)
356 {
357         if (cov->flick_gesture.state == GESTURE_ONGOING) {
358                 int i;
359                 // check if fingers match
360                 for (i = 0; i < cov->flick_gesture.n_fingers; i++) {
361                         if (cov->flick_gesture.finger[i] == ev->multi.device)
362                                 break;
363                 }
364                 if (i == cov->flick_gesture.n_fingers) {
365                         DEBUG("Finger id not recognized. Gesture aborted.");
366                         cov->flick_gesture.state = GESTURE_ABORTED;
367                         goto end;
368                 }
369                 if (cov->flick_gesture.flick_to_scroll)
370                 {
371                         if (ev->multi.device == 1) {
372                                 //if it is second finger then update x and y,
373                                 //We use last x and y coordinates in end_scroll.
374                                 //So if the first finger is up before
375                                 //the second one we will use latest x and y of second finger
376                                 //because second was the finger that scroll follows.
377                                 //Else we can encounter that delta between last continue_scroll
378                                 //coordinates and end_scroll coordinates will be high.
379                                 cov->flick_gesture.flick_to_scroll_last_x = ev->x;
380                                 cov->flick_gesture.flick_to_scroll_last_y = ev->y;
381                         }
382
383                         DEBUG("Flick gesture was interpreted as scroll so we aborting it.");
384                         cov->flick_gesture.state = GESTURE_ABORTED;
385                         goto end;
386                 }
387                 // check if flick for given finger is valid
388                 if (!_flick_gesture_time_check(ev->timestamp, cov->flick_gesture.timestamp[i])) {
389                         DEBUG("finger flick gesture timeout expired. Gesture aborted.");
390                         cov->flick_gesture.state = GESTURE_ABORTED;
391                         goto end;
392                 }
393                 // check minimal flick length
394                 if (!_flick_gesture_length_check(ev->root.x, ev->root.y, cov->flick_gesture.x_org[i], cov->flick_gesture.y_org[i])) {
395                         if (!cov->flick_gesture.finger_out[i]) {
396                                 DEBUG("Minimal gesture length not reached and no return flick. Gesture aborted.");
397                                 cov->flick_gesture.state = GESTURE_ABORTED;
398                                 goto end;
399                         }
400                         cov->flick_gesture.return_flick[i] = EINA_TRUE;
401                 }
402
403                 flick_direction_e s = cov->flick_gesture.return_flick[i] ? cov->flick_gesture.dir : _flick_gesture_direction_get(ev->root.x, ev->root.y,
404                                                                                                                                                                                                                                                  cov->flick_gesture.x_org[i],
405                                                                                                                                                                                                                                                  cov->flick_gesture.y_org[i]);
406
407                 cov->flick_gesture.n_fingers_left--;
408
409                 if ((cov->flick_gesture.dir == FLICK_DIRECTION_UNDEFINED || cov->flick_gesture.dir > FLICK_DIRECTION_RIGHT)
410                         && cov->flick_gesture.return_flick[i] == EINA_FALSE) {
411                         DEBUG("Flick gesture");
412                         cov->flick_gesture.dir = s;
413                 }
414                 // gesture is valid only if all flicks are in same direction
415                 if (cov->flick_gesture.dir != s) {
416                         DEBUG("Flick in different direction. Gesture aborted.");
417                         cov->flick_gesture.state = GESTURE_ABORTED;
418                         goto end;
419                 }
420
421                 cov->flick_gesture.x_end[i] = ev->root.x;
422                 cov->flick_gesture.y_end[i] = ev->root.y;
423
424                 if (!cov->flick_gesture.n_fingers_left) {
425                         _flick_event_emit(cov);
426                         cov->flick_gesture.state = GESTURE_NOT_STARTED;
427                 }
428         }
429
430  end:
431         // if no finger is touching a screen, gesture will be reseted.
432         if (cov->flick_gesture.state == GESTURE_ABORTED) {
433                 if (cov->flick_gesture.flick_to_scroll) {
434                         end_scroll(cov->flick_gesture.flick_to_scroll_last_x, cov->flick_gesture.flick_to_scroll_last_y);
435                         cov->flick_gesture.flick_to_scroll = EINA_FALSE;
436                 }
437                 if (cov->n_taps == 0)
438                         cov->flick_gesture.state = GESTURE_NOT_STARTED;
439         }
440 }
441
442 static Eina_Bool _flick_to_scroll_gesture_conditions_met(Ecore_Event_Mouse_Move * ev, int gesture_timestamp, int dx, int dy)
443 {
444         if (ev->timestamp - gesture_timestamp > _e_mod_config->two_finger_flick_to_scroll_timeout)
445                 if (abs(dx) > _e_mod_config->two_finger_flick_to_scroll_min_length || abs(dy) > _e_mod_config->two_finger_flick_to_scroll_min_length)
446                         return EINA_TRUE;
447
448         return EINA_FALSE;
449 }
450
451 static void _flick_gesture_mouse_move(Ecore_Event_Mouse_Move * ev, Cover * cov)
452 {
453         if (cov->flick_gesture.state == GESTURE_ONGOING) {
454                 int i;
455                 for (i = 0; i < cov->flick_gesture.n_fingers; ++i) {
456                         if (cov->flick_gesture.finger[i] == ev->multi.device)
457                                 break;
458                 }
459                 if (i == cov->flick_gesture.n_fingers) {
460                         if (cov->flick_gesture.n_fingers >= 3)  //that is because of the EFL bug. Mouse move event before mouse down(!)
461                         {
462                                 ERROR("Finger id not recognized. Gesture aborted.");
463                                 cov->flick_gesture.state = GESTURE_ABORTED;
464                                 return;
465                         }
466                 }
467
468                 int dx = ev->root.x - cov->flick_gesture.x_org[i];
469                 int dy = ev->root.y - cov->flick_gesture.y_org[i];
470                 int tmp;
471
472                 switch (win_angle) {
473                 case 90:
474                         tmp = dx;
475                         dx = -dy;
476                         dy = tmp;
477                         break;
478                 case 270:
479                         tmp = dx;
480                         dx = dy;
481                         dy = -tmp;
482                         break;
483                 }
484                 if (i == 1) {
485                         if (cov->flick_gesture.flick_to_scroll || _flick_to_scroll_gesture_conditions_met(ev, cov->flick_gesture.timestamp[i], dx, dy)) {
486                                 if (!cov->flick_gesture.flick_to_scroll) {
487                                         start_scroll(ev->x, ev->y);
488                                         cov->flick_gesture.flick_to_scroll = EINA_TRUE;
489                                 } else {
490                                         continue_scroll(ev->x, ev->y);
491                                 }
492                                 cov->flick_gesture.flick_to_scroll_last_x = ev->x;
493                                 cov->flick_gesture.flick_to_scroll_last_y = ev->y;
494                                 return;
495                         }
496                 }
497
498                 if (!cov->flick_gesture.finger_out[i]) {
499                         if (abs(dx) > _e_mod_config->one_finger_flick_min_length) {
500                                 cov->flick_gesture.finger_out[i] = EINA_TRUE;
501                                 if (dx > 0) {
502                                         if (cov->flick_gesture.dir == FLICK_DIRECTION_UNDEFINED || cov->flick_gesture.dir == FLICK_DIRECTION_RIGHT_RETURN) {
503                                                 cov->flick_gesture.dir = FLICK_DIRECTION_RIGHT_RETURN;
504                                         } else {
505                                                 ERROR("Invalid direction, abort");
506                                                 cov->flick_gesture.state = GESTURE_ABORTED;
507                                         }
508                                 } else {
509                                         if (cov->flick_gesture.dir == FLICK_DIRECTION_UNDEFINED || cov->flick_gesture.dir == FLICK_DIRECTION_LEFT_RETURN) {
510                                                 cov->flick_gesture.dir = FLICK_DIRECTION_LEFT_RETURN;
511                                         } else {
512                                                 ERROR("Invalid direction, abort");
513                                                 cov->flick_gesture.state = GESTURE_ABORTED;
514                                         }
515                                 }
516                                 return;
517                         }
518
519                         else if (abs(dy) > _e_mod_config->one_finger_flick_min_length) {
520                                 cov->flick_gesture.finger_out[i] = EINA_TRUE;
521                                 if (dy > 0) {
522                                         if (cov->flick_gesture.dir == FLICK_DIRECTION_UNDEFINED || cov->flick_gesture.dir == FLICK_DIRECTION_DOWN_RETURN) {
523                                                 cov->flick_gesture.dir = FLICK_DIRECTION_DOWN_RETURN;
524                                         } else {
525                                                 ERROR("Invalid direction, abort");
526                                                 cov->flick_gesture.state = GESTURE_ABORTED;
527                                         }
528                                 } else {
529                                         if (cov->flick_gesture.dir == FLICK_DIRECTION_UNDEFINED || cov->flick_gesture.dir == FLICK_DIRECTION_UP_RETURN) {
530                                                 cov->flick_gesture.dir = FLICK_DIRECTION_UP_RETURN;
531                                         } else {
532                                                 ERROR("Invalid direction, abort");
533                                                 cov->flick_gesture.state = GESTURE_ABORTED;
534                                         }
535                                 }
536                                 return;
537                         }
538                 }
539         }
540         return;
541 }
542
543 static Eina_Bool _on_hover_timeout(void *data)
544 {
545         Cover *cov = data;
546         DEBUG("Hover timer expierd");
547
548         cov->hover_gesture.longpressed = EINA_TRUE;
549         cov->hover_gesture.timer = NULL;
550
551         if (cov->hover_gesture.last_emission_time == -1) {
552                 _hover_event_emit(cov, 0);
553                 cov->hover_gesture.last_emission_time = cov->event_time;
554         }
555         return EINA_FALSE;
556 }
557
558 static void _hover_gesture_timer_reset(Cover * cov, double time)
559 {
560         DEBUG("Hover timer reset");
561         cov->hover_gesture.longpressed = EINA_FALSE;
562         if (cov->hover_gesture.timer) {
563                 ecore_timer_reset(cov->hover_gesture.timer);
564                 return;
565         }
566         cov->hover_gesture.timer = ecore_timer_add(time, _on_hover_timeout, cov);
567 }
568
569 static void _hover_gesture_mouse_down(Ecore_Event_Mouse_Button * ev, Cover * cov)
570 {
571         if (cov->hover_gesture.state == GESTURE_NOT_STARTED && cov->n_taps == 1) {
572                 cov->hover_gesture.state = GESTURE_ONGOING;
573                 cov->hover_gesture.timestamp = ev->timestamp;
574                 cov->hover_gesture.last_emission_time = -1;
575                 cov->hover_gesture.x[0] = ev->root.x;
576                 cov->hover_gesture.y[0] = ev->root.y;
577                 cov->hover_gesture.finger[0] = ev->multi.device;
578                 cov->hover_gesture.n_fingers = 1;
579                 _hover_gesture_timer_reset(cov, _e_mod_config->one_finger_hover_longpress_timeout);
580         }
581         if (cov->hover_gesture.state == GESTURE_ONGOING && cov->n_taps == 2) {
582                 if (cov->hover_gesture.longpressed) {
583                         _hover_event_emit(cov, 2);
584                         goto abort;
585                 }
586                 cov->hover_gesture.timestamp = -1;
587                 cov->hover_gesture.last_emission_time = -1;
588                 cov->hover_gesture.x[1] = ev->root.x;
589                 cov->hover_gesture.y[1] = ev->root.y;
590                 cov->hover_gesture.finger[1] = ev->multi.device;
591                 cov->hover_gesture.n_fingers = 2;
592                 _hover_gesture_timer_reset(cov, _e_mod_config->one_finger_hover_longpress_timeout);
593         }
594         // abort gesture if more then 2 fingers touched screen
595         if ((cov->hover_gesture.state == GESTURE_ONGOING) && cov->n_taps > 2) {
596                 DEBUG("More then 2 finged. Abort hover gesture");
597                 _hover_event_emit(cov, 2);
598                 goto abort;
599         }
600         return;
601
602  abort:
603         cov->hover_gesture.state = GESTURE_ABORTED;
604         if (cov->hover_gesture.timer)
605                 ecore_timer_del(cov->hover_gesture.timer);
606         cov->hover_gesture.timer = NULL;
607 }
608
609 static void _hover_gesture_mouse_up(Ecore_Event_Mouse_Button * ev, Cover * cov)
610 {
611         int i;
612         if (cov->hover_gesture.state == GESTURE_ONGOING) {
613
614                 for (i = 0; i < cov->hover_gesture.n_fingers; i++) {
615                         if (cov->hover_gesture.finger[i] == ev->multi.device)
616                                 break;
617                 }
618                 if (i == cov->hover_gesture.n_fingers) {
619                         DEBUG("Invalid finger id: %d", ev->multi.device);
620                         return;
621                 } else {
622                         cov->hover_gesture.state = GESTURE_ABORTED;
623                         if (cov->hover_gesture.timer)
624                                 ecore_timer_del(cov->hover_gesture.timer);
625                         cov->hover_gesture.timer = NULL;
626                         // aditionally emit event to complete sequence
627                         if (cov->hover_gesture.longpressed)
628                                 _hover_event_emit(cov, 2);
629                 }
630         }
631         // reset gesture only if user released all his fingers
632         if (cov->n_taps == 0)
633                 cov->hover_gesture.state = GESTURE_NOT_STARTED;
634 }
635 #ifdef X11_ENABLED
636 static void _get_root_coords(Ecore_X_Window win, int *x, int *y)
637 {
638         Ecore_X_Window root = ecore_x_window_root_first_get();
639         Ecore_X_Window parent = ecore_x_window_parent_get(win);
640         int wx, wy;
641
642         if (x)
643                 *x = 0;
644         if (y)
645                 *y = 0;
646
647         while (parent && (root != parent)) {
648                 ecore_x_window_geometry_get(parent, &wx, &wy, NULL, NULL);
649                 if (x)
650                         *x += wx;
651                 if (y)
652                         *y += wy;
653                 parent = ecore_x_window_parent_get(parent);
654         }
655 }
656
657 Ecore_X_Window top_window_get(int x, int y)
658 {
659         Ecore_X_Window wins[1] = { win };
660         Ecore_X_Window under = ecore_x_window_at_xy_with_skip_get(x, y, wins, sizeof(wins) / sizeof(wins[0]));
661         if (under) {
662                 _get_root_coords(under, &rx, &ry);
663                 DEBUG("Recieved window with coords:%d %d", rx, ry);
664                 return under;
665         }
666         return 0;
667 }
668 #else
669 Ecore_Wl_Window *top_window_get(int x, int y)
670 {
671         return 0;
672 }
673 #endif
674
675
676 void start_scroll(int x, int y)
677 {
678 #ifdef X11_ENABLED
679         Ecore_X_Window wins[1] = { win };
680         Ecore_X_Window under = ecore_x_window_at_xy_with_skip_get(x, y, wins, sizeof(wins) / sizeof(wins[0]));
681         _get_root_coords(under, &rx, &ry);
682         ecore_x_mouse_in_send(under, x - rx, y - ry);
683         ecore_x_window_focus(under);
684         ecore_x_mouse_down_send(under, x - rx, y - ry, 1);
685         scrolled_win = under;
686 #endif
687 }
688
689 void continue_scroll(int x, int y)
690 {
691 #ifdef X11_ENABLED
692         ecore_x_mouse_move_send(scrolled_win, x - rx, y - ry);
693 #endif
694 }
695
696 void end_scroll(int x, int y)
697 {
698 #ifdef X11_ENABLED
699         ecore_x_mouse_up_send(scrolled_win, x - rx, y - ry, 1); 
700         ecore_x_mouse_out_send(scrolled_win, x - rx, y - ry);
701 #endif
702 }
703
704 static unsigned int _win_angle_get(void)
705 {
706         int angle = 0;
707 #ifdef X11_ENABLED
708         Ecore_X_Window root, first_root;
709         int ret;
710         int count;
711         unsigned char *prop_data = NULL;
712
713         first_root = ecore_x_window_root_first_get();
714         root = ecore_x_window_root_get(first_root);
715         ret = ecore_x_window_prop_property_get(root, ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE, ECORE_X_ATOM_CARDINAL, 32, &prop_data, &count);
716
717         if (ret && prop_data)
718                 memcpy(&angle, prop_data, sizeof(int));
719
720         if (prop_data)
721                 free(prop_data);
722 #else
723
724 #endif
725         return angle;
726 }
727
728 static void _hover_event_emit(Cover * cov, int state)
729 {
730         int ax = 0, ay = 0, j;
731
732         for (j = 0; j < cov->hover_gesture.n_fingers; j++) {
733                 ax += cov->hover_gesture.x[j];
734                 ay += cov->hover_gesture.y[j];
735         }
736
737         ax /= cov->hover_gesture.n_fingers;
738         ay /= cov->hover_gesture.n_fingers;
739
740         switch (cov->hover_gesture.n_fingers) {
741         case 1:
742                 INFO("ONE FINGER HOVER");
743                 _event_emit(ONE_FINGER_HOVER, ax, ay, ax, ay, state, cov->event_time);
744                 break;
745         default:
746                 break;
747         }
748 }
749
750 static void _hover_gesture_mouse_move(Ecore_Event_Mouse_Move * ev, Cover * cov)
751 {
752         if (cov->hover_gesture.state == GESTURE_ONGOING) {
753                 // check fingers
754                 int i;
755                 if (!cov->hover_gesture.longpressed)
756                         return;
757
758                 for (i = 0; i < cov->hover_gesture.n_fingers; i++) {
759                         if (cov->hover_gesture.finger[i] == ev->multi.device)
760                                 break;
761                 }
762                 if (i == cov->hover_gesture.n_fingers) {
763                         DEBUG("Invalid finger id: %d", ev->multi.device);
764                         return;
765                 }
766                 cov->hover_gesture.x[i] = ev->root.x;
767                 cov->hover_gesture.y[i] = ev->root.y;
768                 _hover_event_emit(cov, 1);
769         }
770 }
771
772 static void _tap_event_emit(Cover * cov, int state)
773 {
774         switch (cov->tap_gesture_data.n_taps) {
775         case 1:
776                 if (cov->tap_gesture_data.tap_type == ONE_FINGER_GESTURE) {
777                         DEBUG("ONE_FINGER_SINGLE_TAP");
778                         _event_emit(ONE_FINGER_SINGLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], state, cov->event_time);
779                 } else if (cov->tap_gesture_data.tap_type == TWO_FINGERS_GESTURE) {
780                         DEBUG("TWO_FINGERS_SINGLE_TAP");
781                         _event_emit(TWO_FINGERS_SINGLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[1], cov->tap_gesture_data.y_org[1], state, cov->event_time);
782                 } else if (cov->tap_gesture_data.tap_type == THREE_FINGERS_GESTURE) {
783                         DEBUG("THREE_FINGERS_SINGLE_TAP");
784                         _event_emit(THREE_FINGERS_SINGLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[2], cov->tap_gesture_data.y_org[2], state, cov->event_time);
785                 } else {
786                         ERROR("Unknown tap");
787                 }
788                 break;
789         case 2:
790                 if (cov->tap_gesture_data.tap_type == ONE_FINGER_GESTURE) {
791                         DEBUG("ONE_FINGER_DOUBLE_TAP");
792                         _event_emit(ONE_FINGER_DOUBLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], state, cov->event_time);
793                 } else if (cov->tap_gesture_data.tap_type == TWO_FINGERS_GESTURE) {
794                         DEBUG("TWO_FINGERS_DOUBLE_TAP");
795                         _event_emit(TWO_FINGERS_DOUBLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[1], cov->tap_gesture_data.y_org[1], state, cov->event_time);
796                 } else if (cov->tap_gesture_data.tap_type == THREE_FINGERS_GESTURE) {
797                         DEBUG("THREE_FINGERS_DOUBLE_TAP");
798                         _event_emit(THREE_FINGERS_DOUBLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[2], cov->tap_gesture_data.y_org[2], state, cov->event_time);
799                 } else {
800                         ERROR("Unknown tap");
801                 }
802                 break;
803         case 3:
804                 if (cov->tap_gesture_data.tap_type == ONE_FINGER_GESTURE) {
805                         DEBUG("ONE_FINGER_TRIPLE_TAP");
806                         _event_emit(ONE_FINGER_TRIPLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], state, cov->event_time);
807                 } else if (cov->tap_gesture_data.tap_type == TWO_FINGERS_GESTURE) {
808                         DEBUG("TWO_FINGERS_TRIPLE_TAP");
809                         _event_emit(TWO_FINGERS_TRIPLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[1], cov->tap_gesture_data.y_org[1], state, cov->event_time);
810                 } else if (cov->tap_gesture_data.tap_type == THREE_FINGERS_GESTURE) {
811                         DEBUG("THREE_FINGERS_TRIPLE_TAP");
812                         _event_emit(THREE_FINGERS_TRIPLE_TAP, cov->tap_gesture_data.x_org[0], cov->tap_gesture_data.y_org[0], cov->tap_gesture_data.x_org[2], cov->tap_gesture_data.y_org[2], state, cov->event_time);
813                 } else {
814                         ERROR("Unknown tap");
815                 }
816                 break;
817         default:
818                 ERROR("Unknown tap");
819                 break;
820         }
821 }
822
823 static Eina_Bool _on_tap_timer_expire(void *data)
824 {
825         Cover *cov = data;
826         DEBUG("Timer expired");
827
828         if (cov->tap_gesture_data.started && !cov->tap_gesture_data.pressed)
829                 _tap_event_emit(cov, 2);
830         else
831                 _tap_event_emit(cov, 3);
832
833         // finish gesture
834         cov->tap_gesture_data.started = EINA_FALSE;
835         cov->tap_gesture_data.timer = NULL;
836         cov->tap_gesture_data.tap_type = ONE_FINGER_GESTURE;
837         cov->tap_gesture_data.finger[0] = -1;
838         cov->tap_gesture_data.finger[1] = -1;
839         cov->tap_gesture_data.finger[2] = -1;
840
841         return EINA_FALSE;
842 }
843
844 static int _tap_gesture_finger_check(Cover * cov, int x, int y)
845 {
846         int dx = x - cov->tap_gesture_data.x_org[0];
847         int dy = y - cov->tap_gesture_data.y_org[0];
848
849         if (cov->tap_gesture_data.finger[0] != -1 && (dx * dx + dy * dy < _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius)) {
850                 return 0;
851         }
852
853         dx = x - cov->tap_gesture_data.x_org[1];
854         dy = y - cov->tap_gesture_data.y_org[1];
855         if (cov->tap_gesture_data.finger[1] != -1 && (dx * dx + dy * dy < _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius)) {
856                 return 1;
857         }
858
859         dx = x - cov->tap_gesture_data.x_org[2];
860         dy = y - cov->tap_gesture_data.y_org[2];
861         if (cov->tap_gesture_data.finger[2] != -1 && (dx * dx + dy * dy < _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius)) {
862                 return 2;
863         }
864
865         return -1;
866 }
867
868 static void _tap_gestures_mouse_down(Ecore_Event_Mouse_Button * ev, Cover * cov)
869 {
870         if (cov->n_taps > 4) {
871                 ERROR("Too many fingers");
872                 return;
873         }
874
875         cov->tap_gesture_data.pressed = EINA_TRUE;
876
877         if (cov->tap_gesture_data.started == EINA_FALSE) {
878                 DEBUG("First finger down");
879                 cov->tap_gesture_data.started = EINA_TRUE;
880                 cov->tap_gesture_data.finger[0] = ev->multi.device;
881                 cov->tap_gesture_data.x_org[0] = ev->root.x;
882                 cov->tap_gesture_data.y_org[0] = ev->root.y;
883                 cov->tap_gesture_data.finger[1] = -1;
884                 cov->tap_gesture_data.finger[2] = -1;
885                 cov->tap_gesture_data.n_taps = 0;
886                 cov->tap_gesture_data.timer = ecore_timer_add(_e_mod_config->one_finger_tap_timeout, _on_tap_timer_expire, cov);
887                 cov->tap_gesture_data.tap_type = ONE_FINGER_GESTURE;
888         }
889
890         else {
891                 if (ev->multi.device == cov->tap_gesture_data.finger[0]) {
892                         DEBUG("First finger down");
893
894                         if (_tap_gesture_finger_check(cov, ev->root.x, ev->root.y) == -1) {
895                                 ERROR("Abort gesture");
896                                 cov->tap_gesture_data.started = EINA_FALSE;
897                                 ecore_timer_del(cov->tap_gesture_data.timer);
898                                 cov->tap_gesture_data.timer = NULL;
899                                 cov->tap_gesture_data.tap_type = ONE_FINGER_GESTURE;
900                                 cov->tap_gesture_data.finger[0] = -1;
901                                 cov->tap_gesture_data.finger[1] = -1;
902                                 cov->tap_gesture_data.finger[2] = -1;
903                                 _tap_gestures_mouse_down(ev, cov);
904                                 return;
905                         }
906
907                         cov->tap_gesture_data.x_org[0] = ev->root.x;
908                         cov->tap_gesture_data.y_org[0] = ev->root.y;
909                 } else if (cov->tap_gesture_data.finger[1] == -1 || cov->tap_gesture_data.finger[1] == ev->multi.device) {
910                         DEBUG("Second finger down");
911                         cov->tap_gesture_data.finger[1] = ev->multi.device;
912
913                         cov->tap_gesture_data.x_org[1] = ev->root.x;
914                         cov->tap_gesture_data.y_org[1] = ev->root.y;
915                         if (cov->tap_gesture_data.tap_type < TWO_FINGERS_GESTURE)
916                                 cov->tap_gesture_data.tap_type = TWO_FINGERS_GESTURE;
917                 } else if (cov->tap_gesture_data.finger[2] == -1 || cov->tap_gesture_data.finger[2] == ev->multi.device) {
918                         DEBUG("Third finger down");
919                         cov->tap_gesture_data.finger[2] = ev->multi.device;
920
921                         cov->tap_gesture_data.x_org[2] = ev->root.x;
922                         cov->tap_gesture_data.y_org[2] = ev->root.y;
923                         if (cov->tap_gesture_data.tap_type < THREE_FINGERS_GESTURE)
924                                 cov->tap_gesture_data.tap_type = THREE_FINGERS_GESTURE;
925                 } else {
926                         ERROR("Unknown finger down");
927                 }
928                 ecore_timer_reset(cov->tap_gesture_data.timer);
929         }
930 }
931
932 static void _tap_gestures_mouse_up(Ecore_Event_Mouse_Button * ev, Cover * cov)
933 {
934         if (cov->tap_gesture_data.timer) {
935                 cov->tap_gesture_data.pressed = EINA_FALSE;
936
937                 if (ev->multi.device == cov->tap_gesture_data.finger[0]) {
938                         DEBUG("First finger up");
939
940                         int dx = ev->root.x - cov->tap_gesture_data.x_org[0];
941                         int dy = ev->root.y - cov->tap_gesture_data.y_org[0];
942
943                         if ((dx * dx + dy * dy) < _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius) {
944                                 if (cov->n_taps == 0) {
945                                         cov->tap_gesture_data.n_taps++;
946                                 }
947                         } else {
948                                 ERROR("Abort gesture");
949                                 cov->tap_gesture_data.started = EINA_FALSE;
950                         }
951                 } else if (ev->multi.device == cov->tap_gesture_data.finger[1]) {
952                         DEBUG("Second finger up");
953
954                         int dx = ev->root.x - cov->tap_gesture_data.x_org[1];
955                         int dy = ev->root.y - cov->tap_gesture_data.y_org[1];
956
957                         if ((dx * dx + dy * dy) < _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius) {
958                                 if (cov->n_taps == 0) {
959                                         cov->tap_gesture_data.n_taps++;
960                                 }
961                         } else {
962                                 ERROR("Abort gesture");
963                                 cov->tap_gesture_data.started = EINA_FALSE;
964                         }
965                 } else if (ev->multi.device == cov->tap_gesture_data.finger[2]) {
966                         DEBUG("Third finger up");
967
968                         int dx = ev->root.x - cov->tap_gesture_data.x_org[2];
969                         int dy = ev->root.y - cov->tap_gesture_data.y_org[2];
970
971                         if ((dx * dx + dy * dy) < _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius) {
972                                 if (cov->n_taps == 0) {
973                                         cov->tap_gesture_data.n_taps++;
974                                 }
975                         } else {
976                                 ERROR("Abort gesture");
977                                 cov->tap_gesture_data.started = EINA_FALSE;
978                         }
979                 } else {
980                         ERROR("Unknown finger up, abort gesture");
981                         cov->tap_gesture_data.started = EINA_FALSE;
982                 }
983         }
984 }
985
986 static void _tap_gestures_move(Ecore_Event_Mouse_Move * ev, Cover * cov)
987 {
988         int i;
989         for (i = 0; i < sizeof(cov->tap_gesture_data.finger) / sizeof(cov->tap_gesture_data.finger[0]); i++) {
990                 if (ev->multi.device == cov->tap_gesture_data.finger[i]) {
991                         int dx = ev->root.x - cov->tap_gesture_data.x_org[i];
992                         int dy = ev->root.y - cov->tap_gesture_data.y_org[i];
993
994                         if ((dx * dx + dy * dy) > _e_mod_config->one_finger_tap_radius * _e_mod_config->one_finger_tap_radius) {
995                                 DEBUG("abort tap gesutre");
996                                 cov->tap_gesture_data.started = EINA_FALSE;
997                                 ecore_timer_del(cov->tap_gesture_data.timer);
998                                 cov->tap_gesture_data.timer = NULL;
999                                 cov->tap_gesture_data.tap_type = ONE_FINGER_GESTURE;
1000                                 cov->tap_gesture_data.finger[0] = -1;
1001                                 cov->tap_gesture_data.finger[1] = -1;
1002                                 cov->tap_gesture_data.finger[2] = -1;
1003                         }
1004                         break;
1005                 }
1006         }
1007 }
1008
1009 static Eina_Bool _cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1010 {
1011         Ecore_Event_Mouse_Button *ev = event;
1012
1013         cov->n_taps++;
1014         cov->event_time = ev->timestamp;
1015
1016         DEBUG("mouse down: multi.device: %d, taps: %d", ev->multi.device, cov->n_taps);
1017
1018         win_angle = _win_angle_get();
1019
1020         _flick_gesture_mouse_down(ev, cov);
1021         _hover_gesture_mouse_down(ev, cov);
1022         _tap_gestures_mouse_down(ev, cov);
1023
1024         return ECORE_CALLBACK_PASS_ON;
1025 }
1026
1027 static Eina_Bool _cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1028 {
1029         Ecore_Event_Mouse_Button *ev = event;
1030
1031         cov->n_taps--;
1032         cov->event_time = ev->timestamp;
1033
1034         DEBUG("mouse up, multi.device: %d, taps: %d", ev->multi.device, cov->n_taps);
1035
1036         _flick_gesture_mouse_up(ev, cov);
1037         _hover_gesture_mouse_up(ev, cov);
1038         _tap_gestures_mouse_up(ev, cov);
1039
1040         return ECORE_CALLBACK_PASS_ON;
1041 }
1042
1043 static Eina_Bool _cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1044 {
1045         Ecore_Event_Mouse_Move *ev = event;
1046
1047         cov->event_time = ev->timestamp;
1048
1049         _flick_gesture_mouse_move(ev, cov);
1050         _hover_gesture_mouse_move(ev, cov);
1051         _tap_gestures_move(ev, cov);
1052
1053         return ECORE_CALLBACK_PASS_ON;
1054 }
1055
1056 static Eina_Bool _gesture_input_win_create(void)
1057 {
1058         int w, h;
1059
1060         if (!win) {
1061 #ifdef X11_ENABLED
1062                 Ecore_Window root = ecore_x_window_root_first_get();
1063                 if (!root)
1064                         return EINA_FALSE;
1065                 ecore_x_window_geometry_get(root, NULL, NULL, &w, &h);
1066                 win = ecore_x_window_input_new(root, 0, 0, w, h);
1067 #else
1068                 ecore_wl_screen_size_get(&w, &h);
1069                 win = ecore_wl_window_new(NULL, 0, 0, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW);
1070 #endif
1071         }
1072         if (!win)
1073                 return EINA_FALSE;
1074
1075 #ifdef X11_ENABLED
1076         ecore_x_input_multi_select(win);
1077         ecore_x_window_show(win);
1078         ecore_x_window_raise(win);
1079 #else
1080         ecore_wl_window_show(win);
1081         ecore_wl_window_raise(win);
1082 #endif
1083         // restet gestures
1084         memset(cov, 0x0, sizeof(Cover));
1085
1086         return EINA_TRUE;
1087 }
1088 #ifdef X11_ENABLED
1089 static Eina_Bool _win_property_changed(void *data, int type, void *event)
1090 {
1091         Ecore_X_Event_Window_Property *wp = event;
1092
1093         if (wp->atom != ECORE_X_ATOM_NET_CLIENT_LIST_STACKING)
1094                 return EINA_TRUE;
1095
1096         _gesture_input_win_create();
1097
1098         return EINA_TRUE;
1099 }
1100 #endif
1101
1102 static Eina_Bool _gestures_input_window_init(void)
1103 {
1104 #ifdef X11_ENABLED
1105         Ecore_Window root = ecore_x_window_root_first_get();
1106         if (!root) {
1107                 ERROR("No root window found. Is Window manager running?");
1108                 return EINA_FALSE;
1109         }
1110         ecore_x_event_mask_set(root, ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1111         property_changed_hld = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _win_property_changed, NULL);
1112 #endif
1113         return _gesture_input_win_create();
1114 }
1115
1116 static void _gestures_input_widnow_shutdown(void)
1117 {
1118         ecore_event_handler_del(property_changed_hld);
1119         if (win)
1120 #ifdef X11_ENABLED
1121                 ecore_x_window_free(win);
1122 #else
1123                 ecore_wl_window_free(win);
1124 #endif
1125         win = 0;
1126 }
1127
1128 Eina_Bool screen_reader_gestures_init(void)
1129 {
1130         ecore_init();
1131 #ifdef X11_ENABLED
1132         ecore_x_init(NULL);
1133 #else
1134         ecore_wl_init(NULL);
1135 #endif
1136         cov = calloc(sizeof(Cover), 1);
1137
1138         if (!_gestures_input_window_init()) {
1139                 free(cov);
1140                 return EINA_FALSE;
1141         }
1142
1143         _e_mod_config = calloc(sizeof(Gestures_Config), 1);
1144         _e_mod_config->one_finger_flick_min_length = 100;
1145         _e_mod_config->one_finger_flick_max_time = 400;
1146         _e_mod_config->two_finger_flick_to_scroll_timeout = 100;
1147         _e_mod_config->two_finger_flick_to_scroll_min_length = 50;
1148         _e_mod_config->one_finger_hover_longpress_timeout = 0.81;
1149         _e_mod_config->one_finger_tap_timeout = 0.4;
1150         _e_mod_config->one_finger_tap_radius = 100;
1151
1152         handlers = eina_list_append(NULL, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _cb_mouse_move, NULL));
1153         handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _cb_mouse_up, NULL));
1154         handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _cb_mouse_down, NULL));
1155
1156         return EINA_TRUE;
1157 }
1158
1159 void screen_reader_gestures_shutdown(void)
1160 {
1161         Ecore_Event_Handler *hdlr;
1162         EINA_LIST_FREE(handlers, hdlr) {
1163                 ecore_event_handler_del(hdlr);
1164         }
1165         _gestures_input_widnow_shutdown();
1166 #ifdef X11_ENABLED
1167         ecore_x_shutdown();
1168 #else
1169         ecore_wl_shutdown();
1170 #endif
1171         ecore_shutdown();
1172         free(_e_mod_config);
1173         free(cov);
1174 }
1175
1176 void screen_reader_gestures_tracker_register(GestureCB cb, void *data)
1177 {
1178         _global_cb = cb;
1179         _global_data = data;
1180 }