fix prevent issue
[framework/uifw/libscl-ui.git] / scl / sclresourcecache.cpp
1 /*
2  * Copyright 2012-2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 "sclresourcekeys.h"
21 #include "sclresourcecache.h"
22 #include "scldebug.h"
23 #include "sclcontext.h"
24
25 //#include "sclresource.h"
26 #include "scluibuilder.h"
27 #include "sclres_manager.h"
28 #include <assert.h>
29 using namespace scl;
30
31 CSCLResourceCache* CSCLResourceCache::m_instance = NULL; /* For singleton */
32
33 CSCLResourceCache::CSCLResourceCache()
34 {
35     SCL_DEBUG();
36
37     memset(mCurThemename, 0x00, sizeof(mCurThemename));
38 }
39
40 CSCLResourceCache::~CSCLResourceCache()
41 {
42     SCL_DEBUG();
43 }
44
45 CSCLResourceCache*
46 CSCLResourceCache::get_instance()
47 {
48     if (!m_instance) {
49         m_instance = new CSCLResourceCache();
50     }
51     return (CSCLResourceCache*)m_instance;
52 }
53
54
55 sclboolean
56 CSCLResourceCache::init()
57 {
58     clear_private_keys();
59
60     resize_resource_elements_by_resolution();
61
62     return TRUE;
63 }
64
65 /**
66  * Returns the current layout data
67  */
68 const SclLayout*
69 CSCLResourceCache::get_cur_layout(sclwindow window) const
70 {
71     SCL_DEBUG();
72
73     const SclLayout *ret = NULL;
74     CSCLWindows *windows = CSCLWindows::get_instance();
75
76     if (windows) {
77         if (windows->get_base_window() == window) {
78             ret = &mCurBaseLayout;
79         } else {
80             sclbyte popupindex = windows->find_popup_window_index(window);
81             scl_assert_return_false(popupindex < MAX_POPUP_WINDOW);
82             if (popupindex < MAX_POPUP_WINDOW) {
83                 ret = &mCurPopupLayout[popupindex];
84             }
85         }
86     }
87     return ret;
88 }
89
90 /**
91  * Translates each key's x,y,width,height by the current screen resolution
92  * This func should be called when the class init / or after lazy loading
93  */
94 sclboolean
95 CSCLResourceCache::resize_layout_by_resolution(sclbyte layout_index, sclboolean resize_key_only)
96 {
97     sclint innerLoop;
98     CSCLUtils *utils = CSCLUtils::get_instance();
99
100     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
101     if (utils && sclres_manager) {
102         const PSclDefaultConfigure sclres_default_configure = sclres_manager->get_default_configure();
103         const PSclLayout sclres_layout = sclres_manager->get_layout_table();
104         const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
105             sclres_manager->get_key_coordinate_pointer_frame();
106
107         assert(sclres_default_configure != NULL);
108         assert(sclres_layout != NULL);
109         assert(sclres_layout_key_coordinate_pointer_frame != NULL);
110
111         sclboolean invert_display = FALSE;
112
113         if (sclres_default_configure->auto_detect_landscape) {
114             sclint width, height;
115             utils->get_screen_resolution(&width, &height);
116             /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
117             if (width > height) {
118                 invert_display = TRUE;
119             }
120         }
121
122         sclfloat scale_value_x, scale_value_y;
123         if (invert_display) {
124             if (sclres_layout[layout_index].display_mode == DISPLAYMODE_PORTRAIT) {
125                 scale_value_x = utils->get_scale_rate_y();
126                 scale_value_y = utils->get_scale_rate_x();
127             } else {
128                 scale_value_x = utils->get_scale_rate_x();
129                 scale_value_y = utils->get_scale_rate_y();
130             }
131         } else {
132             if (sclres_layout[layout_index].display_mode == DISPLAYMODE_PORTRAIT) {
133                 scale_value_x = utils->get_scale_rate_x();
134                 scale_value_y = utils->get_scale_rate_y();
135             } else {
136                 scale_value_x = utils->get_scale_rate_y();
137                 scale_value_y = utils->get_scale_rate_x();
138             }
139         }
140
141         ///* FIXME : We should apply this contraint to other scaling routines also! */
142         ///* If the current screen resolution Y is bigger than our target height */
143         //if (scale_value_y > 1.0f) {
144         //    /* And if we have to scale Y-axis more than the X-axis, limit the scale value to X-axis rate */
145         //    if (scale_value_y > scale_value_x) {
146         //        scale_value_y = scale_value_x;
147         //    }
148         //} else if (scale_value_y < 1.0f) { /* Or current screen is smaller than our target resolution */
149         //    /* And if we have to scale Y-axis more than the X-axis, limit the scale value to X-axis rate */
150         //    if (scale_value_y < scale_value_x) {
151         //        scale_value_y = scale_value_x;
152         //    }
153         //}
154
155         if (!resize_key_only) {
156             sclres_layout[layout_index].width *= scale_value_x;
157             sclres_layout[layout_index].height *= scale_value_y;
158         }
159
160         for (innerLoop = 0;innerLoop < MAX_KEY;innerLoop++) {
161             SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][innerLoop];
162             if (p && p->valid) {
163                 p->x *= scale_value_x;
164                 p->y *= scale_value_y;
165                 p->width *= scale_value_x;
166                 p->height *= scale_value_y;
167                 p->add_hit_left *= scale_value_x;
168                 p->add_hit_right *= scale_value_x;
169                 p->add_hit_top *= scale_value_y;
170                 p->add_hit_bottom *= scale_value_y;
171                 p->popup_relative_x *= scale_value_x;
172                 p->popup_relative_y *= scale_value_y;
173                 p->extract_offset_x *= scale_value_x;
174                 p->extract_offset_y *= scale_value_y;
175                 p->magnifier_offset_x *= scale_value_x;
176                 p->magnifier_offset_y *= scale_value_y;
177             }
178         }
179     }
180
181     return TRUE;
182 }
183
184 /**
185  * Translates the current x,y,width,height by the current screen resolution
186  * This func should be called when the class init
187  */
188 sclboolean
189 CSCLResourceCache::resize_resource_elements_by_resolution()
190 {
191     sclint loop, innerLoop;
192     CSCLUtils *utils = CSCLUtils::get_instance();
193
194     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
195     if (utils && sclres_manager) {
196         const PSclDefaultConfigure sclres_default_configure = sclres_manager->get_default_configure();
197         const PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
198         const PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
199         const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
200         const PSclAutoPopupConfigure sclres_autopopup_configure = sclres_manager->get_autopopup_configure();
201         const PSclMagnifierWndConfigure sclres_magnifier_configure = sclres_manager->get_magnifier_configure();
202         
203         assert(sclres_default_configure != NULL);
204         assert(sclres_input_mode_configure != NULL);
205         assert(sclres_modifier_decoration != NULL);
206         assert(sclres_label_properties != NULL);
207         assert(sclres_autopopup_configure != NULL);
208         assert(sclres_magnifier_configure != NULL);
209
210         sclboolean invert_display = FALSE;
211
212         if (sclres_default_configure->auto_detect_landscape) {
213             sclint width, height;
214             utils->get_screen_resolution(&width, &height);
215             /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
216             if (width > height) {
217                 invert_display = TRUE;
218             }
219         }
220
221         /* First we recalculate all the coordinations of each keys and sizes of layouts structure */
222         /* FIXME */
223         //for (loop = 0;loop < MAX_LAYOUT;loop++) {
224         for (loop = 0;loop < MAX_SCL_LAYOUT;loop++) {
225             resize_layout_by_resolution(loop);
226         }
227
228         /* And resize the font labels, adjusting the size of padding also */
229         /* FIXME */
230         //for (loop = 0;loop < MAX_LABEL_PROPERTIES;loop++) {
231         for (loop = 0;loop < MAX_SCL_LABEL_PROPERTIES;loop++) {
232             for (innerLoop = 0;innerLoop < MAX_SIZE_OF_LABEL_FOR_ONE;innerLoop++) {
233                 if (sclres_label_properties[loop][innerLoop].valid)
234                     sclres_label_properties[loop][innerLoop].font_size *= utils->get_smallest_scale_rate();
235                 sclres_label_properties[loop][innerLoop].padding_x *= utils->get_smallest_scale_rate();
236                 sclres_label_properties[loop][innerLoop].padding_y *= utils->get_smallest_scale_rate();
237                 sclres_label_properties[loop][innerLoop].inner_width *= utils->get_smallest_scale_rate();
238                 sclres_label_properties[loop][innerLoop].inner_height *= utils->get_smallest_scale_rate();
239                 sclres_label_properties[loop][innerLoop].shadow_distance *= utils->get_smallest_scale_rate();
240             }
241         }
242
243         /* FIXME - Let's check if these variables also need to be calculated by AutoLandscapeDection */
244         sclres_autopopup_configure->decoration_size *= utils->get_smallest_scale_rate();
245         sclres_autopopup_configure->bg_padding *= utils->get_smallest_scale_rate();
246         sclres_autopopup_configure->button_spacing *= utils->get_smallest_scale_rate();
247         utils->scale_x(&(sclres_autopopup_configure->button_width));
248         utils->scale_y(&(sclres_autopopup_configure->button_height));
249
250         utils->scale_x(&(sclres_magnifier_configure->width));
251         utils->scale_y(&(sclres_magnifier_configure->height));
252         sclres_magnifier_configure->label_area_rect.left *= utils->get_scale_rate_x();
253         sclres_magnifier_configure->label_area_rect.right *= utils->get_scale_rate_x();
254         sclres_magnifier_configure->label_area_rect.top *= utils->get_scale_rate_y();
255         sclres_magnifier_configure->label_area_rect.bottom *= utils->get_scale_rate_y();
256
257         if (invert_display) {
258             /* FIXME */
259             //for (loop = 0;loop < MAX_INPUT_MODE;loop++) {
260             for (loop = 0;loop < MAX_SCL_INPUT_MODE;loop++) {
261                 sclchar *temp = sclres_input_mode_configure[loop].layouts[0];
262                 sclres_input_mode_configure[loop].layouts[0] = sclres_input_mode_configure[loop].layouts[1];
263                 sclres_input_mode_configure[loop].layouts[1] = temp;
264             }
265             /* FIXME */
266             //for (loop = 0;loop < MODIFIER_DECORATION_NUM;loop++) {
267             for (loop = 0;loop < MAX_SCL_MODIFIER_DECORATION_NUM;loop++) {
268                 for(innerLoop = 0;innerLoop < KEY_MODIFIER_MAX;innerLoop++) {
269                     sclchar *temp;
270                     temp = sclres_modifier_decoration[loop].bg_image_path[0][innerLoop];
271                     sclres_modifier_decoration[loop].bg_image_path[0][innerLoop] = sclres_modifier_decoration[loop].bg_image_path[1][innerLoop];
272                     sclres_modifier_decoration[loop].bg_image_path[1][innerLoop] = temp;
273                 }
274             }
275         }
276     }
277
278     return TRUE;
279 }
280
281 /**
282  * Changes the current key properties by the current screen resolution
283  * This func should be called when the class init
284  */
285 sclboolean
286 CSCLResourceCache::change_by_privatekey(const sclbyte input_mode_index, const sclbyte layout_index, const sclbyte key_index, SclLayoutKeyCoordinate* coordination)
287 {
288     SCL_DEBUG();
289     scl_assert_return_false(coordination);
290
291     if (coordination) {
292         for (int loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
293             if (mPrivateKeyProperties[loop].valid &&
294                 !(mPrivateKeyProperties[loop].custom_id.empty()) && coordination->custom_id) {
295                 if (mPrivateKeyProperties[loop].custom_id.compare(coordination->custom_id) == 0) {
296                     /* sets the current properties to private key properties */
297                     copy_from_privatekeyproperties(&mPrivateKeyProperties[loop], coordination);
298                 }
299             }
300         }
301     }
302
303     return TRUE;
304 }
305
306 /**
307  * Copys the given private properties data to the given key properties
308  */
309 sclboolean
310 CSCLResourceCache::copy_from_privatekeyproperties(const SclPrivateKeyProperties* privProperties, SclLayoutKeyCoordinate* coordination)
311 {
312     SCL_DEBUG();
313     scl_assert_return_false(privProperties);
314     scl_assert_return_false(coordination);
315
316     sclint loop;
317     sclint inner_loop;
318     if (privProperties && coordination) {
319         /* Copy customizing-allowed properties only if those properties are valid */
320         coordination->label_count = privProperties->label_count;
321         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
322             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
323                 if (!(privProperties->label[loop][inner_loop].empty())) {
324                     coordination->label[loop][inner_loop] =
325                         (sclchar*)privProperties->label[loop][inner_loop].c_str();
326                 }
327             }
328         }
329         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
330             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
331                 if (!(privProperties->image_label_path[loop][inner_loop].empty())) {
332                     coordination->image_label_path[loop][inner_loop] =
333                         (sclchar*)privProperties->image_label_path[loop][inner_loop].c_str();
334                 }
335             }
336         }
337         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
338             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
339                 if (!(privProperties->bg_image_path[loop][inner_loop].empty())) {
340                     coordination->bg_image_path[loop][inner_loop] =
341                         (sclchar*)privProperties->bg_image_path[loop][inner_loop].c_str();
342                 }
343             }
344         }
345
346         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
347             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
348                 if (!(privProperties->key_value[loop][inner_loop].empty())) {
349                     coordination->key_value[loop][inner_loop] =
350                         (sclchar*)privProperties->key_value[loop][inner_loop].c_str();
351                 }
352             }
353         }
354         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
355             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
356                 if (privProperties->key_event[loop][inner_loop] != 0) {
357                     coordination->key_event[loop][inner_loop] =
358                         privProperties->key_event[loop][inner_loop];
359                 }
360             }
361         }
362         memcpy(coordination->hint_string, privProperties->hint_string, sizeof(coordination->hint_string));
363     }
364
365     return TRUE;
366 }
367
368 /**
369  * Copys the given properties data to the given private key properties
370  */
371 sclboolean
372 CSCLResourceCache::copy_to_privatekeyproperties(const SclLayoutKeyCoordinate *coordination, SclPrivateKeyProperties* privProperties)
373 {
374     SCL_DEBUG();
375     scl_assert_return_false(privProperties);
376     scl_assert_return_false(coordination);
377
378     /* sets the current key Properties to private key privProperties */
379
380     sclint loop;
381     sclint inner_loop;
382     if (privProperties && coordination) {
383         /* Configure */
384         if (coordination->custom_id) {
385             privProperties->custom_id = coordination->custom_id;
386         }
387         privProperties->button_type = coordination->button_type;
388         privProperties->key_type = coordination->key_type;
389         privProperties->popup_type = coordination->popup_type;
390         privProperties->use_magnifier = coordination->use_magnifier;
391         privProperties->use_long_key_magnifier = coordination->use_long_key_magnifier;
392         if (coordination->sound_style) {
393             privProperties->sound_style = coordination->sound_style;
394         }
395         if (coordination->vibe_style) {
396             privProperties->vibe_style = coordination->vibe_style;
397         }
398
399         for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
400             if (coordination->popup_input_mode[loop]) {
401                 privProperties->popup_input_mode[loop] = coordination->popup_input_mode[loop];
402             }
403         }
404
405         /* Properties */
406         privProperties->label_count = coordination->label_count;
407         privProperties->key_value_count = coordination->key_value_count;
408         privProperties->long_key_type = coordination->long_key_type;
409         if (coordination->long_key_value) {
410             privProperties->long_key_value = coordination->long_key_value;
411         }
412         privProperties->long_key_event = coordination->long_key_event;
413         privProperties->use_repeat_key = coordination->use_repeat_key;
414         privProperties->dont_close_popup = coordination->dont_close_popup;
415         privProperties->extra_option = coordination->extra_option;
416         if (coordination->label_type) {
417             privProperties->label_type = coordination->label_type;
418         }
419         if (coordination->image_label_type) {
420             privProperties->image_label_type = coordination->image_label_type;
421         }
422
423         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
424             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
425                 if (coordination->label[loop][inner_loop]) {
426                     privProperties->label[loop][inner_loop] =
427                         coordination->label[loop][inner_loop];
428                 }
429             }
430         }
431         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
432             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
433                 if (coordination->image_label_path[loop][inner_loop]) {
434                     privProperties->image_label_path[loop][inner_loop] =
435                         coordination->image_label_path[loop][inner_loop];
436                 }
437             }
438         }
439         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
440             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
441                 if (coordination->bg_image_path[loop][inner_loop]) {
442                     privProperties->bg_image_path[loop][inner_loop] =
443                         coordination->bg_image_path[loop][inner_loop];
444                 }
445             }
446         }
447
448         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
449             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
450                 if (coordination->key_value[loop][inner_loop]) {
451                     privProperties->key_value[loop][inner_loop] =
452                         coordination->key_value[loop][inner_loop];
453                 }
454             }
455         }
456         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
457             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
458                 if (coordination->key_event[loop][inner_loop]) {
459                     privProperties->key_event[loop][inner_loop] =
460                         coordination->key_event[loop][inner_loop];
461                 }
462             }
463         }
464
465         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
466             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
467                 if (coordination->autopopup_key_labels[loop][inner_loop]) {
468                     privProperties->autopopup_key_labels[loop][inner_loop] =
469                         coordination->autopopup_key_labels[loop][inner_loop];
470                 }
471             }
472         }
473         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
474             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
475                 if (coordination->autopopup_key_events[loop][inner_loop]) {
476                     privProperties->autopopup_key_events[loop][inner_loop] =
477                         coordination->autopopup_key_events[loop][inner_loop];
478                 }
479             }
480         }
481         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
482             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
483                 if (coordination->autopopup_key_values[loop][inner_loop]) {
484                     privProperties->autopopup_key_values[loop][inner_loop] =
485                         coordination->autopopup_key_values[loop][inner_loop];
486                 }
487             }
488         }
489         memcpy(privProperties->hint_string, coordination->hint_string, sizeof(privProperties->hint_string));
490     }
491
492     return TRUE;
493 }
494
495 /**
496  * Copys the given private properties data to the other private properties
497  */
498 sclboolean
499 CSCLResourceCache::copy_privatekeyproperties(const SclPrivateKeyProperties* source, SclPrivateKeyProperties* target)
500 {
501     SCL_DEBUG();
502     scl_assert_return_false(source);
503     scl_assert_return_false(target);
504
505     sclint loop;
506     sclint inner_loop;
507     if (source && target) {
508         target->input_mode_index = source->input_mode_index;
509         target->layout_index = source->layout_index;
510         target->key_index = source->key_index;
511
512         /* Configure */
513         target->custom_id = source->custom_id;
514         target->button_type = source->button_type;
515         target->key_type = source->key_type;
516         target->popup_type = source->popup_type;
517         target->use_magnifier = source->use_magnifier;
518         target->use_long_key_magnifier = source->use_long_key_magnifier;
519         target->sound_style = source->sound_style;
520         target->vibe_style = source->vibe_style;
521
522         for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
523             target->popup_input_mode[loop] = source->popup_input_mode[loop];
524         }
525
526         /* Properties */
527         target->label_count = source->label_count;
528         target->key_value_count = source->key_value_count;
529         target->long_key_type = source->long_key_type;
530         target->long_key_value = source->long_key_value;
531         target->long_key_event = source->long_key_event;
532         target->use_repeat_key = source->use_repeat_key;
533         target->dont_close_popup = source->dont_close_popup;
534         target->extra_option = source->extra_option;
535         target->label_type = source->label_type;
536         target->image_label_type = source->image_label_type;
537
538         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
539             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
540                 target->label[loop][inner_loop] =
541                     source->label[loop][inner_loop];
542             }
543         }
544         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
545             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
546                 target->image_label_path[loop][inner_loop] =
547                     source->image_label_path[loop][inner_loop];
548             }
549         }
550         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
551             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
552                 target->bg_image_path[loop][inner_loop] =
553                     source->bg_image_path[loop][inner_loop];
554             }
555         }
556
557         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
558             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
559                 target->key_value[loop][inner_loop] =
560                     source->key_value[loop][inner_loop];
561             }
562         }
563         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
564             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
565                 target->key_event[loop][inner_loop] =
566                     source->key_event[loop][inner_loop];
567             }
568         }
569
570         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
571             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
572                 target->autopopup_key_labels[loop][inner_loop] =
573                     source->autopopup_key_labels[loop][inner_loop];
574             }
575         }
576         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
577             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
578                 target->autopopup_key_events[loop][inner_loop] =
579                     source->autopopup_key_events[loop][inner_loop];
580             }
581         }
582         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
583             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
584                 target->autopopup_key_values[loop][inner_loop] =
585                     source->autopopup_key_values[loop][inner_loop];
586             }
587         }
588     }
589
590     return TRUE;
591 }
592
593 /**
594  * Clears the given private properties data
595  */
596 sclboolean
597 CSCLResourceCache::clear_privatekeyproperties(SclPrivateKeyProperties* privProperties)
598 {
599     SCL_DEBUG();
600     scl_assert_return_false(privProperties);
601
602     /* sets the current key Properties to private key privProperties */
603
604     sclint loop;
605     sclint inner_loop;
606     if (privProperties) {
607         /* Configure */
608         privProperties->valid = FALSE;
609         privProperties->input_mode_index = NOT_USED;
610         privProperties->layout_index = NOT_USED;
611         privProperties->key_index = NOT_USED;
612
613         privProperties->custom_id.clear();
614         privProperties->button_type = BUTTON_TYPE_NORMAL;
615         privProperties->key_type = KEY_TYPE_NONE;
616         privProperties->popup_type = POPUP_TYPE_NONE;
617         privProperties->use_magnifier = FALSE;
618         privProperties->use_long_key_magnifier = FALSE;
619         privProperties->sound_style.clear();
620         privProperties->vibe_style.clear();
621
622         for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
623             privProperties->popup_input_mode[loop].clear();
624         }
625
626         /* Properties */
627         privProperties->label_count = 0;
628         privProperties->key_value_count = 0;
629         privProperties->long_key_type = KEY_TYPE_NONE;
630         privProperties->long_key_value.clear();
631         privProperties->long_key_event = 0;
632         privProperties->use_repeat_key = FALSE;
633         privProperties->dont_close_popup = FALSE;
634         privProperties->extra_option = 0;
635         privProperties->label_type.clear();
636         privProperties->image_label_type.clear();
637
638         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
639             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
640                 privProperties->label[loop][inner_loop].clear();
641             }
642         }
643         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
644             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
645                 privProperties->image_label_path[loop][inner_loop].clear();
646             }
647         }
648         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
649             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
650                 privProperties->bg_image_path[loop][inner_loop].clear();
651             }
652         }
653
654         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
655             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
656                 privProperties->key_value[loop][inner_loop].clear();
657             }
658         }
659         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
660             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
661                 privProperties->key_event[loop][inner_loop] = 0;
662             }
663         }
664
665         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
666             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
667                 privProperties->autopopup_key_labels[loop][inner_loop].clear();
668             }
669         }
670         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
671             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
672                 privProperties->autopopup_key_events[loop][inner_loop] = 0;
673             }
674         }
675         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
676             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
677                 privProperties->autopopup_key_values[loop][inner_loop].clear();
678             }
679         }
680     }
681
682     return TRUE;
683 }
684
685 /**
686  * Adds a new private key
687  * It will update it to the current cache properties context because the application can call it anytime
688  * For adapting it in realtime, you should explictly call the draw_button function.
689  *
690  * @param[out] fNeedInvalid It will return true if the current private can be adapt into the current display.
691  * @return id an array index of the private key
692  */
693 sclint
694 CSCLResourceCache::add_private_key(SclPrivateKeyProperties* privProperties, sclboolean *fNeedInvaild)
695 {
696     SCL_DEBUG();
697     scl_assert_return_false(privProperties);
698     sclint ret = NOT_USED;
699     *fNeedInvaild = FALSE; /* don't need to update now */
700
701     if (privProperties->custom_id.empty())
702         return ret;
703
704     /* Finds an index to be set */
705     sclint loop = 0;
706     for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
707         if (mPrivateKeyProperties[loop].custom_id.compare(privProperties->custom_id) == 0) {
708             break;
709         }
710     }
711
712     if (loop == MAX_PRIVATE_KEY) {
713         for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
714             if (mPrivateKeyProperties[loop].valid == FALSE) break;
715         }
716         if (loop == MAX_PRIVATE_KEY) {
717             printf("Out of buffer!! could not insert new private data into buffer \n");
718             return ret;
719         }
720     }
721
722     copy_privatekeyproperties(privProperties, &mPrivateKeyProperties[loop]);
723     mPrivateKeyProperties[loop].valid = TRUE;
724     ret = loop;
725
726     sclboolean found = FALSE;
727     for (sclint loop = 0;loop < MAX_KEY; loop++) {
728         if ((!(privProperties->custom_id.empty())) && mCurBaseLayoutKeyCoordination[loop].custom_id) {
729             if (privProperties->custom_id.compare(mCurBaseLayoutKeyCoordination[loop].custom_id) == 0) {
730                 /* sets the current properties to private key properties */
731                 copy_from_privatekeyproperties(privProperties, &mCurBaseLayoutKeyCoordination[loop]);
732                 found = TRUE;
733             }
734         }
735     }
736     if (found) {
737         *fNeedInvaild = TRUE;
738         return ret;
739     }
740
741 #if 0
742     /* For popup layout */
743     CSCLWindows *windows = CSCLWindows::get_instance();
744     for (int ploop = 0; ploop < MAX_POPUP_WINDOW; ploop++) {
745         layout = context->get_popup_layout(windows->get_nth_popup_window(ploop));
746         if (privProperties->input_mode_index == inputmode && privProperties->layout_index == layout) {
747             /* sets the current properties to private key properties */
748             copy_privatekeyproperties_to_keyproperties(privProperties, &mCurPopupLayoutKeyProperties[ploop][privProperties->key_index]);
749             return ret;
750             *fNeedInvaild = TRUE;
751         }
752     }
753 #endif
754
755     if (ret == NOT_USED) {
756         printf("Failed!. Out of private data buffer\n");
757     }
758     return ret;
759 }
760
761 /**
762  * Removes the private data of the given id from SclPrivateKeyProperties buffer
763  */
764 sclboolean
765 CSCLResourceCache::remove_private_key(sclint id)
766 {
767     SCL_DEBUG();
768     sclint loop;
769     CSCLContext *context = CSCLContext::get_instance();
770
771     /* resets the current properties to predefined properties */
772     sclshort layout =  context->get_base_layout();
773
774     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
775     PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
776         sclres_manager->get_key_coordinate_pointer_frame();
777
778     if (sclres_layout_key_coordinate_pointer_frame == NULL) {
779         return FALSE;
780     }
781     if (scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
782         for (sclint loop = 0;loop < MAX_KEY; loop++) {
783             if ((!(mPrivateKeyProperties[id].custom_id.empty())) && mCurBaseLayoutKeyCoordination[loop].custom_id) {
784                 if (mPrivateKeyProperties[id].custom_id.compare(mCurBaseLayoutKeyCoordination[loop].custom_id) == 0) {
785                     SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
786                     if (p == NULL) {
787                         continue;
788                     }
789                     SclLayoutKeyCoordinatePointer the_key = mCurBaseLayoutKeyCoordination + loop;
790                     assert(the_key != NULL);
791                     memcpy(the_key, p, sizeof(SclLayoutKeyCoordinate));
792
793                 }
794             }
795         }
796     }
797
798     /* Shift all the privatekey properties to the left by 1, starting from the item next to the id th element */
799     for (loop = id;loop < MAX_PRIVATE_KEY - 1; loop++) {
800         copy_privatekeyproperties(&mPrivateKeyProperties[loop + 1], &mPrivateKeyProperties[loop]);
801     }
802     /* Clear the last element */
803     clear_privatekeyproperties(&mPrivateKeyProperties[MAX_PRIVATE_KEY - 1]);
804     return TRUE;
805 }
806
807 /**
808  * Clears all private keys
809  */
810 sclboolean
811 CSCLResourceCache::clear_private_keys()
812 {
813     SCL_DEBUG();
814     for (sclint loop = 0; loop < MAX_PRIVATE_KEY;loop++) {
815         clear_privatekeyproperties(&mPrivateKeyProperties[loop]);
816     }
817     return TRUE;
818 }
819
820 /**
821  * Re-computes the cache data of the given window. The cache data has been including the current key properties, button context, layout etc,,
822  * Another role of this func is to adjust the current coordination according to the current resolution.
823  * This func will be called when a newly window is created
824  */
825 sclboolean
826 CSCLResourceCache::recompute_layout(sclwindow window)
827 {
828     SCL_DEBUG();
829
830     sclint loop;
831
832     CSCLWindows *windows = CSCLWindows::get_instance();
833     CSCLContext *context = CSCLContext::get_instance();
834     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
835     const PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
836     const PSclLayout sclres_layout = sclres_manager->get_layout_table();
837     const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
838         sclres_manager->get_key_coordinate_pointer_frame();
839     const PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
840     const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
841     assert(sclres_input_mode_configure != NULL);
842     assert(sclres_layout != NULL);
843     assert(sclres_layout_key_coordinate_pointer_frame != NULL);
844     assert(sclres_modifier_decoration != NULL);
845     assert(sclres_label_properties != NULL);
846
847     /* FIXME */
848     scl8 popupindex = NOT_USED;
849
850     SclLayout *pCurLayout = NULL;
851     SclLayoutKeyCoordinate (*pCurLayoutKeyCoordination)[MAX_KEY] = NULL;
852     SclButtonContext (*pCurButtonContext)[MAX_KEY] = NULL;
853
854     sclshort layout =  NOT_USED;
855     if (windows && context) {
856         sclbyte display = context->get_display_mode();
857         sclbyte inputmode = context->get_input_mode();
858
859         if (windows->is_base_window(window)) {
860             SCLDisplayMode display_mode = context->get_display_mode();
861             layout = sclres_manager->get_layout_id(
862                 sclres_input_mode_configure[inputmode].layouts[display_mode]);
863             if (layout != context->get_base_layout()) {
864                 sclres_manager->unload();
865             }
866             if (!(sclres_manager->loaded(layout))) {
867                 sclres_manager->load(layout);
868                 resize_layout_by_resolution(layout, TRUE);
869             }
870             context->set_base_layout(layout);
871
872             pCurLayout = &mCurBaseLayout;
873             pCurLayoutKeyCoordination = &mCurBaseLayoutKeyCoordination;
874             pCurButtonContext = &mCurBaseButtonContext;
875         } else {
876             popupindex = windows->find_popup_window_index(window);
877             /* Check if the popup index is in valid range */
878             scl_assert_return_false(popupindex >= 0 && popupindex < MAX_POPUP_WINDOW);
879
880             layout = context->get_popup_layout(window);
881
882             if (!(sclres_manager->loaded(layout))) {
883                 sclres_manager->load(layout);
884                 resize_layout_by_resolution(layout, TRUE);
885             }
886             context->set_base_layout(layout);
887
888             if (popupindex >= 0 && popupindex < MAX_POPUP_WINDOW) {
889                 if (!(windows->is_base_window(window))) {
890                     SclWindowContext *winctx = windows->get_window_context(window);
891                     if (winctx) {
892                         if (winctx->inputmode != NOT_USED) {
893                             inputmode = winctx->inputmode;
894                         }
895                         if (winctx->layout != NOT_USED) {
896                             layout = winctx->layout;
897                         }
898                     }
899                 }
900
901                 pCurLayout = &mCurPopupLayout[popupindex];
902                 pCurLayoutKeyCoordination = &mCurPopupLayoutKeyCoordination[popupindex];
903
904                 pCurButtonContext = &mCurPopupButtonContext[popupindex];
905             }
906         }
907
908         if (pCurLayout && pCurLayoutKeyCoordination && pCurButtonContext) {
909             /* If the layout index represents system-defined autopopup, generate layout and key properties data */
910             if (layout == SCL_LAYOUT_AUTOPOPUP) {
911                 const SclLayoutKeyCoordinate *coordination =
912                     get_cur_layout_key_coordinate(context->get_cur_pressed_window(context->get_last_touch_device_id()),
913                         context->get_cur_pressed_key(context->get_last_touch_device_id()));
914
915                 generate_autopopup_layout(coordination, pCurLayout, pCurLayoutKeyCoordination, pCurButtonContext);
916             } else {
917                 if (scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
918                     memcpy(pCurLayout, &sclres_layout[layout], sizeof(SclLayout));
919
920                     memset(pCurLayoutKeyCoordination, 0x00, sizeof(SclLayoutKeyCoordinate) * (MAX_KEY));
921                     for (int i = 0; i < MAX_KEY; ++i) {
922                         SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][i];
923                         if (!p) break;
924                         memcpy((SclLayoutKeyCoordinatePointer)pCurLayoutKeyCoordination + i, p, sizeof(SclLayoutKeyCoordinate));
925                     }
926                     // FIXME Good Idea
927                     // memset(pCurLayoutKeyCoordination + i, 0x00, sizeof(SclLayoutKeyCoordinate) * (MAX_KEY - i));
928                     // memcpy(pCurLayoutKeyCoordination, sclres_layout_key_coordinate[layout], sizeof(SclLayoutKeyCoordinate) * MAX_KEY);
929                     memset(pCurButtonContext, 0x00, sizeof(SclButtonContext) * MAX_KEY);
930
931                     for (loop = 0;loop < MAX_KEY;loop++) {
932                         SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
933                         if (p && p->valid) {
934                             (*pCurButtonContext)[loop].used = TRUE;
935                             if (popupindex != NOT_USED) {
936                                 change_by_privatekey(inputmode, layout, loop, &(mCurPopupLayoutKeyCoordination[popupindex][loop]));
937                             } else {
938                                 change_by_privatekey(inputmode, layout, loop, &(mCurBaseLayoutKeyCoordination[loop]));
939                             }
940                             /* if this button is UIITEM type, set the state of this button disabled */
941                             if ((*pCurLayoutKeyCoordination)[loop].button_type == BUTTON_TYPE_UIITEM) {
942                                 (*pCurButtonContext)[loop].state = BUTTON_STATE_DISABLED;
943                             }
944
945                             /* If this button's custom id is in the disabled key list, make it disabled */
946                             if ((*pCurLayoutKeyCoordination)[loop].custom_id) {
947                                 for (sclint inner_loop = 0;inner_loop < MAX_DISABLED_KEY;inner_loop++) {
948                                     if (!(mDisabledKeyList[inner_loop].empty())) {
949                                         if (mDisabledKeyList[inner_loop].compare(
950                                             (*pCurLayoutKeyCoordination)[loop].custom_id) == 0) {
951                                                 (*pCurButtonContext)[loop].state = BUTTON_STATE_DISABLED;
952                                         }
953                                     }
954                                 }
955                             }
956                         }
957                     }
958                 }
959             }
960
961             /* Resize window */
962             /*if (windows->is_base_window(window)) {
963                 windows->resize_window(window, mCurBaseLayout.width, mCurBaseLayout.height);
964                 windows->resize_window(windows->get_dim_window(), mCurBaseLayout.width, mCurBaseLayout.height);
965             }*/
966
967             /* EFL testing */
968             windows->update_window(window);
969         }
970     }
971
972     return TRUE;
973 }
974
975 /**
976  * Returns the current key_coordination data
977  */
978 SclLayoutKeyCoordinate*
979 CSCLResourceCache::get_cur_layout_key_coordinate(sclwindow window, sclbyte key_index)
980 {
981     SCL_DEBUG();
982     scl_assert_return_null(key_index < MAX_KEY);
983
984     CSCLWindows *windows = CSCLWindows::get_instance();
985     if (windows->get_base_window() == window) {
986         if (key_index < MAX_KEY) {
987             return &mCurBaseLayoutKeyCoordination[key_index];
988         }
989     } else {
990         sclbyte popupindex = windows->find_popup_window_index(window);
991         scl_assert_return_false(popupindex < MAX_POPUP_WINDOW);
992         if (key_index < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
993             return &mCurPopupLayoutKeyCoordination[popupindex][key_index];
994         }
995     }
996
997     return NULL;
998 }
999
1000 /**
1001  * FIXME : This must be very SLOW - let's refine this function ASAP
1002  * Returns the current label_properties data
1003  */
1004 const SclLabelProperties*
1005 CSCLResourceCache::get_label_properties(sclchar *label_type, sclbyte index) const
1006 {
1007     SCL_DEBUG();
1008
1009     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1010     PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
1011     assert(sclres_label_properties != NULL);
1012     if (sclres_label_properties && label_type) {
1013         /* FIXME */
1014         //if (scl_check_arrindex(labeltype, MAX_LABEL_PROPERTIES) && scl_check_arrindex(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
1015         for(sclshort labeltype = 0;
1016             labeltype < MAX_SCL_LABEL_PROPERTIES && labeltype < sclres_manager->get_labelproperty_size();
1017             labeltype++) {
1018                 if (sclres_label_properties[labeltype][0].label_type) {
1019                     if (strcmp(sclres_label_properties[labeltype][0].label_type, label_type) == 0) {
1020                     if (scl_check_arrindex_unsigned(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
1021                         return &sclres_label_properties[labeltype][index];
1022                     }
1023                 }
1024             }
1025         }
1026     }
1027
1028     CSCLUtils *utils = CSCLUtils::get_instance();
1029     if (utils) {
1030         utils->log("WARNINNG!!!!!!!!!!!!!!!!!! LABEL NAME %s COULD NOT BE FOUND!!!!!\n", label_type);
1031     }
1032
1033     return NULL;
1034 }
1035
1036 /**
1037  * Returns the current button_context data
1038  */
1039 SclButtonContext*
1040 CSCLResourceCache::get_cur_button_context(sclwindow window, sclbyte key_index)
1041 {
1042     SCL_DEBUG();
1043     scl_assert_return_null(key_index < MAX_KEY);
1044
1045     CSCLWindows *windows = CSCLWindows::get_instance();
1046     if (windows->get_base_window() == window) {
1047         if (key_index < MAX_KEY) {
1048             return &mCurBaseButtonContext[key_index];
1049         }
1050     } else {
1051         sclbyte popupindex = windows->find_popup_window_index(window);
1052         scl_assert_return_null(popupindex < MAX_POPUP_WINDOW);
1053         if (key_index < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
1054             return &mCurPopupButtonContext[popupindex][key_index];
1055         }
1056     }
1057
1058     return NULL;
1059 }
1060
1061 /* Generate and fill autopopup layout data */
1062 void CSCLResourceCache::generate_autopopup_layout( const SclLayoutKeyCoordinate *coordination,
1063         SclLayout *pCurLayout, SclLayoutKeyCoordinate (*pCurLayoutKeyCoordination)[MAX_KEY],
1064         SclButtonContext (*pCurButtonContext)[MAX_KEY] )
1065 {
1066     SCL_DEBUG();
1067
1068     CSCLUtils *utils = CSCLUtils::get_instance();
1069     CSCLContext *context = CSCLContext::get_instance();
1070
1071     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1072     PSclAutoPopupConfigure autopopup_configure = NULL;
1073     if (sclres_manager) {
1074         autopopup_configure = sclres_manager->get_autopopup_configure();
1075     }
1076
1077     int loop;
1078     if (coordination && autopopup_configure) {
1079         sclbyte num_keys, num_columns, num_rows;
1080         sclint x, y, width, height;
1081         SCLShiftState shiftidx = context->get_shift_state();
1082         if (shiftidx < 0 || shiftidx >= SCL_SHIFT_STATE_MAX) shiftidx = SCL_SHIFT_STATE_OFF;
1083         if (utils->get_autopopup_window_variables(coordination->autopopup_key_labels[shiftidx], &num_keys, &num_columns, &num_rows, &width, &height)) {
1084             int row = 0, column = 0;
1085
1086             pCurLayout->use_magnifier_window = FALSE;
1087             pCurLayout->valid = TRUE;
1088             pCurLayout->style = LAYOUT_STYLE_POPUP_GRAB;
1089             pCurLayout->name = NULL;
1090             pCurLayout->width = width;
1091             pCurLayout->height = height;
1092             memset(pCurLayout->image_path, 0x00, sizeof(pCurLayout->image_path));
1093             pCurLayout->use_sw_background = TRUE;
1094             if (autopopup_configure->bg_image_path != NULL) {
1095                 pCurLayout->image_path[0] = autopopup_configure->bg_image_path;
1096                 pCurLayout->use_sw_background = FALSE;
1097             }
1098             pCurLayout->use_sw_button = TRUE;
1099             /* If button image path is set, use images instead of SW buttons */
1100             if (autopopup_configure->button_image_path[0] != NULL) {
1101                 pCurLayout->use_sw_button = FALSE;
1102             }
1103             pCurLayout->use_magnifier_window = FALSE;
1104             pCurLayout->extract_background = FALSE;
1105             pCurLayout->bg_color = autopopup_configure->bg_color;
1106             pCurLayout->bg_line_width = autopopup_configure->bg_line_width;
1107             pCurLayout->bg_line_color = autopopup_configure->bg_line_color;
1108             pCurLayout->add_grab_left = autopopup_configure->add_grab_left;
1109             pCurLayout->add_grab_right = autopopup_configure->add_grab_right;
1110             pCurLayout->add_grab_top = autopopup_configure->add_grab_top;
1111             pCurLayout->add_grab_bottom = autopopup_configure->add_grab_bottom;
1112             pCurLayout->mouse_manipulate_x = 0;
1113             pCurLayout->mouse_manipulate_y = (autopopup_configure->button_height * -1);
1114
1115             memset((*pCurLayoutKeyCoordination), 0x00, sizeof(SclLayoutKeyCoordinate) * MAX_KEY);
1116
1117             memset((*pCurButtonContext), 0x00, sizeof(SclButtonContext) * MAX_KEY);
1118
1119             for (loop = 0;loop < (num_columns * num_rows) && loop < MAX_KEY && loop < MAX_SIZE_OF_AUTOPOPUP_STRING;loop++) {
1120                 column = (loop % num_columns);
1121                 row = loop / num_columns;
1122                 x = autopopup_configure->bg_padding + (autopopup_configure->button_width * column) +
1123                     (autopopup_configure->button_spacing * column);
1124                 y = autopopup_configure->bg_padding + (autopopup_configure->button_height * (num_rows - row - 1)) +
1125                     (autopopup_configure->button_spacing * row);
1126
1127                 (*pCurLayoutKeyCoordination)[loop].valid = TRUE;
1128                 (*pCurLayoutKeyCoordination)[loop].x = x + autopopup_configure->decoration_size;
1129                 (*pCurLayoutKeyCoordination)[loop].y = y + autopopup_configure->decoration_size;
1130                 (*pCurLayoutKeyCoordination)[loop].width = autopopup_configure->button_width;
1131                 (*pCurLayoutKeyCoordination)[loop].height = autopopup_configure->button_height;
1132                 (*pCurLayoutKeyCoordination)[loop].popup_relative_x = 0;
1133                 (*pCurLayoutKeyCoordination)[loop].popup_relative_y = 0;
1134                 (*pCurLayoutKeyCoordination)[loop].extract_offset_x = 0;
1135                 (*pCurLayoutKeyCoordination)[loop].extract_offset_y = 0;
1136                 (*pCurLayoutKeyCoordination)[loop].sub_layout = NULL;
1137
1138                 (*pCurLayoutKeyCoordination)[loop].valid = TRUE;
1139                 if (loop < num_keys) {
1140                     (*pCurLayoutKeyCoordination)[loop].button_type = BUTTON_TYPE_NORMAL;
1141                 } else {
1142                     (*pCurLayoutKeyCoordination)[loop].button_type = BUTTON_TYPE_UIITEM;
1143                 }
1144                 (*pCurLayoutKeyCoordination)[loop].key_type = KEY_TYPE_STRING;
1145                 (*pCurLayoutKeyCoordination)[loop].popup_type = POPUP_TYPE_NONE;
1146                 (*pCurLayoutKeyCoordination)[loop].use_magnifier = FALSE;
1147                 (*pCurLayoutKeyCoordination)[loop].use_long_key_magnifier = TRUE;
1148                 memset((*pCurLayoutKeyCoordination)[loop].popup_input_mode, NOT_USED, sizeof((*pCurLayoutKeyCoordination)[loop].popup_input_mode));
1149
1150                 (*pCurLayoutKeyCoordination)[loop].valid = TRUE;
1151                 (*pCurLayoutKeyCoordination)[loop].label_count = 1;
1152                 (*pCurLayoutKeyCoordination)[loop].label[0][0] = coordination->autopopup_key_labels[0][loop];
1153                 (*pCurLayoutKeyCoordination)[loop].label[1][0] = coordination->autopopup_key_labels[1][loop];
1154                 (*pCurLayoutKeyCoordination)[loop].label[2][0] = coordination->autopopup_key_labels[2][loop];
1155                 //(*pCurLayoutKeyProperties)[loop].labelPropId = SCL_LABEL_PROPERTY_AUTOPOPUP;
1156                 (*pCurLayoutKeyCoordination)[loop].label_type = autopopup_configure->label_type;
1157                 memset((*pCurLayoutKeyCoordination)[loop].image_label_path, 0x00, sizeof((*pCurLayoutKeyCoordination)[loop].image_label_path));
1158                 memset((*pCurLayoutKeyCoordination)[loop].bg_image_path, 0x00, sizeof((*pCurLayoutKeyCoordination)[loop].bg_image_path));
1159                 for (int innerLoop = 0;innerLoop < SCL_BUTTON_STATE_MAX;innerLoop++) {
1160                     (*pCurLayoutKeyCoordination)[loop].bg_image_path[SCL_SHIFT_STATE_OFF][innerLoop] =
1161                         (*pCurLayoutKeyCoordination)[loop].bg_image_path[SCL_SHIFT_STATE_ON][innerLoop] =
1162                         (*pCurLayoutKeyCoordination)[loop].bg_image_path[SCL_SHIFT_STATE_LOCK][innerLoop] =
1163                             autopopup_configure->button_image_path[innerLoop];
1164                 }
1165
1166                 (*pCurLayoutKeyCoordination)[loop].key_value_count = 1;
1167
1168                 if (coordination->autopopup_key_values[0][loop] == NULL) {
1169                     (*pCurLayoutKeyCoordination)[loop].key_value[0][0] = coordination->autopopup_key_labels[0][loop];
1170                 } else {
1171                     (*pCurLayoutKeyCoordination)[loop].key_value[0][0] = coordination->autopopup_key_values[0][loop];
1172                 }
1173                 if (coordination->autopopup_key_values[1][loop] == NULL) {
1174                     (*pCurLayoutKeyCoordination)[loop].key_value[1][0] = coordination->autopopup_key_labels[1][loop];
1175                 } else {
1176                     (*pCurLayoutKeyCoordination)[loop].key_value[1][0] = coordination->autopopup_key_values[1][loop];
1177                 }
1178                 if (coordination->autopopup_key_values[2][loop] == NULL) {
1179                     (*pCurLayoutKeyCoordination)[loop].key_value[2][0] = coordination->autopopup_key_labels[2][loop];
1180                 } else {
1181                     (*pCurLayoutKeyCoordination)[loop].key_value[2][0] = coordination->autopopup_key_values[2][loop];
1182                 }
1183                 (*pCurLayoutKeyCoordination)[loop].key_event[0][0] = coordination->autopopup_key_events[0][loop];
1184                 (*pCurLayoutKeyCoordination)[loop].key_event[1][0] = coordination->autopopup_key_events[1][loop];
1185                 (*pCurLayoutKeyCoordination)[loop].key_event[2][0] = coordination->autopopup_key_events[2][loop];
1186                 (*pCurLayoutKeyCoordination)[loop].long_key_type = KEY_TYPE_NONE;
1187                 (*pCurLayoutKeyCoordination)[loop].long_key_value = NULL;
1188                 (*pCurLayoutKeyCoordination)[loop].long_key_event = 0;
1189
1190                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_labels[0][0] = NULL;
1191                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_labels[1][0] = NULL;
1192                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_labels[2][0] = NULL;
1193                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_events[0][0] = 0;
1194                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_events[1][0] = 0;
1195                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_events[2][0] = 0;
1196                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_values[0][0] = NULL;
1197                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_values[1][0] = NULL;
1198                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_values[2][0] = NULL;
1199                 (*pCurLayoutKeyCoordination)[loop].extra_option = 0;
1200
1201                 /* If the keyvalue is in between the SCL_ISCHAR range, consider this to be a KEY_TYPE_CHAR */
1202                 if ((*pCurLayoutKeyCoordination)[loop].key_value[0][0]) {
1203                     if (strlen((*pCurLayoutKeyCoordination)[loop].key_value[0][0]) == 1) {
1204                         if (SCL_ISCHAR(*(*pCurLayoutKeyCoordination)[loop].key_value[0][0])) {
1205                             (*pCurLayoutKeyCoordination)[loop].key_type = KEY_TYPE_CHAR;
1206                         }
1207                     }
1208                 }
1209
1210                 (*pCurButtonContext)[loop].used = TRUE;
1211             }
1212             if (autopopup_configure->decoration_size > 0) {
1213                 sclbyte decoidx;
1214                 for (decoidx = 0;decoidx < MAX_WND_DECORATOR;decoidx++) {
1215                     if (loop + decoidx < MAX_KEY) {
1216                         (*pCurLayoutKeyCoordination)[loop + decoidx].valid = TRUE;
1217                         switch (decoidx) {
1218                             case WND_DECORATOR_TOP_LEFT:
1219                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1220                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
1221                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1222                                     autopopup_configure->decoration_size;
1223                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1224                                     autopopup_configure->decoration_size;
1225                             break;
1226                             case WND_DECORATOR_TOP_CENTER:
1227                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1228                                     autopopup_configure->decoration_size;
1229                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
1230                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1231                                     width - (2 * autopopup_configure->decoration_size);
1232                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1233                                     autopopup_configure->decoration_size;
1234                                 break;
1235                             case WND_DECORATOR_TOP_RIGHT:
1236                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1237                                     width - autopopup_configure->decoration_size;
1238                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
1239                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1240                                     autopopup_configure->decoration_size;
1241                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1242                                     autopopup_configure->decoration_size;
1243                                 break;
1244                             case WND_DECORATOR_MIDDLE_LEFT:
1245                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1246                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1247                                     autopopup_configure->decoration_size;
1248                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1249                                     autopopup_configure->decoration_size;
1250                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1251                                     height - (2 * autopopup_configure->decoration_size);
1252                                 break;
1253                             case WND_DECORATOR_MIDDLE_RIGHT:
1254                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1255                                     width - autopopup_configure->decoration_size;
1256                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1257                                     autopopup_configure->decoration_size;
1258                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1259                                     autopopup_configure->decoration_size;
1260                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1261                                     height - (2 * autopopup_configure->decoration_size);
1262                                 break;
1263                             case WND_DECORATOR_BOTTOM_LEFT:
1264                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1265                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1266                                     height - autopopup_configure->decoration_size;
1267                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1268                                     autopopup_configure->decoration_size;
1269                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1270                                     autopopup_configure->decoration_size;
1271                                 break;
1272                             case WND_DECORATOR_BOTTOM_CENTER:
1273                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1274                                     autopopup_configure->decoration_size;
1275                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1276                                     height - autopopup_configure->decoration_size;
1277                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1278                                     width - (2 * autopopup_configure->decoration_size);
1279                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1280                                     autopopup_configure->decoration_size;
1281                                 break;
1282                             case WND_DECORATOR_BOTTOM_RIGHT:
1283                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1284                                     width - autopopup_configure->decoration_size;
1285                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1286                                     height - autopopup_configure->decoration_size;
1287                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1288                                     autopopup_configure->decoration_size;
1289                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1290                                     autopopup_configure->decoration_size;
1291                                 break;
1292                         }
1293                         
1294                         (*pCurButtonContext)[loop + decoidx].used = TRUE;
1295                         (*pCurLayoutKeyCoordination)[loop + decoidx].valid = TRUE;
1296                         (*pCurLayoutKeyCoordination)[loop + decoidx].button_type = BUTTON_TYPE_UIITEM;
1297                         (*pCurLayoutKeyCoordination)[loop + decoidx].valid = TRUE;
1298                         (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[0][0] =
1299                             (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[0][1] =
1300                             (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[1][0] =
1301                             (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[1][1] =
1302                             autopopup_configure->decoration_image_path[decoidx];
1303                     }
1304                 }
1305             }
1306         }
1307     }
1308 }
1309
1310 /**
1311 * Sets the current theme name
1312 */
1313 sclboolean
1314 CSCLResourceCache::set_cur_themename( const sclchar *themename )
1315 {
1316     /*SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1317     const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
1318     assert(sclres_label_properties != NULL);*/
1319     if (themename) {
1320         strncpy(mCurThemename, themename, _POSIX_PATH_MAX - 1);
1321         mCurThemename[_POSIX_PATH_MAX - 1] = '\0';
1322
1323         /*CSCLUtils *utils = CSCLUtils::get_instance();
1324         utils->get_composed_path(fontprop_path, FONT_PROPERTIES_FILE);
1325         FILE *fp = fopen(fontprop_path, "r");
1326         if (fp) {
1327             sclint index = 0;
1328             sclint r,g,b,a;
1329             if (!feof(fp)) {
1330                 for(sclint shiftstate = 0;shiftstate < SCL_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1331                     char comment[_POSIX_PATH_MAX];
1332                     for(sclint buttonstate = 0;buttonstate < SCL_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1333                         fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1334                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].r = r;
1335                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].g = g;
1336                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].b = b;
1337                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].a = a;
1338                     }
1339                     fscanf(fp, "%s", comment);
1340                 }
1341             }
1342             if (!feof(fp)) {
1343                 sclint subindex = 0;
1344                 while (subindex < MAX_SIZE_OF_LABEL_FOR_ONE && !feof(fp) && scl_magnifier_configure.labelProp[subindex].valid) {
1345                     for(sclint shiftstate = 0;shiftstate < SCL_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1346                         char comment[_POSIX_PATH_MAX];
1347                         for(sclint buttonstate = 0;buttonstate < SCL_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1348                             fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1349                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].r = r;
1350                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].g = g;
1351                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].b = b;
1352                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].a = a;
1353                         }
1354                         fscanf(fp, "%s", comment);
1355                     }
1356                     subindex++;
1357                 }
1358             }
1359             index = 0;
1360             while (index < MAX_LABEL_PROPERTIES && !feof(fp)) {
1361                 sclint subindex = 0;
1362                 while (subindex < MAX_SIZE_OF_LABEL_FOR_ONE && !feof(fp) && sclres_label_properties[index][subindex].valid) {
1363                     for(sclint shiftstate = 0;shiftstate < SCL_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1364                         char comment[_POSIX_PATH_MAX];
1365                         for(sclint buttonstate = 0;buttonstate < SCL_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1366                             fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1367                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].r = r;
1368                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].g = g;
1369                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].b = b;
1370                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].a = a;
1371                         }
1372                         fscanf(fp, "%s", comment);
1373                     }
1374                     subindex++;
1375                 }
1376                 index++;
1377             }
1378             fclose(fp);
1379         }*/
1380     }
1381
1382     return TRUE;
1383 }
1384
1385 const sclchar*
1386 CSCLResourceCache::get_cur_themename()
1387 {
1388     return mCurThemename;
1389 }
1390
1391 /**
1392  * Returns a template private key properties using key properties of the given context
1393  */
1394 void
1395 CSCLResourceCache::clone_keyproperties(SclPrivateKeyProperties* priv, sclbyte input_mode_index, sclbyte layout_index, sclbyte key_index)
1396 {
1397     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1398     const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
1399
1400     SCL_DEBUG();
1401     if (priv && sclres_layout_key_coordinate_pointer_frame) {
1402         CSCLResourceCache *cache = CSCLResourceCache::get_instance();
1403         clear_privatekeyproperties(priv);
1404
1405         /* gets the value of the previous key properties */
1406         sclint loop;
1407         SclLayoutKeyCoordinate keyCoordination = { 0 };
1408         if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT) &&
1409             scl_check_arrindex_unsigned(key_index, MAX_KEY)) {
1410             SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][key_index];
1411             if (p) {
1412                 memcpy(&keyCoordination, p, sizeof(SclLayoutKeyCoordinate));
1413             }
1414         }
1415
1416         scl_assert_return(keyCoordination.valid == TRUE);
1417
1418         /* Sets the default properties base on the properties values of the given context */
1419         cache->copy_to_privatekeyproperties(&keyCoordination, priv);
1420     }
1421 }
1422
1423 /**
1424  * Sets a private key to the current context
1425  *
1426  * @Usage
1427  *       SclPrivateKeyProperties privProperties;
1428  *       gCore->clone_keyproperties(&privProperties, INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
1429  *       // change
1430  *       gCore->set_private_key(&privProperties, TRUE);
1431  */
1432 sclint
1433 CSCLResourceCache::set_private_key(SclPrivateKeyProperties* properties, sclboolean fRedraw, sclboolean fPendingUpdate)
1434 {
1435     SCL_DEBUG();
1436     CSCLContext *context = CSCLContext::get_instance();
1437     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
1438     sclint privateId = NOT_USED;
1439     sclboolean isNeedUpdate = FALSE;
1440     if (cache && context && properties) {
1441         privateId = cache->add_private_key(properties, &isNeedUpdate);
1442         if (fRedraw && isNeedUpdate && !fPendingUpdate && privateId != NOT_USED) {
1443             CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
1444             CSCLWindows *windows = CSCLWindows::get_instance();
1445             if (builder && windows) {
1446                 /* Fix me (we should consider popupwindow later)*/
1447                 sclwindow window = windows->get_base_window();
1448                 /* Let's draw this private key only if the key's sublayout ID is active */
1449                 SclLayoutKeyCoordinate *coordination = get_cur_layout_key_coordinate(window, properties->key_index);
1450                 if (coordination) {
1451                     sclboolean redraw = TRUE;
1452                     if (coordination->sub_layout && context->get_cur_sublayout()) {
1453                         if (strncmp(coordination->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
1454                             redraw = FALSE;
1455                         }
1456                     }
1457                     if (redraw) {
1458                         windows->update_window(window,
1459                             coordination->x, coordination->y, coordination->width, coordination->height);
1460                         //builder->draw_button(window, NULL, properties->key_index, mCurBaseButtonContext[properties->key_index].state);
1461                     }
1462                 }
1463                 /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
1464                 //windows->update_window(windows->get_base_window());
1465             }
1466         }
1467     }
1468     return privateId;
1469 }
1470
1471 /**
1472  * Sets a private key to the current context
1473  * The other properties except given parameters will keep to the orginal value.
1474  * @Usage
1475  * gCore->set_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0, "private", 999, TRUE);
1476  *
1477  * @param fRedraw If true, it will redraw the current key
1478  */
1479 sclint
1480 CSCLResourceCache::set_private_key(sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean fRedraw, sclboolean fPendingUpdate)
1481 {
1482     SCL_DEBUG();
1483
1484     SclPrivateKeyProperties privProperties;
1485     clear_privatekeyproperties(&privProperties);
1486
1487     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1488     PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
1489     assert(sclres_layout_key_coordinate_pointer_frame != NULL);
1490
1491     sclint loop;
1492
1493     privProperties.valid = TRUE;
1494     privProperties.custom_id = custom_id;
1495
1496     privProperties.key_event[SCL_SHIFT_STATE_LOCK][0] = privProperties.key_event[SCL_SHIFT_STATE_ON][0] =
1497         privProperties.key_event[SCL_SHIFT_STATE_OFF][0] = key_event;
1498     if (label) {
1499         privProperties.label[SCL_SHIFT_STATE_LOCK][0] = label;
1500         privProperties.label[SCL_SHIFT_STATE_ON][0] = label;
1501         privProperties.label[SCL_SHIFT_STATE_OFF][0] = label;
1502         privProperties.label_count = 1;
1503     }
1504     if (key_value) {
1505         privProperties.key_value[SCL_SHIFT_STATE_LOCK][0] = privProperties.key_value[SCL_SHIFT_STATE_ON][0] =
1506             privProperties.key_value[SCL_SHIFT_STATE_OFF][0] = key_value;
1507     }
1508     if (imagelabel) {
1509         for (loop =0;loop < SCL_BUTTON_STATE_MAX;loop++) {
1510             if (imagelabel[loop])
1511                 privProperties.image_label_path[SCL_SHIFT_STATE_LOCK][loop] =
1512                     privProperties.image_label_path[SCL_SHIFT_STATE_ON][loop] =
1513                     privProperties.image_label_path[SCL_SHIFT_STATE_OFF][loop] = imagelabel[loop];
1514             }
1515         }
1516     if (imagebg) {
1517         for (loop =0;loop < SCL_BUTTON_STATE_MAX;loop++) {
1518             if (imagebg[loop]) {
1519                 privProperties.bg_image_path[SCL_SHIFT_STATE_LOCK][loop] =
1520                     privProperties.bg_image_path[SCL_SHIFT_STATE_ON][loop] =
1521                     privProperties.bg_image_path[SCL_SHIFT_STATE_OFF][loop] = imagebg[loop];
1522             }
1523         }
1524     }
1525     return set_private_key(&privProperties, fRedraw, fPendingUpdate);
1526 }
1527
1528 /**
1529 * Unset private key for specific key
1530 * @Usage
1531 * gCore->unset_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
1532 */
1533 void
1534 CSCLResourceCache::unset_private_key(sclshort input_mode_index, sclbyte layout_index, sclbyte key_index)
1535 {
1536     sclint loop = 0;
1537     for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
1538         if ((mPrivateKeyProperties[loop].input_mode_index == input_mode_index) &&
1539             mPrivateKeyProperties[loop].layout_index == layout_index &&
1540             mPrivateKeyProperties[loop].key_index == key_index) {
1541                 remove_private_key(loop);
1542         }
1543     }
1544 }
1545
1546 /**
1547 * Unset private by custom_id, effective when removing all private keys with same custom_id
1548 * @Usage
1549 * gCore->unset_private_key(3);
1550 */
1551 void
1552 CSCLResourceCache::unset_private_key(const sclchar* custom_id)
1553 {
1554     int loop;
1555     if (custom_id) {
1556         for(loop = 0;loop < MAX_PRIVATE_KEY;loop++) {
1557             if (mPrivateKeyProperties[loop].valid &&
1558                 mPrivateKeyProperties[loop].custom_id.compare(custom_id) == 0) {
1559                 remove_private_key(loop);
1560             }
1561         }
1562     }
1563 }
1564
1565 /**
1566 * Find appropriate index of the key specified by custom_id
1567 */
1568 sclbyte
1569 CSCLResourceCache::find_keyidx_by_customid(const sclchar* custom_id)
1570 {
1571     sclbyte ret = NOT_USED;
1572     sclint loop;
1573
1574     CSCLContext *context = CSCLContext::get_instance();
1575     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1576     PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
1577
1578     assert(sclres_layout_key_coordinate_pointer_frame != NULL);
1579
1580     sclshort input_mode_index = NOT_USED;
1581     sclbyte layout_index = NOT_USED;
1582     if (context) {
1583         input_mode_index = context->get_input_mode();
1584         layout_index = context->get_base_layout();
1585     }
1586
1587     if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT) && custom_id) {
1588         for (loop = 0;loop < MAX_KEY;loop++) {
1589             SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][loop];
1590             if (!p || !(p->valid)) break;
1591             if (p->custom_id) {
1592                 if (strcmp(p->custom_id, custom_id) == 0) {
1593                     ret = loop;
1594                     break;
1595                 }
1596             }
1597         }
1598     }
1599
1600     return ret;
1601 }
1602
1603 /**
1604 * Enable/disable button for handling mouse events
1605 */
1606 void CSCLResourceCache::enable_button(const sclchar *custom_id, sclboolean enabled)
1607 {
1608     SCL_DEBUG();
1609
1610     sclint loop;
1611     if (custom_id) {
1612         sclbyte key_index = find_keyidx_by_customid(custom_id);
1613         if (scl_check_arrindex_unsigned(key_index, MAX_KEY)) {
1614             if (enabled) {
1615                 mCurBaseButtonContext[key_index].state = BUTTON_STATE_NORMAL;
1616             } else {
1617                 mCurBaseButtonContext[key_index].state = BUTTON_STATE_DISABLED;
1618             }
1619
1620             CSCLWindows *windows = CSCLWindows::get_instance();
1621             /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
1622             windows->update_window(windows->get_base_window());
1623         }
1624
1625         sclboolean found = FALSE;
1626         sclint empty_index = -1;
1627
1628         for (loop = 0;loop < MAX_DISABLED_KEY;loop++) {
1629             if (!(mDisabledKeyList[loop].empty())) {
1630                 if (mDisabledKeyList[loop].compare(custom_id) == 0) {
1631                     if (enabled) {
1632                         /* Erase this item from the disabled key list */
1633                         mDisabledKeyList[loop].clear();
1634                     }
1635                     found = TRUE;
1636                 }
1637             } else {
1638                 empty_index = loop;
1639             }
1640         }
1641
1642         if (!found) {
1643             if (!enabled) {
1644                 if (scl_check_arrindex(empty_index, MAX_DISABLED_KEY)) {
1645                     /* Add to the disabled key */
1646                     mDisabledKeyList[empty_index] = custom_id;
1647                 }
1648             }
1649         }
1650     }
1651 }
1652
1653 void
1654 CSCLResourceCache::set_string_substitution(const sclchar *original, const sclchar *substitute)
1655 {
1656     if (original && substitute) {
1657         mStringSubstitutor[std::string(original)] = std::string(substitute);
1658     }
1659 }
1660
1661 void
1662 CSCLResourceCache::unset_string_substitution(const sclchar *original)
1663 {
1664     if (original) {
1665         mStringSubstitutor.erase(std::string(original));
1666     }
1667 }
1668
1669 const sclchar*
1670 CSCLResourceCache::find_substituted_string(const sclchar *original)
1671 {
1672     const sclchar* ret = original;
1673
1674     if (original) {
1675         std::map<std::string, std::string>::iterator iter = mStringSubstitutor.find(std::string(original));
1676         if (iter != mStringSubstitutor.end()) {
1677             ret = iter->second.c_str();
1678         }
1679     }
1680
1681     return ret;
1682 }