Modified to skip outdated touch events
[platform/core/uifw/libscl-ui.git] / scl / gwes / efl / sclevents-efl.cpp
1 /*
2  * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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
18 #include "sclevents-efl.h"
19 #include "scldebug.h"
20 #include "sclcontroller.h"
21 #include "sclgraphics.h"
22 #include "scluibuilder.h"
23 #include "sclerroradjustment.h"
24 #include "sclresource.h"
25 #include "sclresourcecache.h"
26 #include "sclres_manager.h"
27
28 #include <Elementary.h>
29 #include <dlog.h>
30 #ifdef WAYLAND
31 #include <Ecore_Wayland.h>
32 #else
33 #include <Ecore_X.h>
34 #endif
35
36 #include "sclkeyfocushandler.h"
37
38 using namespace scl;
39
40 #ifdef USING_KEY_GRAB
41 #define HANDLE_KEY_EVENTS
42 #endif
43
44 #define E_PROP_TOUCH_INPUT "X_TouchInput"
45
46 #ifdef WAYLAND
47 #define E_KEYBOARD_SERVICE_BUS_NAME "org.tizen.keyboard"
48 #define E_KEYBOARD_SERVICE_NAVI_IFC_NAME "org.tizen.KBGestureNavigation"
49 #define E_KEYBOARD_SERVICE_NAVI_OBJ_PATH "/org/tizen/KBGestureNavigation"
50 static Eldbus_Connection *eldbus_conn = NULL;
51 typedef enum _Gesture {
52      ONE_FINGER_HOVER = 0,
53      ONE_FINGER_SINGLE_TAP = 15,
54      ONE_FINGER_DOUBLE_TAP = 16
55 } Gesture;
56
57 typedef struct
58 {
59    Gesture type;         // Type of recognized gesture
60    int x;
61    int y;
62 } Gesture_Info;
63 #endif
64
65 static sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */
66 static sclwindow pressed_window = SCLWINDOW_INVALID;
67
68 /* If the gap between two timestamps are bigger than 1 sec, do not compare */
69 const unsigned int _touch_event_timestamp_compare_range = 1000;
70 /* If the gap between two timestamps are smaller than 50 msec, do not process */
71 const unsigned int _touch_event_timestamp_valid_threshold = 50;
72 extern unsigned int g_timestamp_last_base_window_resized;
73
74 #define MIN_XY_DIFF 14
75
76 static Eina_Bool mouse_press(void *data, int type, void *event_info);
77 static Eina_Bool mouse_move(void *data, int type, void *event_info);
78 static Eina_Bool mouse_release(void *data, int type, void *event_info);
79
80 #ifndef WAYLAND
81 static Eina_Bool client_message_cb(void *data, int type, void *event);
82 #endif
83
84 #ifdef HANDLE_KEY_EVENTS
85 static Eina_Bool key_pressed(void *data, int type, void *event_info);
86 #endif
87
88 static sclboolean get_window_rect(const sclwindow window, SclRectangle *rect)
89 {
90     SCL_DEBUG();
91     sclboolean ret = FALSE;
92     CSCLUtils *utils = CSCLUtils::get_instance();
93     CSCLWindows *windows = CSCLWindows::get_instance();
94     CSCLContext *context = CSCLContext::get_instance();
95     if (windows && context && utils && rect) {
96         SclWindowContext *window_context = windows->get_window_context(window);
97         sclint scr_w, scr_h;
98         /* get window size */
99         if (window_context && utils->get_screen_resolution(&scr_w, &scr_h)) {
100             switch (context->get_rotation()) {
101                 case ROTATION_90_CW:
102                     {
103                         rect->height = window_context->geometry.width;
104                         rect->width = window_context->geometry.height;
105                         rect->y = scr_w - rect->height - window_context->geometry.x;
106                         rect->x = window_context->geometry.y;
107                     }
108                     break;
109                 case ROTATION_180:
110                     {
111                         rect->width = window_context->geometry.width;
112                         rect->height = window_context->geometry.height;
113                         rect->x = scr_w - window_context->geometry.x - rect->width;
114                         rect->y = scr_h - window_context->geometry.y - rect->height;
115                     }
116                     break;
117                 case ROTATION_90_CCW:
118                     {
119                         rect->height = window_context->geometry.width;
120                         rect->width = window_context->geometry.height;
121                         rect->y = window_context->geometry.x;
122                         rect->x = scr_h - window_context->geometry.y - rect->width;
123                     }
124                     break;
125                 default:
126                     {
127                         rect->x = window_context->geometry.x;
128                         rect->y = window_context->geometry.y;
129                         rect->width = window_context->geometry.width;
130                         rect->height = window_context->geometry.height;
131                     }
132                     break;
133             }
134             ret = TRUE;
135         } else {
136             rect->x = rect->y = rect->width = rect->height = 0;
137         }
138     }
139     return ret;
140 }
141
142 #ifdef WAYLAND
143 /* In wayland, root.x / root.y is not available, so need to apply virtual offset
144    when event occurred on a virtual window */
145 static void apply_virtual_offset(SclRectangle rect, int *adjustx, int *adjusty)
146 {
147     int virtual_offset_x = 0;
148     int virtual_offset_y = 0;
149     SclRectangle base_rect = {0, 0, 0, 0};
150
151     CSCLWindows *windows = CSCLWindows::get_instance();
152     if (windows) {
153         if (get_window_rect(windows->get_base_window(), &base_rect)) {
154             virtual_offset_x = rect.x - base_rect.x;
155             virtual_offset_y = rect.y - base_rect.y;
156         }
157         if (adjustx && adjusty) {
158             *adjustx -= virtual_offset_x;
159             *adjusty -= virtual_offset_y;
160         }
161     }
162 }
163 #endif
164
165 /**
166  * Constructor
167  */
168 CSCLEventsImplEfl::CSCLEventsImplEfl()
169 {
170     SCL_DEBUG();
171
172     m_mouse_down_handler = NULL;
173     m_mouse_move_handler = NULL;
174     m_mouse_up_handler = NULL;
175
176 #ifndef WAYLAND
177     m_xclient_msg_handler = NULL;
178 #endif
179     m_key_pressed_handler = NULL;
180 }
181
182 #ifdef WAYLAND
183 static void gesture_cb(void *data, const Eldbus_Message *msg)
184 {
185     LOGD("GestureDetected callback");
186     int g_type;
187     static int last_pos_x = -1;
188     static int last_pos_y = -1;
189
190     if (!msg) {
191         LOGD("Incoming message is empty");
192         return;
193     }
194     CSCLController *controller = CSCLController::get_instance();
195     CSCLWindows *windows = CSCLWindows::get_instance();
196
197     if (!windows || !controller) return;
198
199     sclwindow base_window = windows->get_base_window();
200     SclWindowContext *window_context = windows->get_window_context(base_window);
201
202     if (!window_context) return;
203     if (window_context->hidden) return;
204
205     LOGD("window_context->geometry.x=%d y=%d w=%d h=%d",
206             window_context->geometry.x, window_context->geometry.y,
207             window_context->geometry.width, window_context->geometry.height);
208
209     Gesture_Info *info = (Gesture_Info *)calloc(sizeof(Gesture_Info), 1);
210     if (!eldbus_message_arguments_get(msg, "iii", &g_type, &info->x,
211                                       &info->y)) {
212         LOGD("Getting message arguments failed");
213         free(info);
214         return;
215     }
216
217     info->type = (Gesture)g_type;
218     LOGD("Incoming gesture name is %d : %d %d", info->type, info->x, info->y);
219
220     if (info->type == ONE_FINGER_HOVER || info->type == ONE_FINGER_SINGLE_TAP) {
221         if (info->y >= window_context->geometry.y) {
222             last_pos_x = info->x;
223             last_pos_y = info->y - window_context->geometry.y;
224             LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
225             controller->mouse_over(base_window, last_pos_x, last_pos_y);
226         }
227     } else if (info->type == ONE_FINGER_DOUBLE_TAP) {
228         if (info->y >= window_context->geometry.y) {
229             last_pos_x = info->x;
230             last_pos_y = info->y - window_context->geometry.y;
231             LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
232             controller->mouse_press(base_window, last_pos_x, last_pos_y);
233             controller->mouse_release(base_window, last_pos_x, last_pos_y);
234         }
235     }
236     free(info);
237 }
238
239 static void gestures_tracker_register()
240 {
241     Eldbus_Object *obj;
242     Eldbus_Proxy *proxy;
243
244     eldbus_init();
245     LOGD("Registering callback for GestureDetected signal");
246     if (!(eldbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) {
247         LOGD("Error: Unable to get session bus");
248         return;
249     }
250     obj = eldbus_object_get(eldbus_conn, E_KEYBOARD_SERVICE_BUS_NAME, E_KEYBOARD_SERVICE_NAVI_OBJ_PATH);
251     if (!obj) LOGD("Error: Getting object failed");
252
253     proxy = eldbus_proxy_get(obj, E_KEYBOARD_SERVICE_NAVI_IFC_NAME);
254     if (!proxy) LOGD("Error: Getting proxy failed");
255     if (!eldbus_proxy_signal_handler_add(proxy, "KBGestureDetected", gesture_cb, NULL))
256         LOGD("No signal handler returned");
257     LOGD("Callback registration successful");
258     return;
259 }
260
261 static void gestures_tracker_unregister()
262 {
263     if (eldbus_conn) {
264         eldbus_connection_unref(eldbus_conn);
265         eldbus_conn = NULL;
266     }
267
268     eldbus_shutdown();
269 }
270 #endif
271 /**
272  * De-constructor
273  */
274 CSCLEventsImplEfl::~CSCLEventsImplEfl()
275 {
276     SCL_DEBUG();
277
278     fini();
279 }
280
281 void CSCLEventsImplEfl::init()
282 {
283     /* Initializes all window resources */
284     m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL);
285     m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL);
286     m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL);
287
288 #ifndef WAYLAND
289     m_xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, client_message_cb, NULL);
290 #else
291     gestures_tracker_register();
292 #endif
293
294 #ifdef HANDLE_KEY_EVENTS
295     m_key_pressed_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_pressed, NULL);
296 #endif
297 }
298
299 void CSCLEventsImplEfl::fini()
300 {
301     if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler);
302     m_mouse_down_handler = NULL;
303     if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler);
304     m_mouse_move_handler = NULL;
305     if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler);
306     m_mouse_up_handler = NULL;
307 #ifdef HANDLE_KEY_EVENTS
308     if (m_key_pressed_handler) ecore_event_handler_del(m_key_pressed_handler);
309 #endif
310     m_key_pressed_handler = NULL;
311 #ifndef WAYLAND
312     if (m_xclient_msg_handler) ecore_event_handler_del(m_xclient_msg_handler);
313 #else
314     gestures_tracker_unregister();
315 #endif
316 }
317
318 /**  Here x and y contains "actual" x and y position relative to portrait root window,
319      and window_context->width,height contains the window's orientation dependant width and height */
320 SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) {
321     SclPoint ret = {0, 0};
322
323     if (rect) {
324         switch (rotation) {
325             case ROTATION_90_CW:
326                 {
327                     ret.x = (rect->y + rect->width) - y;
328                     ret.y = x - rect->x;
329                 }
330                 break;
331             case ROTATION_180:
332                 {
333                     ret.x = (rect->x + rect->width) - x;
334                     ret.y = (rect->y + rect->height) - y;
335                 }
336                 break;
337             case ROTATION_90_CCW:
338                 {
339                     ret.x = y - rect->y;
340                     ret.y = (rect->x + rect->height) - x;
341                 }
342                 break;
343             default:
344                 {
345                     ret.x = x - rect->x;
346                     ret.y = y - rect->y;
347                 }
348                 break;
349         }
350     }
351     return ret;
352 }
353
354 static Eina_Bool check_timestamp_outdated(unsigned int timestamp)
355 {
356     /* Skip events that were generated nearly at the same time when our base window resized */
357     timestamp -= _touch_event_timestamp_valid_threshold;
358     unsigned int gap = (g_timestamp_last_base_window_resized > timestamp) ?
359         (g_timestamp_last_base_window_resized - timestamp) :
360         (timestamp - g_timestamp_last_base_window_resized);
361     if (gap < _touch_event_timestamp_compare_range) {
362         if (g_timestamp_last_base_window_resized > timestamp) {
363             /* This event was generated before the base window resize event, ignore */
364             LOGD("Skipping event since turned out to be outdated : %u, %u",
365                     g_timestamp_last_base_window_resized, timestamp);
366             return EINA_TRUE;
367         }
368     }
369     return EINA_FALSE;
370 }
371
372 //void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info)
373 static Eina_Bool mouse_press(void *data, int type, void *event_info)
374 {
375     SCL_DEBUG();
376 #ifdef WAYLAND
377     Ecore_Wl_Window *wl_base_window;
378     Ecore_Wl_Window *wl_magnifier_window;
379     Ecore_Wl_Window *wl_window;
380 #endif
381
382     CSCLController *controller = CSCLController::get_instance();
383     CSCLWindows *windows = CSCLWindows::get_instance();
384     CSCLContext *context = CSCLContext::get_instance();
385     CSCLUtils *utils = CSCLUtils::get_instance();
386     CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
387
388     Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
389
390     if (ev && check_timestamp_outdated(ev->timestamp)) {
391         return TRUE;
392     }
393
394     if (controller && windows && context && utils && adjustment && ev) {
395         LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y,
396                 g_timestamp_last_base_window_resized, ev->timestamp);
397
398         sclbyte index = 0;
399         sclboolean processed = FALSE;
400         sclwindow window = SCLWINDOW_INVALID;
401
402 #ifndef WAYLAND
403         Ecore_X_Window inputWindow = 0;
404         Ecore_X_Atom inputAtom = ecore_x_atom_get("DeviceMgr Input Window");
405         ecore_x_window_prop_xid_get(ecore_x_window_root_first_get(),
406             inputAtom, ECORE_X_ATOM_WINDOW, &inputWindow, 1);
407         if (inputWindow == 0) {
408             utils->log("Error : input window NULL!");
409         }
410
411         unsigned int touch_input = 0;
412         int res = ecore_x_window_prop_card32_get(inputWindow,
413             ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1);
414
415         utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input);
416
417         if (1 == res) {
418             if (1 == touch_input) {
419                 adjustment->enable_touch_offset(TRUE);
420             } else if (0 == touch_input) {
421                 adjustment->enable_touch_offset(FALSE);
422             }
423         }
424 #endif
425         sclboolean is_scl_window = FALSE;
426 #ifdef WAYLAND
427         sclboolean is_magnifier_window = FALSE;
428         wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
429         wl_magnifier_window = (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
430         if (wl_base_window && (unsigned int)ecore_wl_window_id_get(wl_base_window) == ev->window) {
431             is_scl_window = TRUE;
432         } else if (wl_magnifier_window && (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
433             is_scl_window = TRUE;
434             is_magnifier_window = TRUE;
435 #else
436         if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window())) == ev->window) {
437             is_scl_window = TRUE;
438         } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_magnifier_window())) == ev->window) {
439             is_scl_window = TRUE;
440 #endif
441         } else {
442             do {
443                 window = windows->get_nth_window_in_Z_order_list(index);
444                 SclWindowContext *window_context = windows->get_window_context(window);
445                 if (window_context) {
446                     if (window_context->is_virtual) {
447                         is_scl_window  = TRUE;
448 #ifdef WAYLAND
449                     } else if ((wl_window = elm_win_wl_window_get(static_cast<Evas_Object*>(window)))) {
450                         if ((unsigned int)ecore_wl_window_id_get(wl_window) == ev->window)
451                             is_scl_window = TRUE;
452 #else
453                     } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(window)) == ev->window) {
454                         is_scl_window = TRUE;
455 #endif
456                     }
457                 }
458                 index++;
459             } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID);
460             index = 0;
461         }
462         if (!is_scl_window) return TRUE;
463
464         SclRectangle rect = {0, 0, 0, 0};
465         do {
466             window = windows->get_nth_window_in_Z_order_list(index);
467             if (window) {
468                 // Update the position of the target window
469                 //windows->get_window_context(window, TRUE);
470                 SclWindowContext *window_context = windows->get_window_context(window);
471                 if (window_context) {
472                     windows->get_window_rect(window, &(window_context->geometry));
473                     if (get_window_rect(window, &rect)) {
474 #ifdef WAYLAND
475                         int root_x = 0;
476                         int root_y = 0;
477                         if (is_magnifier_window) {
478                             SclRectangle magnifier_rect = { 0, 0, 0, 0 };
479                             if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
480                                 root_x = ev->x + magnifier_rect.x;
481                                 root_y = ev->y + magnifier_rect.y;
482                             }
483                         } else {
484                             root_x = ev->x + rect.x;
485                             root_y = ev->y + rect.y;
486                         }
487                         if (window_context->is_virtual) {
488                             apply_virtual_offset(rect, &root_x, &root_y);
489                         }
490 #else
491                         int root_x = ev->root.x;
492                         int root_y = ev->root.y;
493 #endif
494                         int adjust_x = root_x;
495                         int adjust_y = root_y;
496
497                         SclResParserManager *sclres_manager = SclResParserManager::get_instance();
498                         PSclDefaultConfigure default_configure = NULL;
499                         if (sclres_manager) {
500                             default_configure = sclres_manager->get_default_configure();
501                         }
502
503                         if (default_configure) {
504                             SCLDisplayMode display_mode = context->get_display_mode();
505                             if (scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
506                                 adjustment->apply_touch_offset(
507                                         default_configure->touch_offset_level[display_mode],
508                                         &adjust_x, &adjust_y);
509                             }
510                         }
511
512                         sclint win_width = rect.width;
513                         sclint win_height = rect.height;
514                         if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
515                             rect.height = win_width;
516                             rect.width = win_height;
517                         }
518
519                         /* Check whether will-be-adjusted coordinate is within the window area */
520                         sclboolean process_event = FALSE;
521                         if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
522                             (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
523                                 process_event = TRUE;
524                         }
525                         if (process_event) {
526                             /* Now convert the global coordinate to appropriate local coordinate */
527                             SclPoint coords = get_rotated_local_coords(
528                                     root_x, root_y, context->get_rotation(), &rect);
529                             controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
530                             mouse_pressed = TRUE;
531                             processed = TRUE;
532                             pressed_window = window;
533                         }
534                     }
535                 }
536             }
537             index++;
538         } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
539
540         if (!processed) {
541             window = pressed_window;
542             SclWindowContext *window_context = windows->get_window_context(window);
543             if (window_context && get_window_rect(window, &rect)) {
544                 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
545                     sclint temp = rect.width;
546                     rect.width = rect.height;
547                     rect.height = temp;
548                 }
549
550                 // Now convert the global coordinate to appropriate local coordinate
551 #ifdef WAYLAND
552                 int root_x = ev->x + rect.x;
553                 int root_y = ev->y + rect.y;
554                 if (window_context->is_virtual) {
555                     apply_virtual_offset(rect, &root_x, &root_y);
556                 }
557 #else
558                 int root_x = ev->root.x;
559                 int root_y = ev->root.y;
560 #endif
561
562                 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
563                 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
564                 mouse_pressed = TRUE;
565                 processed = TRUE;
566             }
567         }
568     }
569
570     return TRUE;
571
572     /*CSCLContext *context = CSCLContext::get_instance();
573     controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
574     mouse_pressed = TRUE;*/
575
576     //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
577 }
578
579 //void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info)
580 static Eina_Bool mouse_release(void *data, int type, void *event_info)
581 {
582     SCL_DEBUG();
583
584     CSCLController *controller = CSCLController::get_instance();
585     CSCLWindows *windows = CSCLWindows::get_instance();
586     CSCLContext *context = CSCLContext::get_instance();
587
588     //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info;
589     Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
590
591     //if (!mouse_pressed) return FALSE;
592     if (ev && check_timestamp_outdated(ev->timestamp)) {
593         return TRUE;
594     }
595
596     if (controller && windows && context && ev) {
597         LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
598
599         sclbyte index = 0;
600         sclboolean processed = FALSE;
601         sclwindow window = SCLWINDOW_INVALID;
602         SclRectangle rect;
603         sclboolean dimwinevent = FALSE;
604         SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
605         if (dim_window_context) {
606             if (!(dim_window_context->is_virtual)) {
607                 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_dim_window())) == ev->window) {
608                     dimwinevent = TRUE;
609                 }
610             }
611         }
612         if (dimwinevent) {
613             controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
614         } else {
615             do {
616                 window = windows->get_nth_window_in_Z_order_list(index);
617                 if (window) {
618                     SclWindowContext *window_context = windows->get_window_context(window);
619                     if (window_context) {
620                         windows->get_window_rect(window, &(window_context->geometry));
621                         if (get_window_rect(window, &rect)) {
622 #ifdef WAYLAND
623                             int root_x = 0;
624                             int root_y = 0;
625                             Ecore_Wl_Window *wl_magnifier_window =
626                                 (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
627                             if (wl_magnifier_window &&
628                                 (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
629                                 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
630                                 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
631                                     root_x = ev->x + magnifier_rect.x;
632                                     root_y = ev->y + magnifier_rect.y;
633                                 }
634                             } else {
635                                 root_x = ev->x + rect.x;
636                                 root_y = ev->y + rect.y;
637                             }
638                             if (window_context->is_virtual) {
639                                 apply_virtual_offset(rect, &root_x, &root_y);
640                             }
641 #else
642                             int root_x = ev->root.x;
643                             int root_y = ev->root.y;
644 #endif
645                             int adjust_x = root_x;
646                             int adjust_y = root_y;
647
648                             SclResParserManager *sclres_manager = SclResParserManager::get_instance();
649                             PSclDefaultConfigure default_configure = NULL;
650                             if (sclres_manager) {
651                                 default_configure = sclres_manager->get_default_configure();
652                             }
653
654                             if (default_configure) {
655                                 SCLDisplayMode display_mode = context->get_display_mode();
656                                 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
657                                 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
658                                     adjustment->apply_touch_offset(
659                                             default_configure->touch_offset_level[display_mode],
660                                             &adjust_x, &adjust_y);
661                                 }
662                             }
663
664                             sclint win_width = rect.width;
665                             sclint win_height = rect.height;
666                             if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
667                                 rect.height = win_width;
668                                 rect.width = win_height;
669                             }
670
671                             /* Check whether will-be-adjusted coordinate is within the window area */
672                             sclboolean process_event = FALSE;
673                             if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
674                                 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
675                                     process_event = TRUE;
676                             }
677                             if (process_event) {
678                                 /* Now convert the global coordinate to appropriate local coordinate */
679                                 SclPoint coords = get_rotated_local_coords(
680                                         root_x, root_y, context->get_rotation(), &rect);
681                                 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
682                                 processed = TRUE;
683                             }
684                         }
685                     }
686                 }
687                 index++;
688             } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
689         }
690
691         if (!processed) {
692             window = pressed_window;
693             SclWindowContext *window_context = windows->get_window_context(window);
694             if (window_context && get_window_rect(window, &rect)) {
695                 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
696                     sclint temp = rect.width;
697                     rect.width = rect.height;
698                     rect.height = temp;
699                 }
700
701                 /* Now convert the global coordinate to appropriate local coordinate */
702 #ifdef WAYLAND
703                 int root_x = ev->x + rect.x;
704                 int root_y = ev->y + rect.y;
705                 if (window_context->is_virtual) {
706                     apply_virtual_offset(rect, &root_x, &root_y);
707                 }
708 #else
709                 int root_x = ev->root.x;
710                 int root_y = ev->root.y;
711 #endif
712
713                 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
714                 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
715                 processed = TRUE;
716             }
717         }
718
719         mouse_pressed = FALSE;
720     }
721
722     return TRUE;
723     //CSCLController *controller = CSCLController::get_instance();
724     //CSCLWindows *windows = CSCLWindows::get_instance();
725     //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
726     //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
727 }
728
729 #ifdef HANDLE_KEY_EVENTS
730 static Eina_Bool key_pressed(void *data, int type, void *event_info)
731 {
732     LOGD("=-=-=-=- key_pressed \n");
733     CSCLController *controller = CSCLController::get_instance();
734     Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info;
735     const char *ckey_val = ev->key;
736     LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key);
737     LOGD("=-=-=-=- ev->key(string) = %s \n", ev->key);
738     LOGD("=-=-=-=- ev->keyname(char) = %c \n", ev->keyname);
739     LOGD("=-=-=-=- ev->keyname(string) = %s \n", ev->keyname);
740     LOGD("=-=-=-=- ev->string(char) = %c \n", ev->string);
741     LOGD("=-=-=-=- ev->string(string) = %s \n", ev->string);
742
743     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
744     SclButtonContext *prev_button_context = NULL;
745     const SclLayoutKeyCoordinate *prevcoordinate = NULL;
746     SclButtonContext *button_context = NULL;
747     const SclLayoutKeyCoordinate *coordinate = NULL;
748
749     CSCLWindows *windows = CSCLWindows::get_instance();
750     sclwindow window = windows->get_base_window();
751     CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
752
753     sclbyte current_key_index = focus_handler->get_current_key_index();
754     sclbyte key_index = current_key_index;
755
756     if (strcmp(ev->keyname, "Right") == 0) {
757         key_index = focus_handler->get_next_key_index(NAVIGATE_RIGHT);
758     } else if (strcmp(ev->keyname, "Left") == 0) {
759         key_index = focus_handler->get_next_key_index(NAVIGATE_LEFT);
760     } else if (strcmp(ev->keyname, "Up") == 0) {
761         key_index = focus_handler->get_next_key_index(NAVIGATE_UP);
762     } else if (strcmp(ev->keyname, "Down") == 0) {
763         key_index = focus_handler->get_next_key_index(NAVIGATE_DOWN);
764     } else if ((strcmp(ev->keyname, "Return") == 0) || (strcmp(ev->keyname, "Enter") == 0)) {
765         button_context = cache->get_cur_button_context(window, current_key_index);
766         coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
767         button_context->state = BUTTON_STATE_NORMAL;
768         controller->mouse_press(window, coordinate->x, coordinate->y, TRUE);
769         controller->mouse_release(window, coordinate->x, coordinate->y, TRUE);
770         if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
771             button_context->state = BUTTON_STATE_PRESSED;
772             windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
773         } else {
774             focus_handler->init_key_index();
775         }
776         return TRUE;
777     }
778
779     if (current_key_index != key_index) {
780         button_context = cache->get_cur_button_context(window, key_index);
781         prev_button_context = cache->get_cur_button_context(window, current_key_index);
782         prevcoordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
783         coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
784         prev_button_context->state = BUTTON_STATE_NORMAL;
785         button_context->state = BUTTON_STATE_PRESSED;
786         sclshort x, y, width, height;
787         if (prevcoordinate->x < coordinate->x) {
788             x = prevcoordinate->x;
789         } else {
790             x = coordinate->x;
791         }
792
793         if (prevcoordinate->y < coordinate->y) {
794             y = prevcoordinate->y;
795         } else {
796             y = coordinate->y;
797         }
798
799         if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) {
800             width = prevcoordinate->x + prevcoordinate->width - x;
801         } else {
802             width = coordinate->x + coordinate->width - x;
803         }
804
805         if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) {
806             height = prevcoordinate->y + prevcoordinate->height - y;
807         } else {
808             height = coordinate->y + coordinate->height - y;
809         }
810         windows->update_window(window, x, y, width, height);
811
812     } else {
813     }
814
815     return TRUE;
816 }
817 #endif /*HANDLE_KEY_EVENTS*/
818
819 //int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info)
820 static Eina_Bool mouse_move(void *data, int type, void *event_info)
821 {
822     SCL_DEBUG();
823
824     CSCLController *controller = CSCLController::get_instance();
825     CSCLWindows *windows = CSCLWindows::get_instance();
826     CSCLContext *context = CSCLContext::get_instance();
827     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
828
829     //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info;
830     Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info;
831
832     //if (!mouse_pressed) return FALSE;
833     if (ev && check_timestamp_outdated(ev->timestamp)) {
834         return TRUE;
835     }
836
837     if (controller && windows && context && cache && ev) {
838         sclbyte index = 0;
839         sclboolean processed = FALSE;
840         sclwindow window = SCLWINDOW_INVALID;
841         SclRectangle rect;
842
843         LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
844
845         if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID &&
846             get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) {
847             sclint winwidth = rect.width;
848             sclint winheight = rect.height;
849             if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
850                 rect.height = winwidth;
851                 rect.width = winheight;
852             }
853 #ifdef WAYLAND
854             int root_x = 0;
855             int root_y = 0;
856
857             Ecore_Wl_Window *wl_base_window =
858                 elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
859             Ecore_Wl_Window  *wl_magnifier_window =
860                 (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
861             if (wl_base_window && (unsigned int)ecore_wl_window_id_get(wl_base_window) == ev->window) {
862                 SclRectangle base_rect;
863                 get_window_rect(windows->get_base_window(), &base_rect);
864                 root_x = ev->x + base_rect.x;
865                 root_y = ev->y + base_rect.y;
866             } else if (wl_magnifier_window && (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
867                 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
868                 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
869                     root_x = ev->x + magnifier_rect.x;
870                     root_y = ev->y + magnifier_rect.y;
871                 }
872             } else {
873                 root_x = ev->x + rect.x;
874                 root_y = ev->y + rect.y;
875             }
876 #else
877             int root_x = ev->root.x;
878             int root_y = ev->root.y;
879 #endif
880
881             SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
882
883             controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
884             processed = TRUE;
885         } else {
886             do {
887                 window = windows->get_nth_window_in_Z_order_list(index);
888                 if (window) {
889                     SclWindowContext *window_context = windows->get_window_context(window);
890                     if (window_context) {
891                         windows->get_window_rect(window, &(window_context->geometry));
892                         if (get_window_rect(window, &rect)) {
893 #ifdef WAYLAND
894                             int root_x = ev->x + rect.x;
895                             int root_y = ev->y + rect.y;
896                             if (window_context->is_virtual) {
897                                 apply_virtual_offset(rect, &root_x, &root_y);
898                             }
899 #else
900                             int root_x = ev->root.x;
901                             int root_y = ev->root.y;
902 #endif
903                             int adjust_x = root_x;
904                             int adjust_y = root_y;
905
906                             SclResParserManager *sclres_manager = SclResParserManager::get_instance();
907                             PSclDefaultConfigure default_configure = NULL;
908                             if (sclres_manager) {
909                                 default_configure = sclres_manager->get_default_configure();
910                             }
911                             if (default_configure) {
912                                 SCLDisplayMode display_mode = context->get_display_mode();
913                                 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
914                                 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
915                                     adjustment->apply_touch_offset(
916                                             default_configure->touch_offset_level[display_mode],
917                                             &adjust_x, &adjust_y);
918                                 }
919                             }
920
921                             sclint win_width = rect.width;
922                             sclint win_height = rect.height;
923                             if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
924                                 rect.height = win_width;
925                                 rect.width = win_height;
926                             }
927
928                             sclboolean process_event = FALSE;
929                             if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
930                                 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
931                                     process_event = TRUE;
932                             }
933                             /* Process this event regardless of the coordinate if the top window has the POPUP_GRAB layout style */
934                             if (index == SCL_WINDOW_Z_TOP) {
935                                 const SclLayout *layout = cache->get_cur_layout(window);
936                                 if (layout) {
937                                     if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
938                                         process_event = TRUE;
939                                     }
940                                 }
941                             }
942                             if (process_event) {
943                                 /* Now convert the global coordinate to appropriate local coordinate */
944                                 SclPoint coords = get_rotated_local_coords(
945                                         root_x, root_y, context->get_rotation(), &rect);
946                                 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
947                                 processed = TRUE;
948                             }
949                         }
950                     }
951                 }
952                 index++;
953             } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
954         }
955
956         if (!processed) {
957             window = pressed_window;
958             SclWindowContext *window_context = windows->get_window_context(window);
959             if (window_context && get_window_rect(window, &rect)) {
960                 /* Now convert the global coordinate to appropriate local coordinate */
961 #ifdef WAYLAND
962                 int root_x = ev->x + rect.x;
963                 int root_y = ev->y + rect.y;
964                 if (window_context->is_virtual) {
965                     apply_virtual_offset(rect, &root_x, &root_y);
966                 }
967 #else
968                 int root_x = ev->root.x;
969                 int root_y = ev->root.y;
970 #endif
971
972                 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
973                 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
974                 processed = TRUE;
975             }
976         }
977     }
978     //CSCLController *controller = CSCLController::get_instance();
979     //CSCLWindows *windows = CSCLWindows::get_instance();
980     //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
981     //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
982
983     return TRUE;
984 }
985
986 /**
987  * Regists a event callback func to given window.
988  * In this function, it should call several event functions of CSCLController class whenever an event has occurred
989  * The below list shows what event function should be called.
990  * - mouse_press (when the user presses mouse button)
991  * - mouse_release (when the user releases mouse button)
992  * - mouse_move (when the user drags mouse button)
993  * - show_base_layout (when the expost event has occurred)
994  */
995 void
996 CSCLEventsImplEfl::connect_window_events(const sclwindow wnd, const sclint evt)
997 {
998     SCL_DEBUG();
999
1000     //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL);
1001     /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL);
1002     evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/
1003 }
1004
1005 #ifndef WAYLAND
1006 static Eina_Bool
1007 client_message_cb(void *data, int type, void *event)
1008 {
1009     Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event;
1010     if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) {
1011         CSCLWindows *windows = CSCLWindows::get_instance();
1012         CSCLController *controller = CSCLController::get_instance();
1013
1014         static int last_pos_x = -10000;
1015         static int last_pos_y = -10000;
1016
1017         if (windows && controller) {
1018             Evas_Object *base_win = (Evas_Object *)windows->get_base_window();
1019             if (base_win == NULL) return FALSE;
1020
1021             if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) {
1022                 if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) {
1023                 // 1 finger double tap
1024                 controller->mouse_press(base_win, last_pos_x, last_pos_y);
1025                 controller->mouse_release(base_win, last_pos_x, last_pos_y);
1026                 } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) {
1027                     // 1 finger tap
1028                     // 1 finger touch & move
1029                     last_pos_x = ev->data.l[2];
1030                     last_pos_y = ev->data.l[3];
1031                     controller->mouse_over(base_win, last_pos_x, last_pos_y);
1032                 }
1033             }
1034         }
1035     }
1036     return ECORE_CALLBACK_PASS_ON;
1037 }
1038 #endif
1039
1040 Eina_Bool timer_event(void *data)
1041 {
1042     SCL_DEBUG();
1043     CSCLUtils *utils = CSCLUtils::get_instance();
1044     CSCLController *controller = CSCLController::get_instance();
1045
1046     scl32 sendData = static_cast<scl32>(reinterpret_cast<uintptr_t>(data) & 0xffffffff);
1047
1048     if (controller && utils) {
1049         scl16 id = SCL_LOWORD(sendData); /* Timer ID */
1050         Eina_Bool ret = controller->timer_event(sendData);
1051         if (!ret) {
1052             utils->log("Returning Timer : %d %d\n", id, ret);
1053         }
1054         return ret;
1055     }
1056     return TRUE;
1057 }
1058
1059 /**
1060  * Creates a timer
1061  * In this function, it should call timer_event of CSCLController class
1062  */
1063 void
1064 CSCLEventsImplEfl::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap)
1065 {
1066     SCL_DEBUG();
1067     sclint data = SCL_MAKELONG(id, value);
1068     Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)data);
1069     if (pTimer) {
1070         CSCLUtils *utils = CSCLUtils::get_instance();
1071         if (utils) {
1072             utils->log("Created Timer : %d %p\n", id, pTimer);
1073         }
1074         if (addToMap) {
1075             idMap[id] = pTimer;
1076         }
1077     }
1078 }
1079
1080 /**
1081  * Destroys the given ID's timer
1082  */
1083 void
1084 CSCLEventsImplEfl::destroy_timer(const scl32 id)
1085 {
1086     SCL_DEBUG();
1087     //for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) {
1088         std::map<int, Ecore_Timer*>::iterator idx = idMap.find(id);
1089         //if ((*idx).first == id) {
1090         if (idx != idMap.end()) {
1091             CSCLUtils *utils = CSCLUtils::get_instance();
1092             if (utils) {
1093                 utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
1094             }
1095             ecore_timer_del((*idx).second);
1096             idMap.erase((*idx).first);
1097             //break;
1098         }
1099     //}
1100 }
1101
1102 /**
1103  * Destroys all of created timer
1104  */
1105 void
1106 CSCLEventsImplEfl::destroy_all_timer()
1107 {
1108     SCL_DEBUG();
1109     for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx ) {
1110         ecore_timer_del((*idx).second);
1111
1112         CSCLUtils *utils = CSCLUtils::get_instance();
1113         if (utils) {
1114             utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
1115         }
1116     }
1117     idMap.clear();
1118 }
1119
1120 void
1121 CSCLEventsImplEfl::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y)
1122 {
1123     CSCLWindows *windows = CSCLWindows::get_instance();
1124     SclWindowContext *window_context = NULL;
1125
1126     static const sclint MAX_DEVICES = 100;
1127     static sclboolean pressed[MAX_DEVICES] = { FALSE };
1128     if (windows) {
1129         switch (type) {
1130             case SCL_MOUSE_EVENT_PRESS:
1131             {
1132                 sclboolean generated = FALSE;
1133                 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1134                     if (pressed[loop] != TRUE) {
1135                         pressed[loop] = TRUE;
1136                         Ecore_Event_Mouse_Button evt;
1137 #ifdef WAYLAND
1138                         Ecore_Wl_Window *wl_base_window;
1139                         wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1140                         if (wl_base_window)
1141                             evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1142 #else
1143                         evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1144 #endif
1145                         //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1146                         window_context = windows->get_window_context(windows->get_base_window());
1147                         if (window_context) {
1148                             evt.root.x = x + window_context->geometry.x;
1149                             evt.root.y = y + window_context->geometry.y;
1150                             evt.multi.device = loop;
1151                             mouse_press(NULL, 0, &evt);
1152                         }
1153                         generated = TRUE;
1154                     }
1155                 }
1156             }
1157             break;
1158             case SCL_MOUSE_EVENT_RELEASE:
1159             {
1160                 sclboolean generated = FALSE;
1161                 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1162                     if (pressed[loop] == TRUE) {
1163                         pressed[loop] = FALSE;
1164                         Ecore_Event_Mouse_Button evt;
1165 #ifdef WAYLAND
1166                         Ecore_Wl_Window *wl_base_window;
1167                         wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1168                         if (wl_base_window)
1169                             evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1170 #else
1171                         evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1172 #endif
1173                         //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1174                         window_context = windows->get_window_context(windows->get_base_window());
1175                         if (window_context) {
1176                             evt.root.x = x + window_context->geometry.x;
1177                             evt.root.y = y + window_context->geometry.y;
1178                             evt.multi.device = loop;
1179                             mouse_release(NULL, 0, &evt);
1180                         }
1181                         generated = TRUE;
1182                     }
1183                 }
1184             }
1185             break;
1186             case SCL_MOUSE_EVENT_MOVE:
1187             {
1188                 sclboolean generated = FALSE;
1189                 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1190                     if (pressed[loop] == TRUE) {
1191                         Ecore_Event_Mouse_Move evt;
1192 #ifdef WAYLAND
1193                         Ecore_Wl_Window *wl_base_window;
1194                         wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1195                         if (wl_base_window)
1196                             evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1197 #else
1198                         evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1199 #endif
1200                         //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1201                         window_context = windows->get_window_context(windows->get_base_window());
1202                         if (window_context) {
1203                             evt.root.x = x + window_context->geometry.x;
1204                             evt.root.y = y + window_context->geometry.y;
1205                             evt.multi.device = loop;
1206                             mouse_move(NULL, 0, &evt);
1207                         }
1208                         generated = TRUE;
1209                     }
1210                 }
1211             }
1212             break;
1213             default:
1214             break;
1215         }
1216     }
1217 }