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