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