3eacde338ab830f9bfa4994ebe706f5b758efd65
[framework/uifw/libscl-ui.git] / scl / sclwindows.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.h"
19 #ifdef  __WIN32__
20 #include "sclwindows-win32.h"
21 #elif defined(__EFL__)
22 #include "sclwindows-efl.h"
23 #else
24 #include "sclwindows-gtk.h"
25 #endif
26 #include "scldebug.h"
27 #include "sclevents.h"
28 #include "sclresourcecache.h"
29 #include "sclcontroller.h"
30 #include "sclactionstate.h"
31 #include "sclres_manager.h"
32 #include "sclkeyfocushandler.h"
33 #include <dlog.h>
34
35 using namespace scl;
36
37 CSCLWindows::CSCLWindows()
38 {
39     SCL_DEBUG();
40
41     sclint loop;
42
43     m_impl = NULL;
44
45     memset(&m_base_window_context, 0x00, sizeof(SclWindowContext));
46     memset(&m_magnifier_window_context, 0x00, sizeof(SclWindowContext));
47     memset(&m_dim_window_context, 0x00, sizeof(SclWindowContext));
48     memset(m_popup_window_context, 0x00, sizeof(SclWindowContext) * MAX_POPUP_WINDOW);
49
50     m_pending_update = FALSE;
51
52     for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
53         m_Z_order_list[loop] = SCLWINDOW_INVALID;
54     }
55 }
56
57 CSCLWindows::~CSCLWindows()
58 {
59     SCL_DEBUG();
60
61     if (m_impl) {
62         delete m_impl;
63         m_impl = NULL;
64     }
65 }
66
67 void CSCLWindows::init()
68 {
69     int loop;
70     CSCLWindowsImpl *impl = get_scl_windows_impl();
71     if (impl) {
72         impl->init();
73     }
74     for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
75         m_Z_order_list[loop] = SCLWINDOW_INVALID;
76     }
77     m_initialized = TRUE;
78 }
79
80 void CSCLWindows::fini()
81 {
82     CSCLWindowsImpl* impl = get_scl_windows_impl();
83
84     if (impl) {
85         impl->fini();
86
87         if (SCLWINDOW_INVALID != m_base_window_context.window) {
88             impl->destroy_window(m_base_window_context.window);
89             m_base_window_context.window = SCLWINDOW_INVALID;
90         }
91
92         if (SCLWINDOW_INVALID != m_magnifier_window_context.window) {
93             impl->destroy_window(m_magnifier_window_context.window);
94             m_magnifier_window_context.window = SCLWINDOW_INVALID;
95         }
96
97         if (SCLWINDOW_INVALID != m_dim_window_context.window) {
98             impl->destroy_window(m_dim_window_context.window);
99             m_dim_window_context.window = SCLWINDOW_INVALID;
100         }
101
102         for (int loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
103             if (m_popup_window_context[loop].window != SCLWINDOW_INVALID) {
104                 if (!m_popup_window_context[loop].is_virtual) {
105                     impl->destroy_window(m_popup_window_context[loop].window);
106                 }
107                 m_popup_window_context[loop].window = SCLWINDOW_INVALID;
108             }
109         }
110     }
111
112     m_initialized = FALSE;
113 }
114
115 CSCLWindowsImpl*
116 CSCLWindows::get_scl_windows_impl()
117 {
118     if (m_impl == 0) {
119 #ifdef  __WIN32__
120         m_impl = new CSCLWindowsImplWin32;
121 #elif defined(__EFL__)
122         m_impl = new CSCLWindowsImplEfl;
123 #else
124         m_impl = new CSCLWindowsImplGtk;
125 #endif
126     }
127     return m_impl;
128 }
129
130 CSCLWindows*
131 CSCLWindows::get_instance()
132 {
133     static CSCLWindows instance;
134     return &instance;
135 }
136
137 sclwindow CSCLWindows::open_popup(const SclWindowOpener opener, const SclRectangle &geometry, sclshort inputmode, sclshort layout, SCLPopupType popup_type, sclboolean is_virtual, sclboolean use_dim_window, sclint img_offset_x, sclint img_offset_y, sclint timeout)
138 {
139     sclwindow window = SCLWINDOW_INVALID;
140
141     CSCLEvents *events = CSCLEvents::get_instance();
142     CSCLActionState *state = CSCLActionState::get_instance();
143     CSCLController *controller = CSCLController::get_instance();
144     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
145     CSCLContext *context = CSCLContext::get_instance();
146     CSCLWindows *windows = CSCLWindows::get_instance();
147     CSCLUtils *utils = CSCLUtils::get_instance();
148
149     if (events && state && controller && cache && context && windows && utils) {
150         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
151             if (m_popup_window_context[loop].window != SCLWINDOW_INVALID) {
152                 if (m_popup_window_context[loop].layout == layout) return SCLWINDOW_INVALID;
153             }
154         }
155
156         window = create_window(opener, geometry, inputmode, layout, popup_type, is_virtual, img_offset_x, img_offset_y, timeout);
157         events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
158         if (timeout > 0) {
159             events->create_timer(SCL_TIMER_POPUP_TIMEOUT, timeout, layout);
160         }
161
162         LOGD("create window (%p) x: %d, y:%d, width:%d, height:%d , layout:%d, popuptype:%d",
163             window, geometry.x, geometry.y, geometry.width, geometry.height, layout, popup_type);
164
165         events->connect_window_events(window, SCL_EVENT_MOUSE | SCL_EVENT_EXPOSE);
166         controller->handle_engine_signal(SCL_SIG_POPUP_SHOW, window);
167
168         /* Shows the dim window if it uses the dim_window */
169         if (use_dim_window) {
170             sclwindow dim_window = get_dim_window();
171
172             /* Currently, get_window_rect does not work normally (need to check X). So I have commented it*/
173             SclRectangle rect;
174             get_window_rect(get_base_window(), &rect);
175             resize_window(dim_window, rect.width, rect.height);
176             move_window(dim_window, rect.x, rect.y);
177             events->connect_window_events(dim_window, SCL_EVENT_MOUSE);
178             /*If we use transient_for them the ISE will occure some crash. It needs to check X11*/
179             set_parent(opener.window, dim_window);
180             SclWindowContext *dim_window_context = get_window_context(get_dim_window());
181             if (dim_window_context) {
182                 if (dim_window_context->is_virtual) {
183                     set_parent(opener.window, window);
184                 } else {
185                     set_parent(dim_window, window);
186                 }
187             }
188             show_window(dim_window);
189         } else {
190             /*If we use transient_for them the ISE will occure some crash. It needs to check X11*/
191             set_parent(opener.window, window);
192         }
193         show_window(window);
194
195         push_window_in_Z_order_list(window);
196
197         state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
198
199         const SclLayout *cur_layout = cache->get_cur_layout(window);
200         if (cur_layout) {
201             /* If the newly opened popup window has POPUP_GRAB style, lets press the nearest button on the new window */
202             if (cur_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
203                 sclwindow pressed_window = context->get_cur_pressed_window(context->get_last_touch_device_id());
204                 sclbyte pressed_key = context->get_cur_pressed_key(context->get_last_touch_device_id());
205
206                 const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
207
208                 sclwindow moving_window = context->get_cur_moving_window(context->get_last_touch_device_id());
209                 SclPoint moving_point = context->get_cur_moving_point(context->get_last_touch_device_id());
210                 SclWindowContext *moving_window_context = windows->get_window_context(moving_window);
211                 SclWindowContext *popup_window_context = windows->get_window_context(window);
212                 if (moving_window_context && popup_window_context) {
213                     moving_point.x =
214                         (moving_window_context->geometry.x - popup_window_context->geometry.x) + moving_point.x;
215                     moving_point.y =
216                         (moving_window_context->geometry.y - popup_window_context->geometry.y) + moving_point.y;
217                 }
218
219                 /* Find the nearest button on the autopopup window */
220                 sclboolean ended = FALSE;
221                 sclfloat min_dist = (float)((sclu32)(-1));
222                 sclint min_dist_index = NOT_USED;
223                 for (sclint loop = 0;loop < MAX_KEY && !ended;loop++) {
224                     SclButtonContext *popup_button_context = cache->get_cur_button_context(window, loop);
225                     const SclLayoutKeyCoordinate *popup_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
226                     if (popup_button_context && popup_coordinate) {
227                         if (!(popup_button_context->used)) {
228                             ended = TRUE;
229                         } else if (popup_button_context->state != BUTTON_STATE_DISABLED &&
230                             popup_coordinate->button_type != BUTTON_TYPE_UIITEM) {
231                                 if (popup_coordinate) {
232                                     float dist = utils->get_approximate_distance(moving_point.x, moving_point.y,
233                                         popup_coordinate->x + (popup_coordinate->width / 2) -
234                                         cur_layout->mouse_manipulate_x,
235                                         popup_coordinate->y + (popup_coordinate->height / 2) -
236                                         cur_layout->mouse_manipulate_y);
237                                     if (dist < min_dist) {
238                                         min_dist_index = loop;
239                                         min_dist = dist;
240                                     }
241                                 }
242                         }
243                     }
244                 }
245                 /* When we found the nearest button, make it pressed */
246                 if (min_dist_index != NOT_USED) {
247                     const SclLayoutKeyCoordinate *popup_coordinate =
248                         cache->get_cur_layout_key_coordinate(window, min_dist_index);
249                     if (popup_coordinate) {
250                         sclint x = popup_coordinate->x + (popup_coordinate->width / 2) -
251                             cur_layout->mouse_manipulate_x;
252                         sclint y = popup_coordinate->y + (popup_coordinate->height / 2) -
253                             cur_layout->mouse_manipulate_y;
254                         controller->mouse_press(window, x, y, context->get_last_touch_device_id());
255                     }
256                 }
257
258                 /* The below code block seems unnecessary since we already invoked mouse_press() */
259                 /*context->set_cur_pressed_window(context->get_last_touch_device_id(), window);
260                 context->set_cur_pressed_key(context->get_last_touch_device_id(), min_dist_index);
261                 if (button_context) {
262                     button_context->state = BUTTON_STATE_NORMAL;
263                 }*/
264
265                 windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
266             }
267         }
268     }
269
270     return window;
271 }
272
273 bool CSCLWindows::close_popup(sclwindow window)
274 {
275     LOGD("close_popup window (%p)",window);
276
277     CSCLKeyFocusHandler *focus_handler = CSCLKeyFocusHandler::get_instance();
278     if (focus_handler) {
279         focus_handler->popup_closed(window);
280     }
281     pop_window_in_Z_order_list(window);
282
283     hide_window(get_dim_window());
284     hide_window(window);
285     return destroy_window(window);
286 }
287
288 bool CSCLWindows::close_all_popups(sclwindow skip_window /* = SCLWINDOW_INVALID */)
289 {
290     sclboolean all_closed = TRUE;
291     /* Close all the popup windows except the targetWindow */
292     int loop = 0;
293     sclwindow window;
294     do {
295         window = get_nth_popup_window(loop);
296         if (window) {
297             if (window != skip_window) {
298                 close_popup(window);
299             } else {
300                 all_closed = FALSE;
301             }
302         }
303         loop++;
304     } while (window);
305
306     /* If there is a popup still opened, don't destroy POPUP_TIMEOUT timer */
307     return all_closed;
308 }
309
310 sclwindow
311 CSCLWindows::create_base_window(const sclwindow parent, scl16 width, scl16 height)
312 {
313     SCL_DEBUG();
314
315     if (m_initialized) {
316         m_base_window_context.hidden = TRUE;
317         m_base_window_context.geometry.width = width;
318         m_base_window_context.geometry.height = height;
319         m_base_window_context.is_virtual = FALSE;
320         m_base_window_context.popup_type = POPUP_TYPE_NONE;
321         m_base_window_context.opener.window = parent;
322         m_base_window_context.geometry.x = m_base_window_context.geometry.y = 0;
323         m_base_window_context.etc_info = NULL;
324         m_base_window_context.window =
325             get_scl_windows_impl()->create_base_window(parent, &m_base_window_context, width, height);
326
327         push_window_in_Z_order_list(m_base_window_context.window);
328     }
329
330     // Update the position information
331     //get_window_context(parent, TRUE);
332
333     return m_base_window_context.window;
334 }
335
336 /**
337  * Creates a new top-level window
338  *
339  * @Code
340  *  CSCLGwes* gwes = CSCLGwes::get_instance();
341  *  sclwindow popupWindow = gwes->m_windows->create_window(window, 100, 500, 200, 100, 4, POPUP_TYPE_BTN_RELEASE_POPUP, FALSE);
342  *  if (popupWindow != NULL) {
343  *     gwes->m_events->connect_window_events(popupWindow, SCL_EVENT_MOUSE | SCL_EVENT_EXPOSE);
344  *      cache->recompute_layout(popupWindow);
345  *      gwes->m_windows->show_window(popupWindow);
346  *  }
347  */
348 sclwindow
349 CSCLWindows::create_window(const SclWindowOpener opener, const SclRectangle &geometry, sclshort inputmode, sclshort layout, SCLPopupType popup_type, sclboolean is_virtual, sclint img_offset_x, sclint img_offset_y, sclint timeout)
350 {
351     SCL_DEBUG();
352
353     CSCLWindowsImpl* impl = get_scl_windows_impl();
354     sclwindow window = SCLWINDOW_INVALID;
355
356     if (impl) {
357         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
358             if (m_popup_window_context[loop].window == SCLWINDOW_INVALID) {
359                 m_popup_window_context[loop].hidden = TRUE;
360                 m_popup_window_context[loop].opener = opener;
361                 m_popup_window_context[loop].etc_info = NULL;
362                 m_popup_window_context[loop].inputmode = inputmode;
363                 m_popup_window_context[loop].layout = layout;
364                 m_popup_window_context[loop].popup_type = popup_type;
365                 m_popup_window_context[loop].is_virtual = is_virtual;
366
367                 m_popup_window_context[loop].geometry = geometry;
368
369                 m_popup_window_context[loop].layout_image_offset.x = img_offset_x;
370                 m_popup_window_context[loop].layout_image_offset.y = img_offset_y;
371
372                 m_popup_window_context[loop].timeout = timeout;
373
374                 if (!is_virtual) {
375                     window = impl->create_window(opener.window,
376                         &(m_popup_window_context[loop]), geometry.width, geometry.height);
377                 } else {
378                     window = reinterpret_cast<sclwindow>(loop + 1);
379                 }
380                 if (window) {
381                     m_popup_window_context[loop].window = window;
382                 }
383                 //set_window_rotation(window, context->get_rotation_degree());
384                 if (!m_popup_window_context[loop].is_virtual) {
385                     impl->move_window(window, geometry.x, geometry.y);
386                 }
387                 break;
388             }
389         }
390
391         // Update the position information
392         //get_window_context(window, TRUE);
393
394         if (window == NULL) {
395             LOGW("Failed to create a new window. The size of window buffer has exeeded.");
396         }
397     }
398     return window;
399 }
400
401 sclwindow
402 CSCLWindows::create_magnifier_window(const sclwindow parent, scl16 x, scl16 y, scl16 width, scl16 height)
403 {
404     SCL_DEBUG();
405
406     CSCLWindowsImpl* impl = get_scl_windows_impl();
407     sclwindow window = SCLWINDOW_INVALID;
408
409     if (impl && m_initialized) {
410         if (m_magnifier_window_context.window == SCLWINDOW_INVALID) {
411             window = impl->create_magnifier_window(parent, &m_magnifier_window_context, width, height);
412             impl->set_keep_above(window, TRUE);
413             if (window) {
414                 m_magnifier_window_context.window = window;
415                 m_magnifier_window_context.geometry.width = width;
416                 m_magnifier_window_context.geometry.height = height;
417                 m_magnifier_window_context.hidden = TRUE;
418             }
419         } else {
420             window = m_magnifier_window_context.window;
421         }
422         set_parent(parent, window);
423
424         if (window == NULL) {
425             LOGW("Failed to create a new window. The size of window buffer has exeeded.");
426         } else {
427             LOGD("Magnifier Window %p created", window);
428         }
429     }
430
431     // Update the position information
432     //get_window_context(window, TRUE);
433
434     return window;
435 }
436
437 sclwindow
438 CSCLWindows::get_magnifier_window()
439 {
440     SCL_DEBUG();
441     return m_magnifier_window_context.window;
442 }
443
444 sclwindow
445 CSCLWindows::create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
446 {
447     SCL_DEBUG();
448
449     CSCLWindowsImpl* impl = get_scl_windows_impl();
450     sclwindow window = SCLWINDOW_INVALID;
451
452     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
453     PSclDefaultConfigure default_configure = NULL;
454     if (sclres_manager) {
455         default_configure = sclres_manager->get_default_configure();
456     }
457
458     if (impl && m_initialized && default_configure) {
459         if (m_dim_window_context.window == NULL) {
460             m_dim_window_context.hidden = TRUE;
461             if (default_configure->use_actual_dim_window) {
462                 window = impl->create_dim_window(parent, &m_dim_window_context, width, height);
463             } else {
464                 window = reinterpret_cast<sclwindow>(SCLWINDOW_VIRTUAL_DIM);
465                 m_dim_window_context.is_virtual = TRUE;
466             }
467             if (window) {
468                 m_dim_window_context.window = window;
469             }
470         } else {
471             window = m_dim_window_context.window;
472         }
473
474         if (window == NULL) {
475             LOGW("Failed to create a new window. The size of window buffer has exeeded");
476         }
477     }
478
479     return window;
480 }
481
482 sclwindow
483 CSCLWindows::get_dim_window()
484 {
485     SCL_DEBUG();
486     return m_dim_window_context.window;
487 }
488
489 bool
490 CSCLWindows::destroy_window(sclwindow window)
491 {
492     SCL_DEBUG();
493
494     CSCLWindowsImpl* impl = get_scl_windows_impl();
495     sclboolean ret = FALSE;
496
497     if (impl) {
498         if (window == m_base_window_context.window) {
499             impl->destroy_window(window);
500             memset(&m_base_window_context, 0x00, sizeof(SclWindowContext));
501             m_base_window_context.window = SCLWINDOW_INVALID;
502             ret = TRUE;
503         } else if (window == m_magnifier_window_context.window) {
504             impl->destroy_window(window);
505             memset(&m_magnifier_window_context, 0x00, sizeof(SclWindowContext));
506             m_magnifier_window_context.window = SCLWINDOW_INVALID;
507             ret = TRUE;
508         } else if (window == m_dim_window_context.window) {
509             impl->destroy_window(window);
510             memset(&m_dim_window_context, 0x00, sizeof(SclWindowContext));
511             m_dim_window_context.window = SCLWINDOW_INVALID;
512             ret = TRUE;
513         } else {
514             for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
515                 if (m_popup_window_context[loop].window == window) {
516                     impl->destroy_window(window);
517                     memset(&m_popup_window_context[loop], 0x00, sizeof(SclWindowContext));
518                     ret = TRUE;
519                     m_popup_window_context[loop].window = SCLWINDOW_INVALID;
520                     break;
521                 }
522             }
523         }
524     }
525
526     return ret;
527 }
528
529 sclwindow
530 CSCLWindows::get_base_window()
531 {
532     SCL_DEBUG();
533
534     return m_base_window_context.window;
535 }
536
537 sclboolean
538 CSCLWindows::is_base_window(sclwindow window)
539 {
540     SCL_DEBUG();
541
542     sclboolean ret = FALSE;
543
544     if (window != SCLWINDOW_INVALID) {
545         if (window == m_base_window_context.window) {
546             ret = TRUE;
547         }
548     }
549
550     return ret;
551 }
552
553 sclwindow
554 CSCLWindows::find_by_etcinfo( void* etc_info )
555 {
556     SCL_DEBUG();
557
558     sclwindow ret = SCLWINDOW_INVALID;
559
560     if (etc_info == m_base_window_context.etc_info) {
561         ret = m_base_window_context.window;
562     } else if (etc_info == m_magnifier_window_context.etc_info) {
563         ret = m_magnifier_window_context.window;
564     } else if (etc_info == m_dim_window_context.etc_info) {
565         ret = m_dim_window_context.window;
566     } else {
567         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
568             if (etc_info == m_popup_window_context[loop].etc_info) {
569                 ret = m_popup_window_context[loop].window;
570                 break;
571             }
572         }
573     }
574
575     return ret;
576 }
577
578 SclWindowContext*
579 //CSCLWindows::get_window_context(sclwindow window, sclboolean geometry_update)
580 CSCLWindows::get_window_context(sclwindow window)
581 {
582     SCL_DEBUG();
583
584     SclWindowContext* ret = NULL;
585
586     if (window == m_base_window_context.window) {
587         /*if (geometry_update) {
588             SclRectangle rect;
589             get_window_rect(window, &rect);
590             m_base_window_context.geometry.x = rect.x;
591             m_base_window_context.geometry.y = rect.y;
592         }*/
593         ret = &m_base_window_context;
594     } else if (window == m_magnifier_window_context.window) {
595         ret = &m_magnifier_window_context;
596     } else if (window == m_dim_window_context.window) {
597         ret = &m_dim_window_context;
598     } else {
599         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
600             if (m_popup_window_context[loop].window == window) {
601                 /*if (geometry_update) {
602                     SclRectangle rect;
603                     get_window_rect(window, &rect);
604                     m_popup_window_context[loop].geometry.x = rect.x;
605                     m_popup_window_context[loop].geometry.y = rect.y;
606                 }*/
607                 ret = &m_popup_window_context[loop];
608                 break;
609             }
610         }
611     }
612
613     return ret;
614 }
615
616 void
617 CSCLWindows::set_window_context(sclwindow window, SclWindowContext* context)
618 {
619     SCL_DEBUG();
620
621     if (window == m_base_window_context.window) {
622         memcpy(&m_base_window_context,context, sizeof(SclWindowContext));
623     } else {
624         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
625             if (m_popup_window_context[loop].window == window) {
626                 memcpy(&m_popup_window_context[loop], context, sizeof(SclWindowContext));
627                 break;
628             }
629         }
630     }
631 }
632
633 scl8
634 CSCLWindows::find_popup_window_index(sclwindow window)
635 {
636     SCL_DEBUG();
637
638     scl8 ret = NOT_USED;
639
640     for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
641         if (m_popup_window_context[loop].window == window) {
642             ret = loop;
643             break;
644         }
645     }
646
647     return ret;
648 }
649
650 void
651 CSCLWindows::move_window(const sclwindow window, scl16 x, scl16 y)
652 {
653     SCL_DEBUG();
654
655     sclboolean is_virtual = FALSE;
656     if (window == m_base_window_context.window) {
657         m_base_window_context.geometry.x = x;
658         m_base_window_context.geometry.y = y;
659         is_virtual = m_base_window_context.is_virtual;
660     } else if (window == m_magnifier_window_context.window) {
661         m_magnifier_window_context.geometry.x = x;
662         m_magnifier_window_context.geometry.y = y;
663         is_virtual = m_magnifier_window_context.is_virtual;
664     } else if (window == m_dim_window_context.window) {
665         m_dim_window_context.geometry.x = x;
666         m_dim_window_context.geometry.y = y;
667         is_virtual = m_dim_window_context.is_virtual;
668     } else {
669         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
670             if (m_popup_window_context[loop].window == window) {
671                 m_popup_window_context[loop].geometry.x = x;
672                 m_popup_window_context[loop].geometry.y = y;
673                 is_virtual = m_popup_window_context[loop].is_virtual;
674                 break;
675             }
676         }
677     }
678     if (!is_virtual) {
679         CSCLWindowsImpl* impl = get_scl_windows_impl();
680         if (impl) {
681             impl->move_window(window, x, y);
682         }
683     }
684 }
685
686 void
687 CSCLWindows::resize_window(const sclwindow window, scl16 width, scl16 height)
688 {
689     SCL_DEBUG();
690
691     sclboolean is_virtual = FALSE;
692     if (window == m_base_window_context.window) {
693         m_base_window_context.geometry.width = width;
694         m_base_window_context.geometry.height = height;
695         is_virtual = m_base_window_context.is_virtual;
696     } else if (window == m_magnifier_window_context.window) {
697         m_magnifier_window_context.geometry.width = width;
698         m_magnifier_window_context.geometry.height = height;
699         is_virtual = m_magnifier_window_context.is_virtual;
700     } else if (window == m_dim_window_context.window) {
701         m_dim_window_context.geometry.width = width;
702         m_dim_window_context.geometry.height = height;
703         is_virtual = m_dim_window_context.is_virtual;
704     } else {
705         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
706             if (m_popup_window_context[loop].window == window) {
707                 m_popup_window_context[loop].geometry.width = width;
708                 m_popup_window_context[loop].geometry.height = height;
709                 is_virtual = m_popup_window_context[loop].is_virtual;
710                 break;
711             }
712         }
713     }
714     if (!is_virtual) {
715         CSCLWindowsImpl* impl = get_scl_windows_impl();
716         if (impl) {
717             impl->resize_window(window, width, height);
718         }
719     }
720 }
721
722 void
723 CSCLWindows::move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height)
724 {
725     SCL_DEBUG();
726
727     sclboolean is_virtual = FALSE;
728     if (window == m_base_window_context.window) {
729         m_base_window_context.geometry.x = x;
730         m_base_window_context.geometry.y = y;
731         m_base_window_context.geometry.width = width;
732         m_base_window_context.geometry.height = height;
733         is_virtual = m_base_window_context.is_virtual;
734     } else if (window == m_magnifier_window_context.window) {
735         m_magnifier_window_context.geometry.x = x;
736         m_magnifier_window_context.geometry.y = y;
737         m_magnifier_window_context.geometry.width = width;
738         m_magnifier_window_context.geometry.height = height;
739         is_virtual = m_magnifier_window_context.is_virtual;
740     } else if (window == m_dim_window_context.window) {
741         m_dim_window_context.geometry.x = x;
742         m_dim_window_context.geometry.y = y;
743         m_dim_window_context.geometry.width = width;
744         m_dim_window_context.geometry.height = height;
745         is_virtual = m_dim_window_context.is_virtual;
746     } else {
747         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
748             if (m_popup_window_context[loop].window == window) {
749                 m_popup_window_context[loop].geometry.x = x;
750                 m_popup_window_context[loop].geometry.y = y;
751                 m_popup_window_context[loop].geometry.width = width;
752                 m_popup_window_context[loop].geometry.height = height;
753                 is_virtual = m_popup_window_context[loop].is_virtual;
754                 break;
755             }
756         }
757     }
758     if (!is_virtual) {
759         CSCLWindowsImpl* impl = get_scl_windows_impl();
760         if (impl) {
761             impl->move_resize_window(window, x, y, width, height);
762         }
763     }
764 }
765
766
767 /* Push given window into a Z-order list */
768 void CSCLWindows::push_window_in_Z_order_list(sclwindow window)
769 {
770     SCL_DEBUG();
771
772     sclint loop;
773
774     for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
775         if (m_Z_order_list[loop] == SCLWINDOW_INVALID) {
776             m_Z_order_list[loop] = window;
777             return;
778         }
779     }
780 }
781
782 /* Pop given window from a Z-order list */
783 void CSCLWindows::pop_window_in_Z_order_list(sclwindow window)
784 {
785     SCL_DEBUG();
786
787     sclint loop;
788     sclboolean found = FALSE;
789
790     for (loop = 0;loop < MAX_ZORDER_NUM - 1;loop++) {
791         if (m_Z_order_list[loop] == window || found) {
792             found = TRUE;
793             m_Z_order_list[loop] = m_Z_order_list[loop + 1];
794         }
795     }
796
797     m_Z_order_list[MAX_ZORDER_NUM - 1] = SCLWINDOW_INVALID;
798 }
799
800 /* Search n-th window in the Z-order stack, starting from the top (TOPMOST window would be the 0 index) */
801 sclwindow CSCLWindows::get_nth_window_in_Z_order_list(sclbyte index)
802 {
803     SCL_DEBUG();
804
805     sclint loop;
806
807     for (loop = MAX_ZORDER_NUM - 1;loop >= 0;loop--) {
808         if (m_Z_order_list[loop] != SCLWINDOW_INVALID) {
809             if (index == 0) {
810                 return m_Z_order_list[loop];
811             }
812             index--;
813         }
814     }
815
816     return SCLWINDOW_INVALID;
817 }
818
819 sclwindow CSCLWindows::get_nth_popup_window( sclbyte index )
820 {
821     SCL_DEBUG();
822
823     scl_assert_return_null(index >= 0 && index < MAX_POPUP_WINDOW);
824
825     if (index < MAX_POPUP_WINDOW) {
826         return m_popup_window_context[index].window;
827     }
828
829     return SCLWINDOW_INVALID;
830 }
831
832 sclbyte CSCLWindows::get_Z_order(sclwindow window)
833 {
834     SCL_DEBUG();
835
836     sclbyte loop;
837     for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
838         if (m_Z_order_list[loop] == window) {
839             return loop;
840         }
841     }
842     return NOT_USED;
843 }
844
845 void CSCLWindows::set_parent( const sclwindow parent, const sclwindow window )
846 {
847     /* Do not set parent if the window is a virtual window */
848     //SclWindowContext *window_context = get_window_context(window, FALSE);
849     SclWindowContext *window_context = get_window_context(window);
850     if (window_context) {
851         if (!(window_context->is_virtual)) {
852             CSCLWindowsImpl* impl = get_scl_windows_impl();
853             if (impl) {
854                 impl->set_parent(parent, window);
855             }
856         }
857     }
858 }
859
860 void CSCLWindows::set_window_rotation(const sclwindow window, SCLRotation rotation)
861 {
862     SCL_DEBUG();
863
864     CSCLWindowsImpl* impl = get_scl_windows_impl();
865
866     if (impl) {
867         if (window == NULL) {
868             impl->set_window_rotation(m_base_window_context.window, rotation);
869             if (SCLWINDOW_INVALID != m_magnifier_window_context.window) {
870                 CSCLUtils *utils = CSCLUtils::get_instance();
871
872                 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
873                 PSclMagnifierWndConfigure magnifier_configure = NULL;
874                 if (sclres_manager) {
875                     magnifier_configure = sclres_manager->get_magnifier_configure();
876                 }
877                 if (magnifier_configure) {
878                     m_magnifier_window_context.geometry.width =
879                         magnifier_configure->width * utils->get_custom_scale_rate_x();
880                     m_magnifier_window_context.geometry.height =
881                         magnifier_configure->height * utils->get_custom_scale_rate_y();
882
883                     impl->set_window_rotation(m_magnifier_window_context.window, rotation);
884                 }
885             }
886
887             if (SCLWINDOW_INVALID != m_dim_window_context.window) {
888                 /* For indivisual window rotation */
889                 impl->set_window_rotation(m_dim_window_context.window, rotation);
890                 //resize_window(m_dim_window_context.window, m_base_window_context.width, m_base_winctx.height);
891                 //move_window(m_dim_window_context.window, m_base_window_context.x, m_base_winctx.y);
892                 hide_window(m_dim_window_context.window);
893             }
894             /* For indivisual window rotation
895             for (int loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
896                 if (m_popup_window_context[loop].window != SCLWINDOW_INVALID) {
897                     if (!m_popup_window_context[loop].isVirtual) {
898                         get_scl_windows_impl()->set_window_rotation(m_popup_window_context[loop].window, degree);
899                     }
900                 }
901             }
902             */
903         } else {
904             impl->set_window_rotation(window, rotation);
905             LOGD("## set_window_rotation : %d", rotation);
906         }
907     }
908
909     // Update the position information
910     //get_window_context(window, TRUE);
911     SclWindowContext *window_context = get_window_context(window);
912     if (window_context) {
913         get_window_rect(window, &(window_context->geometry));
914     }
915 }
916
917
918 void
919 CSCLWindows::show_window(const sclwindow window, sclboolean queue /*= FALSE*/)
920 {
921     SCL_DEBUG();
922
923     if (window == m_base_window_context.window) {
924         m_base_window_context.hidden = FALSE;
925     } else if (window == m_magnifier_window_context.window) {
926         m_magnifier_window_context.hidden = FALSE;
927     } else if (window == m_dim_window_context.window) {
928         m_dim_window_context.hidden = FALSE;
929     } else {
930         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
931             if (m_popup_window_context[loop].window == window) {
932                 m_popup_window_context[loop].hidden = FALSE;
933                 break;
934             }
935         }
936     }
937
938     CSCLWindowsImpl* impl = get_scl_windows_impl();
939     if (impl) {
940         impl->show_window(window, queue);
941     }
942 }
943
944 void
945 CSCLWindows::hide_window(const sclwindow window, sclboolean force /*= FALSE*/)
946 {
947     SCL_DEBUG();
948
949     if (window == m_base_window_context.window) {
950         m_base_window_context.hidden = TRUE;
951     } else if (window == m_magnifier_window_context.window) {
952         m_magnifier_window_context.hidden = TRUE;
953     } else if (window == m_dim_window_context.window) {
954         m_dim_window_context.hidden = TRUE;
955     } else {
956         for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
957             if (m_popup_window_context[loop].window == window) {
958                 m_popup_window_context[loop].hidden = TRUE;
959                 break;
960             }
961         }
962     }
963
964     CSCLWindowsImpl* impl = get_scl_windows_impl();
965     if (impl) {
966         impl->hide_window(window, force);
967     }
968 }
969
970 void
971 CSCLWindows::set_keep_above(const sclwindow window, sclboolean keep_above)
972 {
973     CSCLWindowsImpl* impl = get_scl_windows_impl();
974     if (impl) {
975         impl->set_keep_above(window, keep_above);
976     }
977 }
978
979 void
980 CSCLWindows::set_update_pending(sclboolean pend)
981 {
982     m_pending_update = pend;
983     if (!pend) {
984         update_window(m_base_window_context.window);
985     }
986 }
987
988 sclboolean
989 CSCLWindows::get_update_pending()
990 {
991     return m_pending_update;
992 }
993
994 void
995 CSCLWindows::update_window(const sclwindow window,
996                            scl16 x /*= 0*/, scl16 y /*= 0*/, scl16 width /*= 0*/, scl16 height /*= 0*/ )
997 {
998     if (!m_pending_update) {
999         CSCLWindowsImpl* impl = get_scl_windows_impl();
1000         if (impl) {
1001             impl->update_window(window, x, y, width, height);
1002         }
1003     }
1004 }
1005
1006 sclboolean
1007 CSCLWindows::get_window_rect(const sclwindow window, SclRectangle *rect) {
1008     SCL_DEBUG();
1009
1010     sclboolean is_virtual = FALSE;
1011     sclboolean ret = FALSE;
1012     if (rect) {
1013         if (window == m_base_window_context.window) {
1014             is_virtual = m_base_window_context.is_virtual;
1015             if (is_virtual) {
1016                 *rect = m_base_window_context.geometry;
1017             }
1018         } else if (window == m_magnifier_window_context.window) {
1019             is_virtual = m_magnifier_window_context.is_virtual;
1020             if (is_virtual) {
1021                 *rect = m_magnifier_window_context.geometry;
1022             }
1023         } else if (window == m_dim_window_context.window) {
1024             is_virtual = m_dim_window_context.is_virtual;
1025             if (is_virtual) {
1026                 *rect = m_dim_window_context.geometry;
1027             }
1028         } else {
1029             for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
1030                 if (m_popup_window_context[loop].window == window) {
1031                     is_virtual = m_popup_window_context[loop].is_virtual;
1032                     if (is_virtual) {
1033                         *rect = m_popup_window_context[loop].geometry;
1034                     }
1035                     break;
1036                 }
1037             }
1038         }
1039     }
1040     if (!is_virtual) {
1041          CSCLWindowsImpl* impl = get_scl_windows_impl();
1042          if (impl) {
1043              ret = impl->get_window_rect(window, rect);
1044          }
1045     }
1046
1047     return ret;
1048 }