Remove unreachable code
[platform/core/uifw/libscl-ui.git] / scl / scluibuilder.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 <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "scluibuilder.h"
23 #include "scldebug.h"
24 #include "sclresourcecache.h"
25 #include "sclcontext.h"
26 #include "sclimageproxy.h"
27 #include "sclactionstate.h"
28 #include "sclkeyfocushandler.h"
29 #include "sclanimator.h"
30
31 //#include "sclresource.h"
32 #include <assert.h>
33 #include "sclres_manager.h"
34
35 using namespace scl;
36
37 //extern sclboolean g_key_spacing_off;
38
39 CSCLUIBuilder::CSCLUIBuilder()
40 {
41     SCL_DEBUG();
42
43     m_gwes = NULL;
44     m_utils = NULL;
45 }
46
47 CSCLUIBuilder::~CSCLUIBuilder()
48 {
49     SCL_DEBUG();
50     m_gwes = NULL;
51     m_utils = NULL;
52 }
53
54 CSCLUIBuilder*
55 CSCLUIBuilder::get_instance()
56 {
57     static CSCLUIBuilder instance;
58     return &instance;
59 }
60
61 void
62 CSCLUIBuilder::init(sclwindow parent)
63 {
64     SCL_DEBUG();
65
66     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
67
68     m_gwes = CSCLGwes::get_instance();
69     m_utils = CSCLUtils::get_instance();
70     /* It will create the base window */
71
72     scl8 mode = NOT_USED;
73     sclint layout = NOT_USED;
74     SCLDisplayMode display_mode = DISPLAYMODE_PORTRAIT;
75
76     PSclDefaultConfigure default_configure = NULL;
77     PSclMagnifierWndConfigure magnifier_configure = NULL;
78     if (m_gwes && m_utils && sclres_manager) {
79         PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
80         PSclLayout sclres_layout = sclres_manager->get_layout_table();
81
82         assert(sclres_input_mode_configure != NULL);
83         assert(sclres_layout != NULL);
84
85         default_configure = sclres_manager->get_default_configure();
86         magnifier_configure = sclres_manager->get_magnifier_configure();
87         if (default_configure) {
88             display_mode = default_configure->display_mode;
89             mode = sclres_manager->get_inputmode_id(default_configure->input_mode);
90         }
91         /* Make sure these variables does not exceed the size of our array */
92         if (!scl_check_arrindex(mode, MAX_SCL_INPUT_MODE) ||
93             !scl_check_arrindex(mode, sclres_manager->get_inputmode_size())) {
94             mode = 0;
95         }
96         if (!scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
97             display_mode = DISPLAYMODE_PORTRAIT;
98         }
99
100         layout = sclres_manager->get_layout_id(sclres_input_mode_configure[mode].layouts[display_mode]);
101         if (layout < 0 || !scl_check_arrindex_unsigned(layout, MAX_SCL_LAYOUT) ||
102             !scl_check_arrindex_unsigned(layout, sclres_manager->get_layout_size())) {
103             layout = 0;
104         }
105
106         if (m_utils) {
107             m_gwes->init(parent,
108                         m_utils->get_scaled_x(sclres_layout[layout].width),
109                         m_utils->get_scaled_y(sclres_layout[layout].height));
110         }
111
112         CSCLContext *context = CSCLContext::get_instance();
113         if (context) {
114             context->set_display_mode(display_mode);
115             context->set_input_mode(mode);
116             context->set_base_layout(sclres_manager->get_layout_id(sclres_input_mode_configure[mode].layouts[display_mode]));
117         }
118
119         CSCLResourceCache *cache = CSCLResourceCache::get_instance();
120         sclwindow window = SCLWINDOW_INVALID;
121         if (m_gwes->m_windows)
122             window = m_gwes->m_windows->get_base_window();
123
124         if (cache)
125             cache->recompute_layout(window);
126
127         /* Creates the magnifier window */
128         if (default_configure && magnifier_configure) {
129             if (default_configure->use_magnifier_window) {
130                 if (m_gwes->m_windows && m_gwes->m_events) {
131                     sclwindow magnifier_window = m_gwes->m_windows->create_magnifier_window(parent, 0, 0,
132                         magnifier_configure->width, magnifier_configure->height);
133                     m_gwes->m_events->connect_window_events(magnifier_window, SCL_EVENT_EXPOSE | SCL_EVENT_MOUSE);
134                 }
135             }
136         }
137
138         /* Creates the dim window */
139         /* FIXME */
140         //if (scl_check_arrindex(defaultLayoutIdx, MAX_LAYOUT)) {
141         if (m_gwes->m_windows)
142             m_gwes->m_windows->create_dim_window(window, NULL, sclres_layout[layout].width, sclres_layout[layout].height);
143
144         /* m_gwes->m_events->set_touch_event_offset(scl_default_configure.touch_offset);*/
145         /*Moved to Show Layout*/
146
147         /* For testing pre-image load */
148         /*CSCLImageProxy *proxy = CSCLImageProxy::get_instance();
149         sclchar composed_path[_POSIX_PATH_MAX] = {0,};
150         for (sclint loop = 0; loop < MAX_PRELOAD_IMG_CNT; loop++) {
151             memset(composed_path, 0x00, sizeof(sclchar)*_POSIX_PATH_MAX);
152             m_utils->get_composed_path(composed_path, scl_preload_image[loop]);
153             proxy->get_image(composed_path);
154         }*/
155     }
156 }
157
158 /**
159  * Shows the current layout and contexts
160  * This function will be called by expose event and invalidate rect
161  */
162 sclboolean
163 CSCLUIBuilder::show_layout(const sclwindow window, const scl16 x, const scl16 y, const scl16 width, const scl16 height)
164 {
165     SCL_DEBUG();
166
167     sclboolean ret = FALSE;
168
169     CSCLEvents *events = CSCLEvents::get_instance();
170     CSCLWindows *windows = CSCLWindows::get_instance();
171     CSCLGraphics *graphics = CSCLGraphics::get_instance();
172     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
173     CSCLContext *context = CSCLContext::get_instance();
174     CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
175
176     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
177     PSclDefaultConfigure default_configure = NULL;
178     if (sclres_manager) {
179         default_configure = sclres_manager->get_default_configure();
180     }
181     if (events && windows && graphics && cache && context && focus_handler && default_configure) {
182     /* FIXME : The draw_ctx should be acquired from the base window also, if the target window is virtual
183        However, for ease of developement, leave the drawctx to be acquired from the target window for now
184        Should modify the EFLObject list management routine after fixing the issue described above
185     */
186         scldrawctx draw_ctx = graphics->begin_paint(window);
187         SCLDisplayMode display_mode =  context->get_display_mode();
188         events->set_touch_event_offset(default_configure->touch_offset[display_mode]);
189
190         if (window == windows->get_magnifier_window()) {
191             /* For the magnifier window */
192             ret = show_magnifier(window, draw_ctx);
193         } else if (window == windows->get_dim_window()) {
194             SclWindowContext *dim_window_context = windows->get_window_context(window);
195             if (dim_window_context) {
196                 SclSize size;
197                 SclColor color;
198                 size.width = dim_window_context->geometry.width;
199                 size.height = dim_window_context->geometry.height;
200                 color = default_configure->dim_color;
201                 draw_window_bg_by_sw(window, draw_ctx, size, 0.0, color, color);
202                 /*sclchar composed_path[_POSIX_PATH_MAX] = {0,};
203                 const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
204                 m_utils->get_composed_path(composed_path, layout->image_path[BUTTON_STATE_NORMAL]);
205                 graphics->draw_image(window, draw_ctx, composed_path, 0, 0, layout->width, layout->height);*/
206             }
207         } else {
208             /* For the base and popup window */
209             const SclLayout* layout = cache->get_cur_layout(window);
210             // FIXME implement later
211             // SclLayoutInfoCache *info_cache = cache->get_cur_layout_info_cache(window);
212             if (layout) {
213                 //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
214                 SclWindowContext *window_context = windows->get_window_context(window);
215                 scl_assert_return_false(layout);
216
217                 if (layout->use_sw_background) {
218                     if (window_context) {
219                         SclSize size;
220                         size.width = window_context->geometry.width;
221                         size.height = window_context->geometry.height;
222                         draw_window_bg_by_sw(window, draw_ctx, size, layout->bg_line_width, layout->bg_line_color, layout->bg_color);
223                     }
224                 } else if (layout->image_path[BUTTON_STATE_NORMAL]) {
225                     sclint targetx = 0;
226                     sclint targety = 0;
227                     /* If the target window is virtual window, let's draw it on the base window */
228                     sclwindow targetwin = window;
229                     if (window_context) {
230                         if (window_context->is_virtual) {
231                             /*SclWindowContext *base_window_context =
232                                 windows->get_window_context(windows->get_base_window(), FALSE);*/
233                             SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
234                             if (base_window_context) {
235                                 targetwin = windows->get_base_window();
236                                 targetx = window_context->geometry.x - base_window_context->geometry.x;
237                                 targety = window_context->geometry.y - base_window_context->geometry.y;
238                             }
239                         }
240                         /* Apply custom starting coordinates only to the base window, and if the option is ALL */
241                         if (windows->is_base_window(window) &&
242                             cache->get_custom_starting_coordinates_option() == SCL_STARTING_COORDINATES_OPTION_ALL) {
243                             targetx += cache->get_custom_starting_coordinates().x;
244                             targety += cache->get_custom_starting_coordinates().y;
245                         }
246                         if (strlen(layout->image_path[BUTTON_STATE_NORMAL]) > 0) {
247                             /*SclImageCachedInfo cached_info = {0, };
248                             cached_info.nine_patch_left = info_cache->bg_image_path[BUTTON_STATE_NORMAL].left;
249                             cached_info.nine_patch_right = info_cache->bg_image_path[BUTTON_STATE_NORMAL].right;
250                             cached_info.nine_patch_top = info_cache->bg_image_path[BUTTON_STATE_NORMAL].top;
251                             cached_info.nine_patch_bottom = info_cache->bg_image_path[BUTTON_STATE_NORMAL].bottom;*/
252
253                             sclchar composed_path[_POSIX_PATH_MAX] = {0, };
254                             m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, layout->image_path[BUTTON_STATE_NORMAL]);
255                             // Temporary testing for EFL backend.. Otherwise the background image covers other buttons
256                             if (window_context && (x + y + width + height == 0)) {
257                                 //graphics->draw_image(targetwin, draw_ctx, composed_path, &cached_info, targetx, targety, layout->width, layout->height, window_context->layout_image_offset.x, winctx->layout_image_offset.y, -1, -1, layout->extract_background);
258                                 graphics->draw_image(targetwin, draw_ctx, composed_path, NULL,
259                                     targetx, targety, layout->width, layout->height,
260                                     window_context->layout_image_offset.x, window_context->layout_image_offset.y,
261                                     -1, -1, layout->extract_background);
262                             }
263                         }
264                     }
265                 }
266                 draw_button_all(window, draw_ctx, x, y, width, height);
267
268                 //if (highlight_ui_enabled)
269                 if (focus_handler->get_current_focus_window() == window) {
270                     sclint startx = 0;
271                     sclint starty = 0;
272
273                     SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
274                     if (window_context && base_window_context) {
275                         if (window_context->is_virtual) {
276                             startx += (window_context->geometry.x - base_window_context->geometry.x);
277                             starty += (window_context->geometry.y - base_window_context->geometry.y);
278                         }
279                     }
280
281                     sclboolean draw_highlight_ui = TRUE;
282                     SclAnimationState *state = NULL;
283                     CSCLAnimator *animator = CSCLAnimator::get_instance();
284                     if (animator) {
285                         sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
286                         state = animator->get_animation_state(id);
287                     }
288                     if (state) {
289                         // If currently the highlight UI is being animated, don't draw it here
290                         if (state->active) {
291                             draw_highlight_ui = FALSE;
292                         }
293                     }
294
295                     if (draw_highlight_ui && context->get_highlight_ui_enabled()) {
296                         sclchar composed_path[_POSIX_PATH_MAX] = {0, };
297                         const SclLayoutKeyCoordinate *coordinate = NULL;
298                         scl8 current_key_index = focus_handler->get_current_focus_key();
299                         coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
300                         /* FIXME : Need to use highlight image */
301                         m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE);
302                         if (coordinate) {
303                             // Draw highlight
304                             graphics->draw_image(window, draw_ctx, composed_path, NULL,
305                                 startx + coordinate->x, starty + coordinate->y, coordinate->width, coordinate->height);
306                         }
307                     }
308                 }
309             }
310         }
311         graphics->end_paint(window, draw_ctx);
312     }
313
314     return ret;
315 }
316
317 /**
318  * Draws all of buttons
319  */
320 sclboolean
321 CSCLUIBuilder::draw_button_all(const sclwindow window, const scldrawctx draw_ctx, const scl16 x /* = 0 */, const scl16 y /* = 0 */, const scl16 width /* = 0 */, const scl16 height /* = 0 */)
322 {
323     SCL_DEBUG();
324     scl_assert_return_false(window);
325
326     sclboolean drawall = FALSE;
327     SclRectangle updatearea = {x, y, width, height};
328     if (x + y + width + height == 0) {
329         drawall = TRUE;
330     }
331     CSCLContext *context = CSCLContext::get_instance();
332     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
333     CSCLUtils *utils = CSCLUtils::get_instance();
334     SclLayoutKeyCoordinate* coordinate = NULL;
335     SclButtonContext* button_context = NULL;
336
337     if (context && cache && utils) {
338         for (sclint idx = 0; idx < MAX_KEY; idx++) {
339             coordinate = cache->get_cur_layout_key_coordinate(window, idx);
340             button_context = cache->get_cur_button_context(window, idx);
341             if (coordinate && button_context) {
342                 /* First check if this button is enabled in current active sublayout */
343                 sclboolean subLayoutMatch = TRUE;
344                 if (coordinate->sub_layout && context->get_cur_sublayout()) {
345                     if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
346                         subLayoutMatch = FALSE;
347                     }
348                 }
349                 if (coordinate->valid && subLayoutMatch) {
350                     SclRectangle itemrect = {coordinate->x, coordinate->y, coordinate->width, coordinate->height};
351                     if (drawall || utils->is_rect_overlap(itemrect, updatearea)) {
352                         SCLButtonState state = button_context->state;
353                         if (button_context->toggled) {
354                             state = BUTTON_STATE_TOGGLED;
355                         }
356                         if (!draw_button(window, draw_ctx, idx, state)) {
357                             break;
358                         }
359                     }
360                 }
361             }
362         }
363     }
364     return TRUE;
365 }
366
367 /**
368  * Draws the button of the given key index by type of the button
369  * @remark draw_button_all
370  */
371 sclboolean
372 CSCLUIBuilder::draw_button(const sclwindow window, scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state, const sclboolean force_draw_bg /* = FALSE */)
373 {
374     SCL_DEBUG();
375     scl_assert_return_false(window);
376     scl_assert_return_false(key_index > NOT_USED && key_index < MAX_KEY);
377     scl_assert_return_false(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
378
379     CSCLContext *context = CSCLContext::get_instance();
380     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
381     CSCLGraphics *graphics = CSCLGraphics::get_instance();
382
383     if (cache && context && graphics) {
384         SclButtonContext* button_context = cache->get_cur_button_context(window, key_index);
385
386         if (button_context) {
387             if (!button_context->used) {
388                 return FALSE;
389             }
390
391             /* creates a cairo surface if the value of the given draw_ctx is NULL */
392             sclboolean need_endpaint = FALSE;
393             if (draw_ctx == NULL) {
394                 draw_ctx = graphics->begin_paint(window);
395                 need_endpaint = TRUE;
396             }
397
398             /* FIXME : There is a case that begin_pain fails. Inspection on the root cause is needed */
399             if (draw_ctx) {
400                 SCLShiftState shift_index = context->get_shift_state();
401                 if (shift_index < 0 || shift_index >= SCL_SHIFT_STATE_MAX) shift_index = SCL_SHIFT_STATE_OFF;
402
403                 const SclLayout* layout = cache->get_cur_layout(window);
404                 const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
405
406                 /* 1. drawing the background of the button */
407                 /* check it according to the following check-list */
408                 /* check it whether uses SW style button */
409                 if (layout && coordinate) {
410                     if (layout->use_sw_button) {
411                         /* case 1 (uses Software button) */
412                         draw_button_bg_by_sw(window, draw_ctx, key_index, state);
413                     } else {
414                         /* check it whether uses an individual images */
415                         if (coordinate->bg_image_path[shift_index][state]) {
416                             if (strcmp(coordinate->bg_image_path[shift_index][state], SCL_BACKGROUND_IMAGE_STRING) != 0) {
417                                 /* case 2 (uses an indivisual image) */
418                                 draw_button_bg_by_img(window, draw_ctx, key_index, state, shift_index);
419                             } else {
420                                 /* case 3 (uses the layout background image) */
421                                 draw_button_bg_by_layoutimg(window, draw_ctx, key_index, state, shift_index);
422                             }
423                         } else if (force_draw_bg) {
424                             draw_button_bg_by_layoutimg(window, draw_ctx, key_index, state, shift_index);
425                         }
426                         /* case 4 (don't draw anything for button's background if image_path is NULL) */
427                     }
428
429                     /* 2. displaying the label of the button */
430                     draw_button_label(window, draw_ctx, key_index, state, shift_index);
431                 }
432             }
433
434             /* destrorys the cairo surface if the value of the given(parameter) draw_ctx is NULL */
435             if (need_endpaint) {
436                 graphics->end_paint(window, draw_ctx);
437             }
438         } else {
439             return FALSE;
440         }
441     }
442     return TRUE;
443 }
444
445 /**
446  * Draws labels for the target button
447  * @remark draw_button
448  */
449 sclboolean
450 CSCLUIBuilder::draw_button_label(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, SCLButtonState state, SCLShiftState shift)
451 {
452     SCL_DEBUG();
453
454     CSCLUtils *utils = CSCLUtils::get_instance();
455     CSCLWindows *windows = CSCLWindows::get_instance();
456     CSCLGraphics *graphics = CSCLGraphics::get_instance();
457     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
458     const SclLayoutKeyCoordinate* coordinate = NULL;
459
460     if (!utils || !windows || !graphics || !cache) return FALSE;
461
462     coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
463     if (coordinate) {
464         scl_assert_return_false(window);
465         scl_assert_return_false(draw_ctx);
466         scl_assert_return_false(coordinate);
467
468         /* If the target window is virtual window, let's draw it on the base window */
469         sclint targetaddx = 0;
470         sclint targetaddy = 0;
471         sclwindow targetwin = window;
472         //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
473         SclWindowContext *window_context = windows->get_window_context(window);
474         if (window_context) {
475             if (window_context->is_virtual) {
476                 //SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE);
477                 SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
478                 if (base_window_context) {
479                     targetwin = windows->get_base_window();
480                     targetaddx = window_context->geometry.x - base_window_context->geometry.x;
481                     targetaddy = window_context->geometry.y - base_window_context->geometry.y;
482                 }
483             }
484         }
485
486         /* for image label  */
487         if (coordinate->image_label_path[shift][state]) {
488             if (strlen(coordinate->image_label_path[shift][state]) > 0) {
489                 sclchar composed_path[_POSIX_PATH_MAX] = {0, };
490                 m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, coordinate->image_label_path[shift][state]);
491
492                 SclSize imgSize = m_gwes->m_graphics->get_image_size(composed_path);
493                 if (imgSize.width == 0 && imgSize.height == 0) {
494                     imgSize.width = coordinate->width;
495                     imgSize.height = coordinate->height;
496                 }
497                 imgSize.width *= m_utils->get_smallest_scale_rate() * m_utils->get_smallest_custom_scale_rate();
498                 imgSize.height *= m_utils->get_smallest_scale_rate() * m_utils->get_smallest_custom_scale_rate();
499
500                 /* Make sure the image label is not bigger than the given coordinate */
501                 if (imgSize.width > coordinate->width) {
502                     imgSize.width = coordinate->width;
503                 }
504                 if (imgSize.height > coordinate->height) {
505                     imgSize.height = coordinate->height;
506                 }
507
508                 SclPoint pos = {0, 0};
509                 const SclLabelProperties *labelproperties = cache->get_label_properties(coordinate->image_label_type, 0);
510                 if (labelproperties) {
511                     SCLLabelAlignment align = labelproperties->alignment;
512                     sclshort padding_x = labelproperties->padding_x * utils->get_custom_scale_rate_x();
513                     sclshort padding_y = labelproperties->padding_y * utils->get_custom_scale_rate_y();
514                     if (align == LABEL_ALIGN_LEFT_MIDDLE ||
515                         align == LABEL_ALIGN_CENTER_MIDDLE ||
516                         align == LABEL_ALIGN_RIGHT_MIDDLE) {
517                             pos.y = coordinate->y + ((coordinate->height - imgSize.height) / 2) + padding_y;
518                     } else if (align == LABEL_ALIGN_LEFT_BOTTOM ||
519                         align == LABEL_ALIGN_CENTER_BOTTOM ||
520                         align == LABEL_ALIGN_RIGHT_BOTTOM) {
521                             pos.y = coordinate->y + (coordinate->height - imgSize.height) - padding_y;
522                     } else {
523                         pos.y = coordinate->y + padding_y;
524                     }
525                     if (align == LABEL_ALIGN_CENTER_TOP ||
526                         align == LABEL_ALIGN_CENTER_MIDDLE ||
527                         align == LABEL_ALIGN_CENTER_BOTTOM) {
528                             pos.x = coordinate->x + ((coordinate->width - imgSize.width) / 2) + padding_x;
529                     } else if (align == LABEL_ALIGN_RIGHT_TOP ||
530                         align == LABEL_ALIGN_RIGHT_MIDDLE ||
531                         align == LABEL_ALIGN_RIGHT_BOTTOM) {
532                             pos.x = coordinate->x + (coordinate->width - imgSize.width) - padding_x;
533                     } else {
534                         pos.x = coordinate->x + padding_x;
535                     }
536                 } else {
537                     pos.x = coordinate->x + ((coordinate->width - imgSize.width) / 2);
538                     pos.y = coordinate->y + ((coordinate->height - imgSize.height) / 2);
539                 }
540
541                 /*
542                 graphics->draw_image(
543                     targetwin,
544                     draw_ctx,
545                     composed_path,
546                     pos.x + targetaddx,
547                     pos.y + targetaddy,
548                     imgSize.width,
549                     imgSize.height
550                 );*/
551                 graphics->draw_image(
552                     targetwin,
553                     draw_ctx,
554                     composed_path,
555                     NULL,
556                     pos.x + targetaddx,
557                     pos.y + targetaddy,
558                     imgSize.width,
559                     imgSize.height);
560             }
561         }
562
563         /* for text */
564         for (int idx = 0; idx < coordinate->label_count; idx++) {
565             SclFontInfo info;
566             const SclLabelProperties *labelproperties = cache->get_label_properties(coordinate->label_type, idx);
567             if (labelproperties) {
568                 const sclchar *label = coordinate->label[shift][idx];
569                 label = cache->find_substituted_string(label);
570
571                 /* If the button type is BUTTON_TYPE_ROTATION, display current keyvalue */
572                 if (idx == 0) {
573                     if (coordinate->button_type == BUTTON_TYPE_ROTATION) {
574                         SclButtonContext* button_context = cache->get_cur_button_context(window, key_index);
575                         if (button_context) {
576                             if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
577                                 label = coordinate->key_value[shift][button_context->multitap_index];
578                             }
579                         }
580                     }
581                 }
582                 if (labelproperties->font_name) {
583                     strncpy(info.font_name, labelproperties->font_name, MAX_FONT_NAME_LEN - 1);
584                     info.font_name[MAX_FONT_NAME_LEN - 1] = '\0';
585                     info.font_size = labelproperties->font_size * utils->get_smallest_custom_scale_rate();
586                     info.is_bold = info.is_italic = true;
587
588                     CSCLContext *context = CSCLContext::get_instance();
589                     SCLShiftState shiftstate = SCL_SHIFT_STATE_OFF;
590                     if (context)
591                         shiftstate = context->get_shift_state();
592                     if (labelproperties->shadow_distance > 0 && labelproperties->shadow_color[shiftstate][state].a != 0) {
593                         sclint deltax = 0;
594                         sclint deltay = 0;
595
596                         if (labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_TOP ||
597                                 labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_MIDDLE ||
598                                 labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_BOTTOM) {
599                             deltax -= labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
600                         } else if (labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_TOP ||
601                                    labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_MIDDLE ||
602                                    labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_BOTTOM) {
603                             deltax += labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
604                         }
605
606                         if (labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_TOP ||
607                                 labelproperties->shadow_direction == SHADOW_DIRECTION_CENTER_TOP ||
608                                 labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_TOP) {
609                             deltay -= labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
610                         } else if (labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_BOTTOM ||
611                                    labelproperties->shadow_direction == SHADOW_DIRECTION_CENTER_BOTTOM ||
612                                    labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_BOTTOM) {
613                             deltay += labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
614                         }
615
616                         graphics->draw_text(
617                             targetwin,
618                             draw_ctx,
619                             info,
620                             labelproperties->shadow_color[shiftstate][state],
621                             label,
622                             NULL,
623                             (sclint)coordinate->x + deltax + targetaddx,
624                             (sclint)coordinate->y + deltax + targetaddy,
625                             (sclint)coordinate->width,
626                             (sclint)coordinate->height,
627                             labelproperties->alignment,
628                             labelproperties->padding_x * utils->get_custom_scale_rate_x(),
629                             labelproperties->padding_y * utils->get_custom_scale_rate_y(),
630                             labelproperties->inner_width * utils->get_custom_scale_rate_x(),
631                             labelproperties->inner_height * utils->get_custom_scale_rate_y());
632                     }
633                     graphics->draw_text(
634                         targetwin,
635                         draw_ctx,
636                         info,
637                         labelproperties->font_color[shiftstate][state],
638                         label,
639                         NULL,
640                         (sclint)coordinate->x + targetaddx,
641                         (sclint)coordinate->y + targetaddy,
642                         (sclint)coordinate->width,
643                         (sclint)coordinate->height,
644                         labelproperties->alignment,
645                         labelproperties->padding_x * utils->get_custom_scale_rate_x(),
646                         labelproperties->padding_y * utils->get_custom_scale_rate_y(),
647                         labelproperties->inner_width * utils->get_custom_scale_rate_x(),
648                         labelproperties->inner_height * utils->get_custom_scale_rate_y());
649                 }
650             }
651         }
652     }
653
654     return TRUE;
655 }
656
657 /**
658 * Draws window's background using software
659 * @remark
660 */
661 sclboolean
662 CSCLUIBuilder::draw_window_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const SclSize size,
663                                     const scldouble line_width, const SclColor line_color, const SclColor fill_color)
664 {
665     SCL_DEBUG();
666     scl_assert_return_false(window);
667     scl_assert_return_false(draw_ctx);
668
669     CSCLWindows *windows = CSCLWindows::get_instance();
670     CSCLGraphics *graphics = CSCLGraphics::get_instance();
671     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
672
673     if (graphics && windows && cache) {
674         /* If the target window is virtual window, let's draw it on the base window */
675         sclwindow targetwin = window;
676         //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
677         SclWindowContext *window_context = windows->get_window_context(window);
678         if (window_context) {
679             if (window_context->is_virtual) {
680                 targetwin = windows->get_base_window();
681             }
682         }
683
684         graphics->draw_rectangle(targetwin, draw_ctx,
685             cache->get_custom_starting_coordinates().x, cache->get_custom_starting_coordinates().y,
686             size.width, size.height, line_width, line_color, TRUE, fill_color);
687     }
688
689     return TRUE;
690 }
691
692 /**
693  * Draws a button using software
694  * @remark draw_button
695  */
696 sclboolean
697 CSCLUIBuilder::draw_button_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state)
698 {
699     //SCL_DEBUG();
700
701     //CSCLResourceCache *cache = CSCLResourceCache::get_instance();
702     //const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(window, key_index);
703
704     //scl_assert_return_false(window);
705     //scl_assert_return_false(draw_ctx);
706     //scl_assert_return_false(coords);
707
708     //scl_assert_return_false(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
709
710     //scldouble line_width = scl_swbutton_style[scl_default_configure.sw_button_style].line_width[state];
711     //SclColor &line_color = scl_swbutton_style[scl_default_configure.sw_button_style].line_color[state];
712     //SclColor &bg_color = scl_swbutton_style[scl_default_configure.sw_button_style].bg_color[state];
713     //scldouble line_curve = scl_swbutton_style[scl_default_configure.sw_button_style].line_curve;
714     //sclfloat bg_alpha = scl_swbutton_style[scl_default_configure.sw_button_style].bg_alpha;
715
716     ///*if (g_key_spacing_off) {
717     //    m_gwes->m_graphics->draw_rectangle(window,
718     //        draw_ctx,
719     //        (sclint)coords->x - (sclint)coords->add_hit_left,
720     //        (sclint)coords->y - (sclint)coords->add_hit_top,
721     //        (sclint)coords->width + (sclint)coords->add_hit_left + (sclint)coords->add_hit_right,
722     //        (sclint)coords->height + (sclint)coords->add_hit_top + (sclint)coords->add_hit_bottom,
723     //        line_width,
724     //        line_color,
725     //        TRUE,
726     //        bg_color,
727     //        line_curve,
728     //        bg_alpha);
729     //} else {*/
730     //    m_gwes->m_graphics->draw_rectangle(window,
731     //                                 draw_ctx,
732     //                                 coords->x,
733     //                                 coords->y,
734     //                                 coords->width,
735     //                                 coords->height,
736     //                                 line_width,
737     //                                 line_color,
738     //                                 TRUE,
739     //                                 bg_color,
740     //                                 line_curve,
741     //                                 bg_alpha);
742     ////}
743     return TRUE;
744 }
745
746 /**
747  * Draws a button using the set image
748  * @remark draw_button
749  */
750 sclboolean
751 CSCLUIBuilder::draw_button_bg_by_img(const sclwindow window, const scldrawctx draw_ctx, scl16 key_index, SCLButtonState state, SCLShiftState shift)
752 {
753     SCL_DEBUG();
754
755     CSCLContext *context = CSCLContext::get_instance();
756     CSCLWindows *windows = CSCLWindows::get_instance();
757     CSCLGraphics *graphics = CSCLGraphics::get_instance();
758     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
759     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
760
761     const SclLayoutKeyCoordinate* coordinate = NULL;
762
763     if (!context || !windows || !graphics || !cache || !sclres_manager) return FALSE;
764
765     coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
766
767     PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
768     assert(sclres_modifier_decoration != NULL);
769     scl_assert_return_false(window);
770     scl_assert_return_false(draw_ctx);
771
772     scl_assert_return_false(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
773
774     sclchar composed_path[_POSIX_PATH_MAX] = {0, };
775
776     if (context && windows && graphics && cache && coordinate) {
777         sclboolean path_composed = FALSE;
778         /* Check if we need to decorate the button's drag state */
779         //if (context->get_cur_drag_state(context->get_last_touch_device_id()) != SCL_DRAG_STATE_NONE &&
780         if (context->get_cur_key_modifier(context->get_last_touch_device_id()) != KEY_MODIFIER_NONE &&
781             context->get_cur_pressed_window(context->get_last_touch_device_id()) == window &&
782             context->get_cur_pressed_key(context->get_last_touch_device_id()) == key_index &&
783             coordinate->modifier_decorator) {
784                 sclchar *decoration_bg_img = NULL;
785                 const SclModifierDecoration *decoration = NULL;
786                 /* FIXME */
787                 /*if (scl_check_arrindex(coordinate->modifier_decorator,
788                     sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
789                 scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
790                 if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
791                     if (sclres_modifier_decoration[decoration_id].valid) {
792                         decoration = &(sclres_modifier_decoration[decoration_id]);
793                     }
794                 }
795                 if (decoration) {
796                     sclshort display = context->get_display_mode();
797                     if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
798                     SCLKeyModifier modifier = context->get_cur_key_modifier(context->get_last_touch_device_id());
799                     if (!scl_check_arrindex(modifier, KEY_MODIFIER_MAX)) modifier = KEY_MODIFIER_NONE;
800                     decoration_bg_img = decoration->bg_image_path[display][modifier];
801                     /*sclshort dragstate = context->get_cur_drag_state(context->get_last_touch_device_id());
802                     if (!scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) dragstate = 0;
803                     decoration_bg_img = decoration->bg_image_path[display][dragstate];*/
804                 }
805                 if (decoration_bg_img) {
806                     if (strlen(decoration_bg_img) > 0) {
807                         m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, decoration_bg_img);
808                         path_composed = TRUE;
809                     }
810                 }
811         }
812         if (!path_composed) {
813             m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, coordinate->bg_image_path[shift][state]);
814         }
815
816         /* If the target window is virtual window, let's draw it on the base window */
817         sclint targetx = coordinate->x;
818         sclint targety = coordinate->y;
819         sclwindow targetwin = window;
820         //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
821         SclWindowContext *window_context = windows->get_window_context(window);
822         if (window_context) {
823             if (window_context->is_virtual) {
824                 //SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE);
825                 SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
826                 if (base_window_context) {
827                     targetwin = windows->get_base_window();
828                     targetx += window_context->geometry.x - base_window_context->geometry.x;
829                     targety += window_context->geometry.y - base_window_context->geometry.y;
830                 }
831             }
832         }
833
834         /*if (g_key_spacing_off) {
835             m_gwes->m_graphics->draw_image(
836                 window,
837                 draw_ctx,
838                 composed_path,
839                 (sclint)coordinate->x - (sclint)coordinate->add_hit_left,
840                 (sclint)coordinate->y - (sclint)coordinate->add_hit_top,
841                 (sclint)coordinate->width + (sclint)coordinate->add_hit_left + (sclint)coordinate->add_hit_right,
842                 (sclint)coordinate->height + (sclint)coordinate->add_hit_top + (sclint)coordinate->add_hit_bottom
843                 );
844         } else {*/
845             graphics->draw_image(
846                 targetwin,
847                 draw_ctx,
848                 composed_path,
849                 NULL,
850                 (sclint)targetx,
851                 (sclint)targety,
852                 (sclint)coordinate->width,
853                 (sclint)coordinate->height);
854         //}
855     }
856
857     return TRUE;
858 }
859
860 /**
861  * Draws a button using the set layout image
862  * @remark draw_button
863  */
864 sclboolean
865 CSCLUIBuilder::draw_button_bg_by_layoutimg(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state, const sclboolean shift)
866 {
867     SCL_DEBUG();
868
869     CSCLContext *context = CSCLContext::get_instance();
870     CSCLWindows *windows = CSCLWindows::get_instance();
871     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
872     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
873
874     if (!context || !windows || !cache || !sclres_manager) return FALSE;
875
876     const SclLayout* layout = cache->get_cur_layout(window);
877     const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
878     PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
879     assert(sclres_modifier_decoration != NULL);
880
881     scl_assert_return_false(window);
882     scl_assert_return_false(draw_ctx);
883
884     scl_assert_return_false(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
885
886     //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
887     SclWindowContext *window_context = windows->get_window_context(window);
888
889     sclchar composed_path[_POSIX_PATH_MAX] = {0, };
890     if (context && cache && coordinate && window_context) {
891         sclboolean path_composed = FALSE;
892         /* Check if we need to decorate the button's drag state */
893         //if (context->get_cur_drag_state(context->get_last_touch_device_id()) != SCL_DRAG_STATE_NONE &&
894         if (context->get_cur_key_modifier(context->get_last_touch_device_id()) != KEY_MODIFIER_NONE &&
895             context->get_cur_pressed_window(context->get_last_touch_device_id()) == window &&
896             context->get_cur_pressed_key(context->get_last_touch_device_id()) == key_index &&
897             coordinate->modifier_decorator) {
898                 sclchar *decoration_bg_img = NULL;
899                 const SclModifierDecoration *decoration = NULL;
900                 /* FIXME */
901                 /*if (scl_check_arrindex(coordinate->modifier_decorator,
902                     sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
903                 scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
904                 if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
905                     if (sclres_modifier_decoration[decoration_id].valid) {
906                         decoration = &(sclres_modifier_decoration[decoration_id]);
907                     }
908                 }
909                 if (decoration) {
910                     sclshort display = context->get_display_mode();
911                     if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
912                     SCLKeyModifier modifier = context->get_cur_key_modifier(context->get_last_touch_device_id());
913                     if (!scl_check_arrindex(modifier, KEY_MODIFIER_MAX)) modifier = KEY_MODIFIER_NONE;
914                     decoration_bg_img = decoration->bg_image_path[display][modifier];
915                     /*sclshort dragstate = context->get_cur_drag_state(context->get_last_touch_device_id());
916                     if (!scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) dragstate = 0;
917                     decoration_bg_img = decoration->bg_image_path[display][dragstate];*/
918                 }
919                 if (decoration_bg_img) {
920                     if (strlen(decoration_bg_img) > 0) {
921                         m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, decoration_bg_img);
922                         path_composed = TRUE;
923                     }
924                 }
925         }
926         if (!path_composed && layout) {
927             m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, layout->image_path[state]);
928         }
929         /*if (g_key_spacing_off) {
930             m_gwes->m_graphics->draw_image(
931                 window,
932                 draw_ctx,
933                 composed_path,
934                 (sclint)coordinate->x - (sclint)coordinate->add_hit_left,
935                 (sclint)coordinate->y - (sclint)coordinate->add_hit_top,
936                 (sclint)coordinate->width + (sclint)coordinate->add_hit_left + (sclint)coordinate->add_hit_right,
937                 (sclint)coordinate->height + (sclint)coordinate->add_hit_top + (sclint)coordinate->add_hit_bottom,
938                 window_context->imgOffsetx + (sclint)coordinate->x - (sclint)coordinate->add_hit_left,
939                 window_context->imgOffsety + (sclint)coordinate->y - (sclint)coordinate->add_hit_top,
940                 (sclint)coordinate->width + (sclint)coordinate->add_hit_left + (sclint)coordinate->add_hit_right,
941                 (sclint)coordinate->height + (sclint)coordinate->add_hit_top + (sclint)coordinate->add_hit_bottom,
942                 TRUE
943                 );
944         } else {*/
945             sclint dest_x = coordinate->x;
946             sclint dest_y = coordinate->y;
947             if (window_context->is_virtual) {
948                 SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
949                 if (base_window_context) {
950                     dest_x += (window_context->geometry.x - base_window_context->geometry.x);
951                     dest_y += (window_context->geometry.y - base_window_context->geometry.y);
952                 }
953             }
954
955             m_gwes->m_graphics->draw_image(
956                 window,
957                 draw_ctx,
958                 composed_path,
959                 NULL,
960                 dest_x,
961                 dest_y,
962                 (sclint)coordinate->width,
963                 (sclint)coordinate->height,
964                 window_context->layout_image_offset.x + (sclint)coordinate->x,
965                 window_context->layout_image_offset.y + (sclint)coordinate->y,
966                 (sclint)coordinate->width,
967                 (sclint)coordinate->height,
968                 TRUE);
969         //}
970     }
971     return TRUE;
972 }
973
974 /**
975  * Shows the magnifier window
976  */
977 sclboolean
978 CSCLUIBuilder::show_magnifier(const sclwindow window, scldrawctx draw_ctx)
979 {
980     SCL_DEBUG();
981     scl_assert_return_false(window);
982
983
984     CSCLUtils *utils = CSCLUtils::get_instance();
985     CSCLContext *context = CSCLContext::get_instance();
986     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
987     CSCLActionState *state = CSCLActionState::get_instance();
988     CSCLWindows *windows = CSCLWindows::get_instance();
989
990     if (!utils || !context || !cache || !state || !windows) return FALSE;
991
992     utils->log("show_magnifier");
993     sclwindow pressed_window = context->get_cur_pressed_window(context->get_last_touch_device_id());
994     scl8 pressed_key = context->get_cur_pressed_key(context->get_last_touch_device_id());
995
996     /* Due to the explicit delay on hiding mangnifier window, there is a case pressed key has been already reset */
997     if (pressed_key == NOT_USED) {
998         pressed_window = context->get_prev_pressed_window(context->get_last_touch_device_id());
999         pressed_key = context->get_prev_pressed_key(context->get_last_touch_device_id());
1000     }
1001
1002     if (pressed_key == NOT_USED || pressed_key > MAX_KEY) {
1003         //utils->log("show_magnifier pressed_key == NOT_USED || pressed_key > MAX_KEY \n");
1004         return TRUE;
1005     }
1006
1007     const SclLayout *layout = cache->get_cur_layout(windows->get_base_window());
1008     SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
1009     SclButtonContext* button_context = cache->get_cur_button_context(pressed_window, pressed_key);
1010     SCLShiftState shift_index = context->get_shift_state();
1011     if (shift_index < 0 || shift_index >= SCL_SHIFT_STATE_MAX) shift_index = SCL_SHIFT_STATE_OFF;
1012     if (context->get_caps_lock_mode()) {
1013         shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
1014     }
1015
1016     /* Do not show if current layout does not allow magnifier */
1017     if (layout) {
1018         if (!(layout->use_magnifier_window)) {
1019             if (utils) {
1020                 utils->log("!(layout->use_magnifier_window \n");
1021             }
1022             return FALSE;
1023         }
1024     }
1025     if (coordinate) {
1026         /* Some key types do not use the magnifier window */
1027         if ((coordinate->key_type == KEY_TYPE_CONTROL &&
1028             coordinate->key_event[0][0] != MVK_space  &&
1029             coordinate->key_event[0][0] != MVK_BackSpace) ||
1030                 (coordinate->key_type == KEY_TYPE_MODECHANGE ||
1031                 coordinate->key_type == KEY_TYPE_NONE ||
1032                 coordinate->button_type == BUTTON_TYPE_ROTATION)) {
1033             return FALSE;
1034         }
1035         /* FIXME : workaround for not showing magnifier for recent symbols */
1036         /* Do not show if there's nothing to show */
1037         //const char *targetstr = coordinate->key_value[shift_index][button_context->multikeyIdx];
1038         const char *targetstr = coordinate->label[shift_index][0];
1039         if (state) {
1040             if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
1041                 state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
1042                 targetstr = coordinate->long_key_value;
1043             }
1044         }
1045         const sclchar* customstr = NULL;
1046         for (sclint label_index = 0;label_index < MAX_SIZE_OF_LABEL_FOR_ONE && !customstr;label_index++) {
1047             const sclchar *tempstr = context->get_custom_magnifier_label(context->get_last_touch_device_id(), label_index);
1048             if (tempstr) {
1049                 customstr = tempstr;
1050             }
1051         }
1052         if (customstr) {
1053             targetstr = customstr;
1054         }
1055         if (targetstr == NULL) {
1056             if (utils) {
1057                 utils->log("coordinate->key_value[shift][button_context->multikeyIdx] == NULL \n");
1058             }
1059             return FALSE;
1060         } else if (strlen(targetstr) == 0) {
1061             if (utils) {
1062                 utils->log("coordinate->key_value[shift][button_context->multikeyIdx]) == 0 \n");
1063             }
1064             return FALSE;
1065         }
1066     }
1067
1068 #if 0
1069     SclPoint pos = {0, 0};
1070     /* calculates x position to be set */
1071     pos.x = (coordinate->x + (coordinate->width / 2)) - (utils->get_scale_x(scl_magnifier_configure.width) / 2);
1072
1073     /* calculates y position to be set */
1074     sclint scnWidth, scnHeight;
1075     utils->get_screen_resolution(&scnWidth, &scnHeight);
1076     pos.y = (scnHeight - layout->height) + coordinate->y - utils->get_scale_y(scl_magnifier_configure.height);
1077     windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
1078 #endif
1079
1080     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1081     PSclMagnifierWndConfigure magnifier_configure = NULL;
1082     if (sclres_manager) {
1083         magnifier_configure = sclres_manager->get_magnifier_configure();
1084     }
1085     if (coordinate && magnifier_configure && utils && state) {
1086         sclchar composed_path[_POSIX_PATH_MAX] = {0, };
1087         if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY) {
1088             m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_long_key_image_path);
1089             m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
1090                 magnifier_configure->width * utils->get_custom_scale_rate_x(),
1091                 magnifier_configure->height * utils->get_custom_scale_rate_y());
1092         } else {
1093             if (shift_index == SCL_SHIFT_STATE_LOCK) {
1094                 m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_shift_lock_image_path);
1095                 m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
1096                     magnifier_configure->width * utils->get_custom_scale_rate_x(),
1097                     magnifier_configure->height * utils->get_custom_scale_rate_y());
1098             } else if (shift_index == SCL_SHIFT_STATE_ON) {
1099                 m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_shift_image_path);
1100                 m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
1101                     magnifier_configure->width * utils->get_custom_scale_rate_x(),
1102                     magnifier_configure->height * utils->get_custom_scale_rate_y());
1103             } else {
1104                 m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_image_path);
1105                 m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
1106                     magnifier_configure->width * utils->get_custom_scale_rate_x(),
1107                     magnifier_configure->height * utils->get_custom_scale_rate_y());
1108             }
1109         }
1110
1111         for (int loop = 0;loop < MAX_WND_DECORATOR;loop++) {
1112             if (magnifier_configure->decoration_image_path[loop] &&
1113                 strlen(magnifier_configure->decoration_image_path[loop]) > 0) {
1114                 m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->decoration_image_path[loop]);
1115                 int decoration_size = magnifier_configure->decoration_size * utils->get_smallest_custom_scale_rate();
1116                 switch (loop) {
1117                 case WND_DECORATOR_TOP_LEFT:
1118                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1119                         0, 0, decoration_size, decoration_size);
1120                     break;
1121                 case WND_DECORATOR_TOP_CENTER:
1122                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1123                         decoration_size, 0, magnifier_configure->width - (2 * decoration_size), decoration_size);
1124                     break;
1125                 case WND_DECORATOR_TOP_RIGHT:
1126                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1127                         magnifier_configure->width - decoration_size, 0, decoration_size, decoration_size);
1128                     break;
1129                 case WND_DECORATOR_MIDDLE_LEFT:
1130                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1131                         0, decoration_size, decoration_size, magnifier_configure->height - (2 * decoration_size));
1132                     break;
1133                 case WND_DECORATOR_MIDDLE_CENTER:
1134                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1135                         0, 0, magnifier_configure->width, magnifier_configure->height);
1136                     break;
1137                 case WND_DECORATOR_MIDDLE_RIGHT:
1138                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1139                         magnifier_configure->width - decoration_size, decoration_size,
1140                         decoration_size, magnifier_configure->height - (2 * decoration_size));
1141                     break;
1142                 case WND_DECORATOR_BOTTOM_LEFT:
1143                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1144                         0, magnifier_configure->height - decoration_size, decoration_size, decoration_size);
1145                     break;
1146                 case WND_DECORATOR_BOTTOM_CENTER:
1147                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1148                         decoration_size, magnifier_configure->height - decoration_size,
1149                         magnifier_configure->width - (2 * decoration_size), decoration_size);
1150                     break;
1151                 case WND_DECORATOR_BOTTOM_RIGHT:
1152                     m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
1153                         magnifier_configure->width - decoration_size, magnifier_configure->height - decoration_size,
1154                         decoration_size, decoration_size);
1155                     break;
1156                 }
1157             }
1158         }
1159
1160         sclboolean ended = FALSE;
1161         for (int loop = 0;loop < MAX_SIZE_OF_LABEL_FOR_ONE && !ended;loop++) {
1162             const SclLabelProperties *labelproperties = cache->get_label_properties(magnifier_configure->label_type, loop);
1163             if (labelproperties) {
1164                 if (labelproperties->valid) {
1165                     if (magnifier_configure->show_shift_label) {
1166                         shift_index = SCL_SHIFT_STATE_ON;
1167                     }
1168                     if ((coordinate->use_long_key_magnifier && state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY) ||
1169                         state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
1170                             const sclchar* targetstr = coordinate->long_key_value;
1171                             const sclchar* customstr = context->get_custom_magnifier_label(context->get_last_touch_device_id(), loop);
1172                             if (customstr) {
1173                                 if (coordinate->long_key_value == NULL) {
1174                                     targetstr = customstr;
1175                                 } else if (strlen(coordinate->long_key_value) == 0) {
1176                                     targetstr = customstr;
1177                                 } else if (strcmp(coordinate->long_key_value, " ") == 0) {
1178                                     targetstr = customstr;
1179                                 }
1180                                 draw_magnifier_label(window, draw_ctx, loop, targetstr);
1181                             } else if (loop == 0) {
1182                                 targetstr = cache->find_substituted_string(targetstr);
1183                                 draw_magnifier_label(window, draw_ctx, 0, targetstr);
1184                             }
1185                     } else {
1186                         const sclchar* targetstr = NULL;
1187                         const sclchar* customstr = context->get_custom_magnifier_label(context->get_last_touch_device_id(), loop);
1188                         if (customstr) {
1189                             targetstr = customstr;
1190                         } else if (coordinate->magnifier_label[shift_index][loop]) {
1191                             targetstr = coordinate->magnifier_label[shift_index][loop];
1192                             targetstr = cache->find_substituted_string(targetstr);
1193                         } else if (loop == 0) {
1194                             /* Don't display sublabels of each buttons in magnifier window - this policy can be changed, but for now */
1195                             if (button_context) {
1196                                 targetstr = coordinate->label[shift_index][button_context->multitap_index];
1197                                 targetstr = cache->find_substituted_string(targetstr);
1198                             }
1199                         }
1200                         if (targetstr) {
1201                             draw_magnifier_label(window, draw_ctx, loop, targetstr);
1202                         }
1203                     }
1204                 } else {
1205                     ended = TRUE;
1206                 }
1207             }
1208         }
1209     }
1210
1211     return TRUE;
1212 }
1213
1214
1215 /**
1216  * Draws labels on the rectangle of the magnifier window
1217  * @remark show_magnifier
1218  */
1219 sclboolean
1220 CSCLUIBuilder::draw_magnifier_label(const sclwindow window, const scldrawctx draw_ctx, const scl16 label_index, const sclchar* label)
1221 {
1222     SCL_DEBUG();
1223     scl_assert_return_false(window);
1224     scl_assert_return_false(draw_ctx);
1225
1226     CSCLUtils *utils = CSCLUtils::get_instance();
1227     CSCLWindows *windows = CSCLWindows::get_instance();
1228     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
1229     CSCLContext *context = CSCLContext::get_instance();
1230     CSCLGraphics *graphics = CSCLGraphics::get_instance();
1231
1232     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1233     PSclMagnifierWndConfigure magnifier_configure = NULL;
1234     if (sclres_manager) {
1235         magnifier_configure = sclres_manager->get_magnifier_configure();
1236     }
1237
1238     if (utils && windows && cache && context && graphics && magnifier_configure) {
1239         const SclLabelProperties *labelproperties = NULL;
1240         if (scl_check_arrindex(label_index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
1241             labelproperties = cache->get_label_properties(magnifier_configure->label_type, label_index);
1242         }
1243         if (labelproperties) {
1244             SclFontInfo info;
1245             if (labelproperties->font_name) {
1246                 strncpy(info.font_name, labelproperties->font_name, MAX_FONT_NAME_LEN - 1);
1247             }
1248             info.font_name[MAX_FONT_NAME_LEN - 1] = '\0';
1249             info.font_size = labelproperties->font_size * utils->get_smallest_custom_scale_rate();
1250             info.is_bold = info.is_italic = true;
1251
1252             SCLShiftState shiftstate = context->get_shift_state();
1253             if (scl_check_arrindex(shiftstate, SCL_SHIFT_STATE_MAX)) {
1254                 if (context->get_caps_lock_mode()) {
1255                     shiftstate = (shiftstate == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
1256                 }
1257                 graphics->draw_text(
1258                     window,
1259                     draw_ctx,
1260                     info,
1261                     labelproperties->font_color[shiftstate][BUTTON_STATE_NORMAL],
1262                     label,
1263                     NULL,
1264                     magnifier_configure->label_area_rect.left * utils->get_custom_scale_rate_x(),
1265                     magnifier_configure->label_area_rect.top * utils->get_custom_scale_rate_y(),
1266                     magnifier_configure->label_area_rect.right * utils->get_custom_scale_rate_x(),
1267                     magnifier_configure->label_area_rect.bottom * utils->get_custom_scale_rate_y(),
1268                     labelproperties->alignment,
1269                     labelproperties->padding_x * utils->get_custom_scale_rate_x(),
1270                     labelproperties->padding_y * utils->get_custom_scale_rate_y(),
1271                     labelproperties->inner_width * utils->get_custom_scale_rate_x(),
1272                     labelproperties->inner_height * utils->get_custom_scale_rate_y());
1273             }
1274         }
1275     }
1276     return TRUE;
1277 }