Modified to skip outdated touch events
[platform/core/uifw/libscl-ui.git] / scl / gwes / efl / sclwindows-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 "sclwindows-efl.h"
19 #include "scldebug.h"
20 #include "sclcontroller.h"
21 #include "sclcontext.h"
22 #include "sclresourcecache.h"
23 #include "scluibuilder.h"
24 #include "sclwindows.h"
25 #include "sclres_manager.h"
26
27 #include <glib.h>
28 #include <Elementary.h>
29 #include <malloc.h>
30 #ifdef WAYLAND
31 #include <Ecore_Wayland.h>
32 #else
33 #include <Ecore_X.h>
34 #include <X11/Xlib.h>
35 #include <X11/Xatom.h>
36 #include <X11/Xutil.h>
37 #endif
38 #include <dlog.h>
39 #include "sclkeyfocushandler.h"
40
41 using namespace scl;
42
43 #ifndef WAYLAND
44 static Ecore_X_Atom ATOM_WM_CLASS = 0;
45 static Ecore_X_Window app_window = 0;
46 #endif
47
48 const sclint rotation_values_EFL[ROTATION_MAX] = {
49     0, // ROTATION_0
50     90, // ROTATION_90_CW
51     180, // ROTATION_180
52     270, // ROTATION_90_CCW
53 };
54
55 void release_all(Evas_Object *win);
56
57 #include "sclgraphics-efl.h"
58 #ifdef TEST_NEWBACKEND
59 #include <Ecore_Evas.h>
60 #include <Ecore.h>
61 #include <vector>
62 extern std::vector<ImageCache> g_ImageCache;
63 extern std::vector<TextCache> g_TextCache;
64 #else
65 #endif
66
67 /* When the base window is resized, any mouse events generated before this timestamp value
68  * that are waiting in the event queue, could be considered as outdated so we are going to
69  * skip those events */
70 unsigned int g_timestamp_last_base_window_resized = 0;
71
72 /**
73  * Constructor
74  */
75 CSCLWindowsImplEfl::CSCLWindowsImplEfl()
76 {
77     SCL_DEBUG();
78 #ifndef WAYLAND
79     /* Initializes all window resources */
80     ATOM_WM_CLASS = ecore_x_atom_get("WM_CLASS");
81 #endif
82 }
83
84 /**
85  * De-constructor
86  */
87 CSCLWindowsImplEfl::~CSCLWindowsImplEfl()
88 {
89     SCL_DEBUG();
90 }
91
92 static void window_show_cb(void *data, Evas *e, Evas_Object *obj, void *event)
93 {
94     LOGD("INSIDE =-=-=-=- window_show_cb, Trying to Grab Key Board : \n");
95 #ifdef USING_KEY_GRAB
96     CSCLWindows *windows = CSCLWindows::get_instance();
97     CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
98
99     if (windows && focus_handler)
100         focus_handler->grab_keyboard(windows->get_base_window());
101 #endif
102 }
103
104 void CSCLWindowsImplEfl::init()
105 {
106 }
107
108 void CSCLWindowsImplEfl::fini()
109 {
110 }
111
112 /**
113  * Create a content window and binds it into given parent window as a child
114  */
115 sclwindow
116 CSCLWindowsImplEfl::create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
117 {
118     SCL_DEBUG();
119
120     sclwindow ret = SCLWINDOW_INVALID;
121
122     if (window_context) {
123         window_context->etc_info = NULL;
124         window_context->window = parent;
125
126         //Adding window show event handler
127         evas_object_event_callback_add(static_cast<Evas_Object*>(parent), EVAS_CALLBACK_SHOW, window_show_cb, NULL);
128
129         set_window_accepts_focus(parent, FALSE);
130
131 #ifndef WAYLAND
132         ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(parent)), "Virtual Keyboard", "ISF");
133 #endif
134
135         ret = window_context->window;
136     }
137
138     int rots[4] = {0, 90, 180, 270};
139     elm_win_wm_rotation_available_rotations_set(static_cast<Evas_Object*>(parent), rots, 4);
140
141     CSCLUtils *utils = CSCLUtils::get_instance();
142     if (utils) {
143         utils->log("WinEfl_createbasewin %p, %d %d\n",
144                 parent, width, height);
145     }
146     return ret;
147 }
148
149 /**
150  * Creates a window
151  */
152 sclwindow
153 CSCLWindowsImplEfl::create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
154 {
155     SCL_DEBUG();
156
157     Evas_Object *win = NULL;
158     CSCLUtils *utils = CSCLUtils::get_instance();
159
160     win = elm_win_add(static_cast<Evas_Object*>(parent), "SCLPopup", ELM_WIN_UTILITY);
161
162     elm_win_borderless_set(win, EINA_TRUE);
163     elm_win_alpha_set(win, EINA_TRUE);
164     elm_win_title_set(win, "ISF Popup");
165
166     set_window_accepts_focus(win, FALSE);
167
168     int rots[4] = {0, 90, 180, 270};
169     elm_win_wm_rotation_available_rotations_set(win, rots, 4);
170
171     scl16 new_width = 0;
172     scl16 new_height = 0;
173     CSCLContext *context = CSCLContext::get_instance();
174     if (context) {
175         if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
176             new_width = height;
177             new_height = width;
178         } else {
179             new_width = width;
180             new_height = height;
181         }
182     }
183
184 #ifndef FULL_SCREEN_TEST
185     //evas_object_resize(win, width, height);
186 #endif
187
188 #ifdef WAYLAND
189     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
190         rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height);
191     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
192         rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height);
193     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
194         rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height);
195     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
196         rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height);
197 #else
198     /*
199     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
200         rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height);
201     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
202         rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height);
203     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
204         rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height);
205     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
206         rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height);
207     */
208     ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), "ISF Popup", "ISF");
209
210     Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE  = 0;
211     unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect
212
213     ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
214     if (ATOM_WINDOW_EFFECT_ENABLE) {
215         ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
216     } else {
217         if (utils) {
218             utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n");
219         }
220     }
221 #endif
222
223     if (context)
224         set_window_rotation(win, context->get_rotation());
225
226     //elm_win_override_set(win, EINA_TRUE);
227     if (utils) {
228         utils->log("WinEfl_createwin %p, %d %d\n",
229                 win, width, height);
230     }
231     return win;
232 }
233
234
235 /**
236 * Creates a window
237 */
238 sclwindow
239 CSCLWindowsImplEfl::create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
240 {
241     SCL_DEBUG();
242
243     Evas_Object *win = NULL;
244     CSCLUtils *utils = CSCLUtils::get_instance();
245
246     win = elm_win_add(static_cast<Evas_Object*>(parent), "Magnifier", ELM_WIN_UTILITY);
247     LOGD("Created magnifier window %p, using parent %p", win, parent);
248
249     elm_win_borderless_set(win, EINA_TRUE);
250     elm_win_alpha_set(win, EINA_TRUE);
251     elm_win_title_set(win, "ISF Popup");
252
253     set_window_accepts_focus(win, FALSE);
254
255     int rots[4] = { 0, 90, 180, 270 };
256     elm_win_wm_rotation_available_rotations_set(win, rots, 4);
257
258 #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
259     CSCLUtils *utils = CSCLUtils::get_instance();
260     CSCLWindows *windows = CSCLWindows::get_instance();
261     sclint scrx, scry, winx, winy;
262     if (windows && utils) {
263         utils->get_screen_resolution(&scrx, &scry);
264         SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
265         if (window_context) evas_object_resize(win, scrx, height + window_context->height);
266     }
267 #endif
268
269 #ifdef WAYLAND
270     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
271         rotation_values_EFL[ROTATION_0], 0, 0, width, height);
272     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
273         rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width);
274     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
275         rotation_values_EFL[ROTATION_180], 0, 0, width, height);
276     ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(win),
277         rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width);
278 #else
279     /*
280     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
281         rotation_values_EFL[ROTATION_0], 0, 0, width, height);
282     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
283         rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width);
284     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
285         rotation_values_EFL[ROTATION_180], 0, 0, width, height);
286     ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
287         rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width);
288     */
289     ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), "Key Magnifier", "ISF");
290     Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE  = 0;
291     unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect
292     ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
293     if (ATOM_WINDOW_EFFECT_ENABLE) {
294         ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
295     } else {
296         if (utils) {
297             utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n");
298         }
299     }
300 #endif
301
302     CSCLContext *context = CSCLContext::get_instance();
303     if (context)
304         set_window_rotation(win, context->get_rotation());
305
306     if (utils) {
307         utils->log("WinEfl_createmagwin %p, %d %d\n",
308             win, width, height);
309     }
310
311     return win;
312 }
313
314 /**
315  * Creates the dim window
316  */
317 sclwindow
318 CSCLWindowsImplEfl::create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
319 {
320     SCL_DEBUG();
321
322     Evas_Object *win = NULL;
323     CSCLUtils *utils = CSCLUtils::get_instance();
324     win = elm_win_add(static_cast<Evas_Object*>(parent), "SCLPopup", ELM_WIN_UTILITY);
325
326     elm_win_borderless_set(win, EINA_TRUE);
327     elm_win_alpha_set(win, EINA_TRUE);
328     elm_win_title_set(win, "ISF Popup");
329
330     evas_object_resize(win, width, height);
331
332     int rots[4] = {0, 90, 180, 270};
333     elm_win_wm_rotation_available_rotations_set(win, rots, 4);
334
335     set_window_accepts_focus(win, FALSE);
336
337 #ifndef WAYLAND
338     ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), "ISF Popup", "ISF");
339
340     Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE  = 0;
341     unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect
342
343     ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
344     if (ATOM_WINDOW_EFFECT_ENABLE) {
345         ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
346     } else {
347         if (utils) {
348             utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n");
349         }
350     }
351 #endif
352
353     CSCLContext *context = CSCLContext::get_instance();
354     if (context)
355         set_window_rotation(win, context->get_rotation());
356
357     /*Evas_Object *bg;
358     bg = elm_bg_add(win);
359     elm_win_resize_object_add(win, bg);
360     evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
361     SclColor color = scl_dim_window_configure.dim_color;
362     evas_object_color_set(bg, color.r, color.g, color.b, color.a);
363     evas_object_show(bg);*/
364
365     hide_window(win);
366
367     if (utils) {
368         utils->log("WinEfl_createdimwin %p, %d %d\n",
369             win, width, height);
370     }
371     return win;
372 }
373
374 /**
375  * Make a window relation between parent and child
376  * Caution: Currently, If we use transient_for them the ISE will occure some crash. It needs to check X11
377  */
378 void
379 CSCLWindowsImplEfl::set_parent(const sclwindow parent, const sclwindow window)
380 {
381     SCL_DEBUG();
382
383 #ifndef WAYLAND
384     if (parent && window) {
385         ecore_x_icccm_transient_for_set(elm_win_xwindow_get(static_cast<Evas_Object*>(window)),
386                 elm_win_xwindow_get(static_cast<Evas_Object*>(parent)));
387     }
388 #endif
389 }
390
391 Eina_Bool destroy_later(void *data)
392 {
393     evas_object_hide((Evas_Object*)data);
394     evas_object_del((Evas_Object*)data);
395     return ECORE_CALLBACK_CANCEL;
396 }
397
398 /**
399  * Destroys the given window
400  */
401 bool
402 CSCLWindowsImplEfl::destroy_window(sclwindow window)
403 {
404     SCL_DEBUG();
405
406     CSCLWindows *windows = CSCLWindows::get_instance();
407     CSCLUtils *utils = CSCLUtils::get_instance();
408
409     SclWindowContext *window_context = NULL;
410     if (windows && window && utils) {
411         window_context = windows->get_window_context(window);
412         if (window_context) {
413             utils->log("WinEfl_destroywin %p %p (basewin %p mag %p)\n", window,
414                 (!(window_context->is_virtual)) ? elm_win_xwindow_get(static_cast<Evas_Object*>(window)) : 0x01,
415                 windows->get_base_window(), windows->get_magnifier_window());
416             if (window_context->etc_info) {
417                 Eina_List *list = (Eina_List*)(window_context->etc_info);
418                 Eina_List *iter = NULL;
419                 Eina_List *iter_next = NULL;
420                 void *data = NULL;
421
422                 EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
423                     if (data) {
424                         EFLObject *object = (EFLObject*)(data);
425                         if (object) {
426                             Evas_Object* eo = object->object;
427                             if (object->extracted) {
428                                 //evas_object_image_data_set(eo, NULL);
429                                 void *image_data = evas_object_image_data_get(eo, 1);
430                                 if (image_data) {
431                                     free(image_data);
432                                 }
433                             }
434                             if (eo) {
435                                 evas_object_del(eo);
436                                 object->object = NULL;
437                             }
438                             if (object->type == EFLOBJECT_TEXTBLOCK) {
439                                 Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
440                                 if (st) {
441                                     evas_textblock_style_free(st);
442                                 }
443 #ifdef TEST_NEWBACKEND
444                                 for (sclint loop = 0;loop < g_TextCache.size();loop++) {
445                                     if (g_TextCache[loop].text == object->object) {
446                                         g_TextCache[loop].used = FALSE;
447                                     }
448                                 }
449 #endif
450                             } else if (object->type == EFLOBJECT_IMAGE) {
451 #ifdef TEST_NEWBACKEND
452                                 for (sclint loop = 0;loop < g_ImageCache.size();loop++) {
453                                     if (g_ImageCache[loop].image == object->object) {
454                                         g_ImageCache[loop].used = FALSE;
455                                     }
456                                 }
457 #endif
458                             }
459                             delete object;
460                         }
461                     }
462                     list = eina_list_remove_list(list, iter);
463                 }
464                 window_context->etc_info = NULL;
465             }
466
467             if (!(window_context->is_virtual)) {
468                 /* FIXME : A workaround for the bug that event on a window being hidden is delivered to
469                     e17, instead of the window itself or the window right below - Should report to WM */
470                 if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) {
471                     ecore_timer_add(0.1f, destroy_later, (void*)window);
472                 } else {
473                     Evas_Object *win = (Evas_Object*)window;
474                     evas_object_hide(win);
475                     evas_object_del(win);
476                 }
477             }
478             utils->log("WinEfl_destroywin %p (basewin %p mag %p)\n", window,
479                  windows->get_base_window(), windows->get_magnifier_window());
480         }
481     }
482
483     return TRUE;
484 }
485
486 /**
487  * Shows the given window
488  */
489 void
490 CSCLWindowsImplEfl::show_window(const sclwindow window, sclboolean queue)
491 {
492     SCL_DEBUG();
493     CSCLWindows *windows = CSCLWindows::get_instance();
494     CSCLContext *context = CSCLContext::get_instance();
495     CSCLUtils *utils = CSCLUtils::get_instance();
496     if (windows && context && window) {
497         SclWindowContext *window_context = windows->get_window_context(window);
498         if (!(context->get_hidden_state())) {
499             if (window_context) {
500                 if (!(window_context->is_virtual)) {
501                     evas_object_show((Evas_Object*)window);
502                 }
503
504                 if (!(windows->get_update_pending())) {
505                     update_window(window);
506                 }
507             }
508         }
509
510 #ifndef WAYLAND
511         if (windows->get_base_window() == window) {
512             int  ret = 0;
513             Atom type_return;
514             int  format_return;
515             unsigned long    nitems_return;
516             unsigned long    bytes_after_return;
517             unsigned char   *data = NULL;
518
519             Ecore_X_Window win = elm_win_xwindow_get(static_cast<Evas_Object*>(window));
520             ret = XGetWindowProperty((Display *)ecore_x_display_get(),
521                     ecore_x_window_root_get(win),
522                     ecore_x_atom_get("_ISF_ACTIVE_WINDOW"),
523                     0, G_MAXLONG, False, XA_WINDOW, &type_return,
524                     &format_return, &nitems_return, &bytes_after_return,
525                     &data);
526
527             if (data) {
528                 if (ret == Success) {
529                     if ((type_return == XA_WINDOW) && (format_return == 32) && (data)) {
530                         app_window = *(Window *)data;
531                     }
532                 }
533                 XFree(data);
534             }
535         }
536 #endif
537         scl8 popup_index = windows->find_popup_window_index(window);
538         if (windows->get_magnifier_window() == window || popup_index != NOT_USED) {
539             /*
540              * FIXME a solution to make magnifier window always on top
541              * N_SE-17689: magnifier window showing behind of candidate window
542              *
543              * N_SE-52548: ...and modified if() for other popup windows as well...
544              */
545             if (window_context && !(window_context->is_virtual)) {
546 #ifndef WAYLAND
547                 ecore_x_icccm_transient_for_set
548                     (elm_win_xwindow_get(static_cast<Evas_Object*>(window)), app_window);
549 #endif
550                 elm_win_raise((Evas_Object *)window);
551             }
552         }
553
554         if (utils) {
555             utils->log("WinEfl_showwin %p %p (basewin %p mag %p)\n",
556                 window,
557                 windows->get_base_window(), windows->get_magnifier_window());
558         }
559     }
560 }
561
562 /**
563  * Hides the given window
564  */
565 void
566 CSCLWindowsImplEfl::hide_window(const sclwindow window,  sclboolean fForce)
567 {
568     SCL_DEBUG();
569     CSCLWindows *windows = CSCLWindows::get_instance();
570     CSCLUtils *utils = CSCLUtils::get_instance();
571     SclWindowContext *window_context = NULL;
572
573     if (windows && window) {
574 #ifdef USING_KEY_GRAB
575     if (window == windows->get_base_window()) {
576         CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
577         focus_handler->ungrab_keyboard(window);
578     }
579 #endif
580
581         window_context = windows->get_window_context(window);
582         if (window_context) {
583             if (!(window_context->is_virtual)) {
584                 Evas_Object *win = (Evas_Object*)window;
585                 /* FIXME : A workaround for the bug that event on a window being hidden is delivered to
586                    e17, instead of the window itself or the window right below - Should report to WM */
587                 if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) {
588                     evas_object_move(win, -10000, -10000);
589                 } else {
590 #ifdef WAYLAND
591                     /* Under wayland environment, the visibility of keyboard window is controlled by
592                      * wayland server, so it is not allowed to call evas_object_hide() for keyboard window
593                      * directly on the keyboard side */
594                     if (win != windows->get_base_window()) {
595                         evas_object_hide(win);
596                     }
597 #else
598                     evas_object_hide(win);
599 #endif
600                 }
601             }
602         }
603     }
604
605     if (windows && utils && window) {
606         // Memory optimization */
607         if (window == windows->get_magnifier_window() || window == windows->get_dim_window()) {
608             if (window_context) {
609                 if (window_context->etc_info) {
610                     Eina_List *list = (Eina_List*)(window_context->etc_info);
611                     Eina_List *iter = NULL;
612                     Eina_List *iter_next = NULL;
613                     void *data = NULL;
614                     int iIndex = 0;
615 #ifdef TEST_NEWBACKEND
616 #else
617                     EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
618                         if (data) {
619                             EFLObject *object = (EFLObject*)(data);
620                             if (object) {
621                                 sclboolean bShouldRemove = FALSE;
622                                 bShouldRemove = TRUE;
623                                 if (bShouldRemove) {
624                                     Evas_Object* eo = object->object;
625                                     if (object->extracted) {
626                                         void *image_data = evas_object_image_data_get(eo, 1);
627                                         if (image_data) {
628                                             free(image_data);
629                                         }
630                                     }
631                                     if (eo) {
632                                         evas_object_del(eo);
633                                         object->object = NULL;
634                                     }
635                                     if (object->type == EFLOBJECT_TEXTBLOCK) {
636                                         Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
637                                         if (st) {
638                                             evas_textblock_style_free(st);
639                                         }
640 #ifdef TEST_NEWBACKEND
641                                         for (sclint loop = 0;loop < g_TextCache.size();loop++) {
642                                             if (g_TextCache[loop].text == object->object) {
643                                                 g_TextCache[loop].used = FALSE;
644                                             }
645                                         }
646 #endif
647                                     } else if (object->type == EFLOBJECT_IMAGE) {
648 #ifdef TEST_NEWBACKEND
649                                         for (sclint loop = 0;loop < g_ImageCache.size();loop++) {
650                                             if (g_ImageCache[loop].image == object->object) {
651                                                 g_ImageCache[loop].used = FALSE;
652                                             }
653                                         }
654 #endif
655                                     }
656                                     delete object;
657                                     list = eina_list_remove_list(list, iter);
658                                 }
659                             }
660                             iIndex++;
661                         }
662                     }
663                     window_context->etc_info = list;
664 #endif
665                 }
666             }
667             //Evas *evas = evas_object_evas_get((Evas_Object*)window);
668             //evas_render_idle_flush(evas);
669         }
670         if (window == windows->get_base_window()) {
671             elm_cache_all_flush();
672             malloc_trim(0);
673         }
674         utils->log("WinEfl_hidewin %p (basewin %p mag %p)\n",
675             window,
676             windows->get_base_window(), windows->get_magnifier_window());
677     }
678 }
679
680 /**
681  * Moves the window to the given position
682  */
683 sclint magnifierx, magnifiery;
684 void
685 CSCLWindowsImplEfl::move_window(const sclwindow window, scl16 x, scl16 y)
686 {
687     SCL_DEBUG();
688     CSCLUtils *utils = CSCLUtils::get_instance();
689     CSCLContext *context = CSCLContext::get_instance();
690     CSCLWindows *windows = CSCLWindows::get_instance();
691
692     if (utils && context && windows && window) {
693         SclWindowContext *window_context = windows->get_window_context(window);
694         unsigned short win_width = 0;
695         unsigned short win_height = 0;
696         if (window_context) {
697             win_width = window_context->geometry.width;
698             win_height = window_context->geometry.height;
699         }
700
701         scl16 rotatex = x;
702         scl16 rotatey = y;
703         scl16 orgx = x;
704         scl16 orgy = y;
705
706         sclint scr_w, scr_h;
707         /* get window size */
708         utils->get_screen_resolution(&scr_w, &scr_h);
709
710 #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
711         if (window == windows->get_magnifier_window()) {
712             SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE);
713             rotatex = orgx = 0;
714             if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) {
715                 rotatey = orgy = scr_w - base_window_context->height - win_height;
716                 win_width = base_window_context->width;
717                 win_height = base_window_context->height + win_height;
718             } else {
719                 rotatey = orgy = scr_h - base_window_context->height - win_height;
720                 win_width = base_window_context->width;
721                 win_height = base_window_context->height + win_height;
722             }
723             magnifierx = x;
724             magnifiery = y - orgy;
725         }
726 #endif
727
728         switch (context->get_rotation()) {
729             case ROTATION_90_CW: {
730                 rotatex = orgy;
731                 rotatey = scr_w - orgx - win_width;
732             }
733             break;
734             case ROTATION_180: {
735                 rotatex = scr_w - orgx - win_width;
736                 rotatey = scr_h - orgy - win_height;
737             }
738             break;
739             case ROTATION_90_CCW: {
740                 rotatex = scr_h - orgy - win_height;
741                 rotatey = orgx;
742             }
743             break;
744             case ROTATION_0: break;
745             default: break;
746         }
747
748     #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
749         if (window == windows->get_magnifier_window()) {
750             if (rotatex == window_context->x && rotatey == windonw_context->y) return;
751         }
752     #endif
753
754         Evas_Object *win = (Evas_Object*)window;
755 #ifndef FULL_SCREEN_TEST
756         if (window != windows->get_base_window()) {
757             evas_object_move(win, rotatex, rotatey);
758         }
759 #endif
760         //Evas_Object *window_object = (Evas_Object*)window;
761         //Evas *evas = evas_object_evas_get(window_object);
762         //evas_render_idle_flush(evas);
763
764         utils->log("WinEfl_movewin %p %d %d %d %d (basewin %p mag %p)\n",
765             window,
766             x, y, rotatex, rotatey,
767             windows->get_base_window(), windows->get_magnifier_window());
768     }
769 }
770
771 /**
772 * Resizes the window to the given metric
773 */
774 void
775 CSCLWindowsImplEfl::resize_window(const sclwindow window, scl16 width, scl16 height)
776 {
777     SCL_DEBUG();
778
779     CSCLWindows *windows = CSCLWindows::get_instance();
780     CSCLUtils *utils = CSCLUtils::get_instance();
781
782     if (!windows || !utils) return;
783
784 #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
785     if (window == windows->get_magnifier_window()) {
786         SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
787         if (window_context->width != width || window_context->height != height) {
788             sclint scrx, scry, winx, winy;
789             utils->get_screen_resolution(&scrx, &scry);
790             if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) {
791                 evas_object_resize((Evas_Object*)window, scry, height + window_context->height);
792             } else {
793                 evas_object_resize((Evas_Object*)window, scrx, height + window_context->height);
794             }
795         }
796         return;
797     }
798 #endif
799
800     Evas_Object *win = (Evas_Object*)window;
801 #ifndef FULL_SCREEN_TEST
802     if (windows && utils && window) {
803         utils->log("WinEfl_resizewin %p %d %d (basewin %p mag %p)\n",
804             window,
805             windows->get_base_window(), windows->get_magnifier_window());
806     }
807 #endif
808     //Evas_Object *window_object = (Evas_Object*)window;
809     //Evas *evas = evas_object_evas_get(window_object);
810     /*CSCLWindows *windows = CSCLWindows::get_instance();
811     if (windows) {
812         windows->update_window(window);
813     }*/
814     //evas_render_idle_flush(evas);
815     if (windows && window) {
816         if (window != windows->get_base_window()) {
817             evas_object_resize(win, width, height);
818         } else {
819             g_timestamp_last_base_window_resized = (unsigned int)(ecore_loop_time_get() * 1000.0f);
820         }
821
822         if (window == windows->get_dim_window()) {
823             hide_window(window);
824         }
825     }
826 }
827
828 /**
829 * Resizes the window to the given metric
830 */
831 void
832 CSCLWindowsImplEfl::move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height)
833 {
834     SCL_DEBUG();
835     Evas_Object *win = (Evas_Object*)window;
836 #ifndef FULL_SCREEN_TEST
837     CSCLWindows *windows = CSCLWindows::get_instance();
838     CSCLUtils *utils = CSCLUtils::get_instance();
839     if (windows && utils && window) {
840         if (window != windows->get_base_window()) {
841             evas_object_move(win, x, y);
842             evas_object_resize(win, width, height);
843         }
844         utils->log("WinEfl_moveresizewin %p %d %d %d %d (basewin %p mag %p)\n",
845             window, x, y, width, height, windows->get_base_window());
846     }
847 #endif
848     //Evas_Object *window_object = (Evas_Object*)window;
849     //Evas *evas = evas_object_evas_get(window_object);
850     /*CSCLWindows *windows = CSCLWindows::get_instance();
851     if (windows) {
852         windows->update_window(window);
853     }*/
854     //evas_render_idle_flush(evas);
855 }
856
857 /**
858 * Update the window to redraw given area
859 */
860 void
861 CSCLWindowsImplEfl::update_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height)
862 {
863     SCL_DEBUG();
864
865     sclboolean removeall = FALSE;
866     SclRectangle updatearea = {x, y, width, height};
867     if (x + y + width + height == 0) {
868         removeall = TRUE;
869     }
870
871     CSCLWindows *windows = CSCLWindows::get_instance();
872     CSCLUtils *utils = CSCLUtils::get_instance();
873     SclWindowContext *window_context = NULL;
874
875     if (windows && window) {
876         //window_context = windows->get_window_context(window, FALSE);
877         window_context = windows->get_window_context(window);
878     }
879     if (windows && utils && window_context) {
880         if (window_context->is_virtual) {
881             SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
882             if (base_window_context) {
883                 updatearea.x += (window_context->geometry.x - base_window_context->geometry.x);
884                 updatearea.y += (window_context->geometry.y - base_window_context->geometry.y);
885             }
886         }
887         if (window_context->etc_info) {
888             Eina_List *list = (Eina_List*)(window_context->etc_info);
889             Eina_List *iter = NULL;
890             Eina_List *iter_next = NULL;
891             void *data = NULL;
892             int iIndex = 0;
893
894             EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
895                 if (data) {
896                     EFLObject *object = (EFLObject*)(data);
897                     if (object) {
898                         Evas_Object* eo = object->object;
899                         sclboolean bShouldRemove = FALSE;
900                         if (removeall || utils->is_rect_overlap(object->position, updatearea)) {
901                             bShouldRemove = TRUE;
902                         }
903                         if (iIndex == 0 && !removeall) {
904                             bShouldRemove = FALSE; // window's background
905                         }
906                         if (object->type == EFLOBJECT_CLIPOBJECT) {
907                             bShouldRemove = FALSE; // Clip objects are removed when the parent image object is removed
908                         }
909                         if (eo == NULL) { /* If this object is already removed, proceed removing */
910                             bShouldRemove = TRUE;
911                         }
912                         if (bShouldRemove) {
913 #ifdef TEST_NEWBACKEND
914                             //if (object->type == EFLOBJECT_IMAGE) {
915                             SCL_DEBUG_ELAPASED_TIME_START();
916                             if (TRUE) {
917                                 if (window_context->width != object->position.width || window_context->height != object->position.height ||
918                                     object->type == EFLOBJECT_TEXTBLOCK || window == windows->get_magnifier_window()) {
919                                     evas_object_hide(object->object);
920                                 }
921                             } else {
922 #else
923                             if (object->extracted) {
924                                 void *image_data = evas_object_image_data_get(eo, 1);
925                                 if (image_data) {
926                                     free(image_data);
927                                 }
928                             }
929                             if (eo) {
930                                 evas_object_del(eo);
931                                 object->object = NULL;
932                             }
933                             if (object->type == EFLOBJECT_TEXTBLOCK) {
934                                 Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
935                                 if (st) {
936                                     evas_textblock_style_free(st);
937                                 }
938 #ifdef TEST_NEWBACKEND
939                                 for sclint loop = 0;loop < g_TextCache.size();loop++) {
940                                     if (g_TextCache[loop].text == object->object) {
941                                         g_TextCache[loop].used = FALSE;
942                                     }
943                                 }
944 #endif
945                             } else if (object->type == EFLOBJECT_IMAGE) {
946 #ifdef TEST_NEWBACKEND
947                                 for (sclint loop = 0;loop < g_ImageCache.size();loop++) {
948                                     if (g_ImageCache[loop].image == object->object) {
949                                         g_ImageCache[loop].used = FALSE;
950                                     }
951                                 }
952 #endif
953                                 EFLObject *clip_object = (EFLObject*)(object->data);
954                                 if (clip_object) {
955                                     if (clip_object->object) {
956                                         evas_object_del(clip_object->object);
957                                         clip_object->object = NULL;
958                                     }
959                                 }
960                             }
961                             delete object;
962                             list = eina_list_remove_list(list, iter);
963 #endif
964 #ifdef TEST_NEWBACKEND
965                             }
966 #endif
967                         }
968                     }
969                     iIndex++;
970                 }
971             }
972             window_context->etc_info = list;
973
974             /*while ((Eina_List*)(window_context->etc_info))
975             {
976                 EFLObject *object = (EFLObject*)eina_list_data_get((Eina_List*)(window_context->etc_info));
977                 if (object) {
978                     Evas_Object* eo = object->object;
979                     if (eo) {
980                         evas_object_del(eo);
981                         object->object = NULL;
982                     }
983                 }
984                 window_context->etc_info = eina_list_remove_list((Eina_List*)(window_context->etc_info), (Eina_List*)(winctx->etc_info));
985                 delete object;
986             }
987             window_context->etc_info = NULL;*/
988         }
989         CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
990         builder->show_layout(window, x, y, width, height);
991     }
992
993     /*evas_image_cache_flush(evas_object_evas_get((Evas_Object*)window));
994     elm_cache_all_flush();
995     malloc_trim(0);*/
996     //edje_file_cache_flush();
997 }
998
999 /**
1000  * Returns the position of x,y,width,height of the given window
1001  */
1002 sclboolean
1003 CSCLWindowsImplEfl::get_window_rect(const sclwindow window, SclRectangle *rect)
1004 {
1005     SCL_DEBUG();
1006     CSCLUtils *utils = CSCLUtils::get_instance();
1007     CSCLContext *context = CSCLContext::get_instance();
1008
1009     if (utils && context && rect && window) {
1010         int x = 0, y = 0, width = 0, height = 0;
1011         sclint scr_w = 0, scr_h = 0;
1012         elm_win_screen_position_get(static_cast<Evas_Object*>(window), &x, &y);
1013         evas_object_geometry_get(static_cast<Evas_Object*>(window), NULL, NULL, &width, &height);
1014
1015         utils->log("WinEfl_getwinrect %p %d %d %d %d\n",
1016             window, x, y, width, height);
1017
1018         /* get window size */
1019         utils->get_screen_resolution(&scr_w, &scr_h);
1020
1021         switch (context->get_rotation())
1022         {
1023         case ROTATION_90_CW:
1024             {
1025                 rect->width = width;
1026                 rect->height = height;
1027                 rect->x = scr_w - y - width;
1028                 rect->y = x;
1029             }
1030             break;
1031         case ROTATION_180:
1032             {
1033                 rect->x = scr_w - width - x;
1034                 rect->y = scr_h - height - y;
1035                 rect->width = width;
1036                 rect->height = height;
1037             }
1038             break;
1039         case ROTATION_90_CCW:
1040             {
1041                 rect->width = width;
1042                 rect->height = height;
1043                 rect->x = y;
1044                 rect->y = scr_h - x - height;
1045             }
1046             break;
1047         default:
1048             {
1049                 rect->x = x;
1050                 rect->y = y;
1051                 rect->width = width;
1052                 rect->height = height;
1053             }
1054             break;
1055         }
1056     }
1057
1058     return TRUE;
1059 }
1060
1061 /**
1062  * Sets rotation
1063  */
1064 void
1065 CSCLWindowsImplEfl::set_window_rotation(const sclwindow window, SCLRotation rotation)
1066 {
1067     SCL_DEBUG();
1068
1069 #ifndef WAYLAND
1070     CSCLWindows *windows = CSCLWindows::get_instance();
1071     SclWindowContext *window_context = NULL;
1072
1073     if (windows && window) {
1074         //window_context = windows->get_window_context(window, FALSE);
1075         window_context = windows->get_window_context(window);
1076
1077         if (window_context) {
1078             if (window_context->is_virtual) {
1079                 return;
1080             }
1081         }
1082
1083         XSizeHints hint;
1084         long int mask;
1085         Window win;
1086         Display *dpy;
1087
1088         dpy = (Display*)ecore_x_display_get();
1089         win = elm_win_xwindow_get((Evas_Object*)window);
1090
1091         if (!XGetWMNormalHints(dpy, win, &hint, &mask))
1092             memset(&hint, 0, sizeof(XSizeHints));
1093
1094         hint.flags |= USPosition;
1095
1096         XSetWMNormalHints(dpy, win, &hint);
1097         /*if (window_context) {
1098           windows->resize_window(window_context->window, window_context->width, winctx->height);
1099           }*/
1100     }
1101 #endif
1102 }
1103
1104 /**
1105  * Shows a message box
1106  */
1107 void
1108 CSCLWindowsImplEfl::show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg)
1109 {
1110     SCL_DEBUG();
1111 }
1112
1113 void
1114 CSCLWindowsImplEfl::set_keep_above(const sclwindow window, sclboolean keepabove)
1115 {
1116     SCL_DEBUG();
1117 }
1118
1119 void release_all(Evas_Object *win)
1120 {
1121     SCL_DEBUG();
1122     //if (window == windows->get_magnifier_window()) {
1123     //evas_object_move(win, -10000, -10000);
1124     //Evas *evas = evas_object_evas_get(win);
1125     //evas_render_idle_flush(evas);
1126     /*} else {
1127     evas_object_hide(win);
1128     }*/
1129     //LOGD("HIDE_WINDOW : %p\n", window);
1130
1131     CSCLWindows *windows = CSCLWindows::get_instance();
1132     if (!windows) return;
1133
1134     SclWindowContext *window_context = windows->get_window_context(win);
1135         if (window_context && win) {
1136             if (window_context->etc_info) {
1137                 Eina_List *list = (Eina_List*)(window_context->etc_info);
1138                 Eina_List *iter = NULL;
1139                 Eina_List *iter_next = NULL;
1140                 void *data = NULL;
1141                 int iIndex = 0;
1142 #ifdef TEST_NEWBACKEND
1143 #else
1144                 EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
1145                     if (data) {
1146                         EFLObject *object = (EFLObject*)(data);
1147                         if (object) {
1148                             sclboolean bShouldRemove = FALSE;
1149                             bShouldRemove = TRUE;
1150                             if (bShouldRemove) {
1151                                 Evas_Object* eo = object->object;
1152                                 if (object->extracted) {
1153                                     void *image_data = evas_object_image_data_get(eo, 1);
1154                                     if (image_data) {
1155                                         free(image_data);
1156                                     }
1157                                 }
1158                                 if (eo) {
1159                                     evas_object_del(eo);
1160                                     object->object = NULL;
1161                                 }
1162                                 if (object->type == EFLOBJECT_TEXTBLOCK) {
1163                                     Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
1164                                     if (st) {
1165                                         evas_textblock_style_free(st);
1166                                     }
1167 #ifdef TEST_NEWBACKEND
1168                                     for (sclint loop = 0;loop < g_TextCache.size();loop++) {
1169                                         if (g_TextCache[loop].text == object->object) {
1170                                             g_TextCache[loop].used = FALSE;
1171                                         }
1172                                     }
1173 #endif
1174                                 } else if (object->type == EFLOBJECT_IMAGE) {
1175 #ifdef TEST_NEWBACKEND
1176                                     for (sclint loop = 0;loop < g_ImageCache.size();loop++) {
1177                                         if (g_ImageCache[loop].image == object->object) {
1178                                             g_ImageCache[loop].used = FALSE;
1179                                         }
1180                                     }
1181 #endif
1182                                 }
1183                                 delete object;
1184                                 list = eina_list_remove_list(list, iter);
1185                             }
1186                         }
1187                         iIndex++;
1188                     }
1189                 }
1190                 window_context->etc_info = list;
1191 #endif
1192             }
1193         }
1194         //Evas *evas = evas_object_evas_get((Evas_Object*)win);
1195         //evas_render_idle_flush(evas);
1196     //}
1197     /*evas_image_cache_flush(evas_object_evas_get((Evas_Object*)win));
1198     elm_cache_all_flush();
1199     malloc_trim(0);*/
1200 }
1201
1202 void CSCLWindowsImplEfl::set_window_accepts_focus(const sclwindow window, sclboolean acceptable)
1203 {
1204     elm_win_prop_focus_skip_set(static_cast<Evas_Object*>(window), !acceptable);
1205 }