Tizen 2.0 Release
[profile/ivi/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     }
363
364     return TRUE;
365 }
366
367 /**
368  * Copys the given properties data to the given private key properties
369  */
370 sclboolean
371 CSCLResourceCache::copy_to_privatekeyproperties(const SclLayoutKeyCoordinate *coordination, SclPrivateKeyProperties* privProperties)
372 {
373     SCL_DEBUG();
374     scl_assert_return_false(privProperties);
375     scl_assert_return_false(coordination);
376
377     /* sets the current key Properties to private key privProperties */
378
379     sclint loop;
380     sclint inner_loop;
381     if (privProperties && coordination) {
382         /* Configure */
383         if (coordination->custom_id) {
384             privProperties->custom_id = coordination->custom_id;
385         }
386         privProperties->button_type = coordination->button_type;
387         privProperties->key_type = coordination->key_type;
388         privProperties->popup_type = coordination->popup_type;
389         privProperties->use_magnifier = coordination->use_magnifier;
390         privProperties->use_long_key_magnifier = coordination->use_long_key_magnifier;
391         if (coordination->sound_style) {
392             privProperties->sound_style = coordination->sound_style;
393         }
394         if (coordination->vibe_style) {
395             privProperties->vibe_style = coordination->vibe_style;
396         }
397
398         for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
399             if (coordination->popup_input_mode[loop]) {
400                 privProperties->popup_input_mode[loop] = coordination->popup_input_mode[loop];
401             }
402         }
403
404         /* Properties */
405         privProperties->label_count = coordination->label_count;
406         privProperties->key_value_count = coordination->key_value_count;
407         privProperties->long_key_type = coordination->long_key_type;
408         if (coordination->long_key_value) {
409             privProperties->long_key_value = coordination->long_key_value;
410         }
411         privProperties->long_key_event = coordination->long_key_event;
412         privProperties->use_repeat_key = coordination->use_repeat_key;
413         privProperties->dont_close_popup = coordination->dont_close_popup;
414         privProperties->extra_option = coordination->extra_option;
415         if (coordination->label_type) {
416             privProperties->label_type = coordination->label_type;
417         }
418         if (coordination->image_label_type) {
419             privProperties->image_label_type = coordination->image_label_type;
420         }
421
422         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
423             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
424                 if (coordination->label[loop][inner_loop]) {
425                     privProperties->label[loop][inner_loop] =
426                         coordination->label[loop][inner_loop];
427                 }
428             }
429         }
430         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
431             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
432                 if (coordination->image_label_path[loop][inner_loop]) {
433                     privProperties->image_label_path[loop][inner_loop] =
434                         coordination->image_label_path[loop][inner_loop];
435                 }
436             }
437         }
438         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
439             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
440                 if (coordination->bg_image_path[loop][inner_loop]) {
441                     privProperties->bg_image_path[loop][inner_loop] =
442                         coordination->bg_image_path[loop][inner_loop];
443                 }
444             }
445         }
446
447         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
448             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
449                 if (coordination->key_value[loop][inner_loop]) {
450                     privProperties->key_value[loop][inner_loop] =
451                         coordination->key_value[loop][inner_loop];
452                 }
453             }
454         }
455         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
456             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
457                 if (coordination->key_event[loop][inner_loop]) {
458                     privProperties->key_event[loop][inner_loop] =
459                         coordination->key_event[loop][inner_loop];
460                 }
461             }
462         }
463
464         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
465             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
466                 if (coordination->autopopup_key_labels[loop][inner_loop]) {
467                     privProperties->autopopup_key_labels[loop][inner_loop] =
468                         coordination->autopopup_key_labels[loop][inner_loop];
469                 }
470             }
471         }
472         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
473             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
474                 if (coordination->autopopup_key_events[loop][inner_loop]) {
475                     privProperties->autopopup_key_events[loop][inner_loop] =
476                         coordination->autopopup_key_events[loop][inner_loop];
477                 }
478             }
479         }
480         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
481             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
482                 if (coordination->autopopup_key_values[loop][inner_loop]) {
483                     privProperties->autopopup_key_values[loop][inner_loop] =
484                         coordination->autopopup_key_values[loop][inner_loop];
485                 }
486             }
487         }
488     }
489
490     return TRUE;
491 }
492
493 /**
494  * Copys the given private properties data to the other private properties
495  */
496 sclboolean
497 CSCLResourceCache::copy_privatekeyproperties(const SclPrivateKeyProperties* source, SclPrivateKeyProperties* target)
498 {
499     SCL_DEBUG();
500     scl_assert_return_false(source);
501     scl_assert_return_false(target);
502
503     sclint loop;
504     sclint inner_loop;
505     if (source && target) {
506         target->input_mode_index = source->input_mode_index;
507         target->layout_index = source->layout_index;
508         target->key_index = source->key_index;
509
510         /* Configure */
511         target->custom_id = source->custom_id;
512         target->button_type = source->button_type;
513         target->key_type = source->key_type;
514         target->popup_type = source->popup_type;
515         target->use_magnifier = source->use_magnifier;
516         target->use_long_key_magnifier = source->use_long_key_magnifier;
517         target->sound_style = source->sound_style;
518         target->vibe_style = source->vibe_style;
519
520         for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
521             target->popup_input_mode[loop] = source->popup_input_mode[loop];
522         }
523
524         /* Properties */
525         target->label_count = source->label_count;
526         target->key_value_count = source->key_value_count;
527         target->long_key_type = source->long_key_type;
528         target->long_key_value = source->long_key_value;
529         target->long_key_event = source->long_key_event;
530         target->use_repeat_key = source->use_repeat_key;
531         target->dont_close_popup = source->dont_close_popup;
532         target->extra_option = source->extra_option;
533         target->label_type = source->label_type;
534         target->image_label_type = source->image_label_type;
535
536         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
537             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
538                 target->label[loop][inner_loop] =
539                     source->label[loop][inner_loop];
540             }
541         }
542         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
543             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
544                 target->image_label_path[loop][inner_loop] =
545                     source->image_label_path[loop][inner_loop];
546             }
547         }
548         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
549             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
550                 target->bg_image_path[loop][inner_loop] =
551                     source->bg_image_path[loop][inner_loop];
552             }
553         }
554
555         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
556             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
557                 target->key_value[loop][inner_loop] =
558                     source->key_value[loop][inner_loop];
559             }
560         }
561         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
562             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
563                 target->key_event[loop][inner_loop] =
564                     source->key_event[loop][inner_loop];
565             }
566         }
567
568         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
569             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
570                 target->autopopup_key_labels[loop][inner_loop] =
571                     source->autopopup_key_labels[loop][inner_loop];
572             }
573         }
574         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
575             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
576                 target->autopopup_key_events[loop][inner_loop] =
577                     source->autopopup_key_events[loop][inner_loop];
578             }
579         }
580         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
581             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
582                 target->autopopup_key_values[loop][inner_loop] =
583                     source->autopopup_key_values[loop][inner_loop];
584             }
585         }
586     }
587
588     return TRUE;
589 }
590
591 /**
592  * Clears the given private properties data
593  */
594 sclboolean
595 CSCLResourceCache::clear_privatekeyproperties(SclPrivateKeyProperties* privProperties)
596 {
597     SCL_DEBUG();
598     scl_assert_return_false(privProperties);
599
600     /* sets the current key Properties to private key privProperties */
601
602     sclint loop;
603     sclint inner_loop;
604     if (privProperties) {
605         /* Configure */
606         privProperties->valid = FALSE;
607         privProperties->input_mode_index = NOT_USED;
608         privProperties->layout_index = NOT_USED;
609         privProperties->key_index = NOT_USED;
610
611         privProperties->custom_id.clear();
612         privProperties->button_type = BUTTON_TYPE_NORMAL;
613         privProperties->key_type = KEY_TYPE_NONE;
614         privProperties->popup_type = POPUP_TYPE_NONE;
615         privProperties->use_magnifier = FALSE;
616         privProperties->use_long_key_magnifier = FALSE;
617         privProperties->sound_style.clear();
618         privProperties->vibe_style.clear();
619
620         for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
621             privProperties->popup_input_mode[loop].clear();
622         }
623
624         /* Properties */
625         privProperties->label_count = 0;
626         privProperties->key_value_count = 0;
627         privProperties->long_key_type = KEY_TYPE_NONE;
628         privProperties->long_key_value.clear();
629         privProperties->long_key_event = 0;
630         privProperties->use_repeat_key = FALSE;
631         privProperties->dont_close_popup = FALSE;
632         privProperties->extra_option = 0;
633         privProperties->label_type.clear();
634         privProperties->image_label_type.clear();
635
636         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
637             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
638                 privProperties->label[loop][inner_loop].clear();
639             }
640         }
641         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
642             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
643                 privProperties->image_label_path[loop][inner_loop].clear();
644             }
645         }
646         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
647             for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
648                 privProperties->bg_image_path[loop][inner_loop].clear();
649             }
650         }
651
652         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
653             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
654                 privProperties->key_value[loop][inner_loop].clear();
655             }
656         }
657         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
658             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
659                 privProperties->key_event[loop][inner_loop] = 0;
660             }
661         }
662
663         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
664             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
665                 privProperties->autopopup_key_labels[loop][inner_loop].clear();
666             }
667         }
668         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
669             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
670                 privProperties->autopopup_key_events[loop][inner_loop] = 0;
671             }
672         }
673         for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
674             for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
675                 privProperties->autopopup_key_values[loop][inner_loop].clear();
676             }
677         }
678     }
679
680     return TRUE;
681 }
682
683 /**
684  * Adds a new private key
685  * It will update it to the current cache properties context because the application can call it anytime
686  * For adapting it in realtime, you should explictly call the draw_button function.
687  *
688  * @param[out] fNeedInvalid It will return true if the current private can be adapt into the current display.
689  * @return id an array index of the private key
690  */
691 sclint
692 CSCLResourceCache::add_private_key(SclPrivateKeyProperties* privProperties, sclboolean *fNeedInvaild)
693 {
694     SCL_DEBUG();
695     scl_assert_return_false(privProperties);
696     sclint ret = NOT_USED;
697     *fNeedInvaild = FALSE; /* don't need to update now */
698
699     if (privProperties->custom_id.empty())
700         return ret;
701
702     /* Finds an index to be set */
703     sclint loop = 0;
704     for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
705         if (mPrivateKeyProperties[loop].custom_id.compare(privProperties->custom_id) == 0) {
706             break;
707         }
708     }
709
710     if (loop == MAX_PRIVATE_KEY) {
711         for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
712             if (mPrivateKeyProperties[loop].valid == FALSE) break;
713         }
714         if (loop == MAX_PRIVATE_KEY) {
715             printf("Out of buffer!! could not insert new private data into buffer \n");
716             return ret;
717         }
718     }
719
720     copy_privatekeyproperties(privProperties, &mPrivateKeyProperties[loop]);
721     mPrivateKeyProperties[loop].valid = TRUE;
722     ret = loop;
723
724     sclboolean found = FALSE;
725     for (int loop = 0;loop < MAX_KEY; loop++) {
726         if ((!(privProperties->custom_id.empty())) && mCurBaseLayoutKeyCoordination[loop].custom_id) {
727             if (privProperties->custom_id.compare(mCurBaseLayoutKeyCoordination[loop].custom_id) == 0) {
728                 /* sets the current properties to private key properties */
729                 copy_from_privatekeyproperties(privProperties, &mCurBaseLayoutKeyCoordination[loop]);
730                 found = TRUE;
731             }
732         }
733     }
734     if (found) {
735         *fNeedInvaild = TRUE;
736         return ret;
737     }
738
739 #if 0
740     /* For popup layout */
741     CSCLWindows *windows = CSCLWindows::get_instance();
742     for (int ploop = 0; ploop < MAX_POPUP_WINDOW; ploop++) {
743         layout = context->get_popup_layout(windows->get_nth_popup_window(ploop));
744         if (privProperties->input_mode_index == inputmode && privProperties->layout_index == layout) {
745             /* sets the current properties to private key properties */
746             copy_privatekeyproperties_to_keyproperties(privProperties, &mCurPopupLayoutKeyProperties[ploop][privProperties->key_index]);
747             return ret;
748             *fNeedInvaild = TRUE;
749         }
750     }
751 #endif
752
753     if (ret == NOT_USED) {
754         printf("Failed!. Out of private data buffer\n");
755     }
756     return ret;
757 }
758
759 /**
760  * Removes the private data of the given id from SclPrivateKeyProperties buffer
761  */
762 sclboolean
763 CSCLResourceCache::remove_private_key(sclint id)
764 {
765     SCL_DEBUG();
766     sclint loop;
767     CSCLContext *context = CSCLContext::get_instance();
768
769     /* resets the current properties to predefined properties */
770     sclbyte inputmode = context->get_input_mode();
771     sclshort layout =  context->get_base_layout();
772     sclbyte keyidx = mPrivateKeyProperties[id].key_index;
773     clone_keyproperties(&(mPrivateKeyProperties[id]),
774         mPrivateKeyProperties[id].input_mode_index, mPrivateKeyProperties[id].layout_index, keyidx);
775
776     /* reset only if this property has the current inputmode and layout id */
777     if (mPrivateKeyProperties[id].input_mode_index == inputmode &&
778         mPrivateKeyProperties[id].layout_index == layout) {
779         copy_from_privatekeyproperties(&(mPrivateKeyProperties[id]), &mCurBaseLayoutKeyCoordination[keyidx]);
780     }
781
782     /* Shift all the privatekey properties to the left by 1, starting from the item next to the id th element */
783     for (loop = id;loop < MAX_PRIVATE_KEY - 1; loop++) {
784         copy_privatekeyproperties(&mPrivateKeyProperties[loop + 1], &mPrivateKeyProperties[loop]);
785     }
786     /* Clear the last element */
787     clear_privatekeyproperties(&mPrivateKeyProperties[MAX_PRIVATE_KEY - 1]);
788     return TRUE;
789 }
790
791 /**
792  * Clears all private keys
793  */
794 sclboolean
795 CSCLResourceCache::clear_private_keys()
796 {
797     SCL_DEBUG();
798     for (sclint loop = 0; loop < MAX_PRIVATE_KEY;loop++) {
799         clear_privatekeyproperties(&mPrivateKeyProperties[loop]);
800     }
801     return TRUE;
802 }
803
804 /**
805  * Re-computes the cache data of the given window. The cache data has been including the current key properties, button context, layout etc,,
806  * Another role of this func is to adjust the current coordination according to the current resolution.
807  * This func will be called when a newly window is created
808  */
809 sclboolean
810 CSCLResourceCache::recompute_layout(sclwindow window)
811 {
812     SCL_DEBUG();
813
814     sclint loop;
815
816     CSCLWindows *windows = CSCLWindows::get_instance();
817     CSCLContext *context = CSCLContext::get_instance();
818     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
819     const PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
820     const PSclLayout sclres_layout = sclres_manager->get_layout_table();
821     const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
822         sclres_manager->get_key_coordinate_pointer_frame();
823     const PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
824     const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
825     const PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
826     assert(sclres_input_mode_configure != NULL);
827     assert(sclres_layout != NULL);
828     assert(sclres_layout_key_coordinate_pointer_frame != NULL);
829     assert(sclres_modifier_decoration != NULL);
830     assert(sclres_label_properties != NULL);
831
832     /* FIXME */
833     scl8 popupindex = NOT_USED;
834
835     SclLayout *pCurLayout = NULL;
836     SclLayoutKeyCoordinate (*pCurLayoutKeyCoordination)[MAX_KEY] = NULL;
837     SclButtonContext (*pCurButtonContext)[MAX_KEY] = NULL;
838
839     sclshort layout =  NOT_USED;
840     if (windows && context) {
841         sclbyte display = context->get_display_mode();
842         sclbyte inputmode = context->get_input_mode();
843
844         if (windows->is_base_window(window)) {
845             layout = sclres_manager->get_layout_id(sclres_input_mode_configure[inputmode].layouts[context->get_display_mode()]);
846             if (default_configure->use_lazy_loading) {
847                 if (layout != context->get_base_layout()) {
848                     sclres_manager->unload();
849                 }
850                 if (!(sclres_manager->loaded(layout))) {
851                     sclres_manager->load(layout);
852                     resize_layout_by_resolution(layout, TRUE);
853                 }
854             }
855             context->set_base_layout(layout);
856
857             pCurLayout = &mCurBaseLayout;
858             pCurLayoutKeyCoordination = &mCurBaseLayoutKeyCoordination;
859             pCurButtonContext = &mCurBaseButtonContext;
860         } else {
861             popupindex = windows->find_popup_window_index(window);
862             /* Check if the popup index is in valid range */
863             scl_assert_return_false(popupindex >= 0 && popupindex < MAX_POPUP_WINDOW);
864
865             layout = context->get_popup_layout(window);
866
867             if (default_configure->use_lazy_loading) {
868                 if (!(sclres_manager->loaded(layout))) {
869                     sclres_manager->load(layout);
870                     resize_layout_by_resolution(layout, TRUE);
871                 }
872             }
873             context->set_base_layout(layout);
874
875             if (popupindex >= 0 && popupindex < MAX_POPUP_WINDOW) {
876                 if (!(windows->is_base_window(window))) {
877                     SclWindowContext *winctx = windows->get_window_context(window);
878                     if (winctx) {
879                         if (winctx->inputmode != NOT_USED) {
880                             inputmode = winctx->inputmode;
881                         }
882                         if (winctx->layout != NOT_USED) {
883                             layout = winctx->layout;
884                         }
885                     }
886                 }
887
888                 pCurLayout = &mCurPopupLayout[popupindex];
889                 pCurLayoutKeyCoordination = &mCurPopupLayoutKeyCoordination[popupindex];
890
891                 pCurButtonContext = &mCurPopupButtonContext[popupindex];
892             }
893         }
894
895         if (pCurLayout && pCurLayoutKeyCoordination && pCurButtonContext) {
896             /* If the layout index represents system-defined autopopup, generate layout and key properties data */
897             if (layout == SCL_LAYOUT_AUTOPOPUP) {
898                 const SclLayoutKeyCoordinate *coordination =
899                     get_cur_layout_key_coordinate(context->get_cur_pressed_window(context->get_last_touch_device_id()),
900                         context->get_cur_pressed_key(context->get_last_touch_device_id()));
901
902                 generate_autopopup_layout(coordination, pCurLayout, pCurLayoutKeyCoordination, pCurButtonContext);
903             } else {
904                 if (scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
905                     memcpy(pCurLayout, &sclres_layout[layout], sizeof(SclLayout));
906
907                     memset(pCurLayoutKeyCoordination, 0x00, sizeof(SclLayoutKeyCoordinate) * (MAX_KEY));
908                     for (int i = 0; i < MAX_KEY; ++i) {
909                         SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][i];
910                         if (!p) break;
911                         memcpy((SclLayoutKeyCoordinatePointer)pCurLayoutKeyCoordination + i, p, sizeof(SclLayoutKeyCoordinate));
912                     }
913                     // FIXME Good Idea
914                     // memset(pCurLayoutKeyCoordination + i, 0x00, sizeof(SclLayoutKeyCoordinate) * (MAX_KEY - i));
915                     // memcpy(pCurLayoutKeyCoordination, sclres_layout_key_coordinate[layout], sizeof(SclLayoutKeyCoordinate) * MAX_KEY);
916                     memset(pCurButtonContext, 0x00, sizeof(SclButtonContext) * MAX_KEY);
917
918                     for (loop = 0;loop < MAX_KEY;loop++) {
919                         SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
920                         if (p && p->valid) {
921                             (*pCurButtonContext)[loop].used = TRUE;
922                             if (popupindex != NOT_USED) {
923                                 change_by_privatekey(inputmode, layout, loop, &(mCurPopupLayoutKeyCoordination[popupindex][loop]));
924                             } else {
925                                 change_by_privatekey(inputmode, layout, loop, &(mCurBaseLayoutKeyCoordination[loop]));
926                             }
927                             /* if this button is UIITEM type, set the state of this button disabled */
928                             if ((*pCurLayoutKeyCoordination)[loop].button_type == BUTTON_TYPE_UIITEM) {
929                                 (*pCurButtonContext)[loop].state = BUTTON_STATE_DISABLED;
930                             }
931
932                             /* If this button's custom id is in the disabled key list, make it disabled */
933                             if ((*pCurLayoutKeyCoordination)[loop].custom_id) {
934                                 for (sclint inner_loop = 0;inner_loop < MAX_DISABLED_KEY;inner_loop++) {
935                                     if (!(mDisabledKeyList[inner_loop].empty())) {
936                                         if (mDisabledKeyList[inner_loop].compare(
937                                             (*pCurLayoutKeyCoordination)[loop].custom_id) == 0) {
938                                                 (*pCurButtonContext)[loop].state = BUTTON_STATE_DISABLED;
939                                         }
940                                     }
941                                 }
942                             }
943                         }
944                     }
945                 }
946             }
947
948             /* Resize window */
949             if (windows->is_base_window(window)) {
950                 windows->resize_window(window, mCurBaseLayout.width, mCurBaseLayout.height);
951                 windows->resize_window(windows->get_dim_window(), mCurBaseLayout.width, mCurBaseLayout.height);
952             }
953
954             /* EFL testing */
955             windows->update_window(window);
956         }
957     }
958
959     return TRUE;
960 }
961
962 /**
963  * Returns the current key_coordination data
964  */
965 SclLayoutKeyCoordinate*
966 CSCLResourceCache::get_cur_layout_key_coordinate(sclwindow window, sclbyte key_index)
967 {
968     SCL_DEBUG();
969     scl_assert_return_null(key_index < MAX_KEY);
970
971     CSCLWindows *windows = CSCLWindows::get_instance();
972     if (windows->get_base_window() == window) {
973         if (key_index < MAX_KEY) {
974             return &mCurBaseLayoutKeyCoordination[key_index];
975         }
976     } else {
977         sclbyte popupindex = windows->find_popup_window_index(window);
978         scl_assert_return_false(popupindex < MAX_POPUP_WINDOW);
979         if (key_index < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
980             return &mCurPopupLayoutKeyCoordination[popupindex][key_index];
981         }
982     }
983
984     return NULL;
985 }
986
987 /**
988  * FIXME : This must be very SLOW - let's refine this function ASAP
989  * Returns the current label_properties data
990  */
991 const SclLabelProperties*
992 CSCLResourceCache::get_label_properties(sclchar *label_type, sclbyte index) const
993 {
994     SCL_DEBUG();
995
996     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
997     PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
998     assert(sclres_label_properties != NULL);
999     if (sclres_label_properties && label_type) {
1000         /* FIXME */
1001         //if (scl_check_arrindex(labeltype, MAX_LABEL_PROPERTIES) && scl_check_arrindex(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
1002         for(sclshort labeltype = 0;
1003             labeltype < MAX_SCL_LABEL_PROPERTIES && labeltype < sclres_manager->get_labelproperty_size();
1004             labeltype++) {
1005                 if (sclres_label_properties[labeltype][0].label_type) {
1006                     if (strcmp(sclres_label_properties[labeltype][0].label_type, label_type) == 0) {
1007                     if (scl_check_arrindex_unsigned(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
1008                         return &sclres_label_properties[labeltype][index];
1009                     }
1010                 }
1011             }
1012         }
1013     }
1014
1015     CSCLUtils *utils = CSCLUtils::get_instance();
1016     if (utils) {
1017         utils->log("WARNINNG!!!!!!!!!!!!!!!!!! LABEL NAME %s COULD NOT BE FOUND!!!!!\n", label_type);
1018     }
1019
1020     return NULL;
1021 }
1022
1023 /**
1024  * Returns the current button_context data
1025  */
1026 SclButtonContext*
1027 CSCLResourceCache::get_cur_button_context(sclwindow window, sclbyte key_index)
1028 {
1029     SCL_DEBUG();
1030     scl_assert_return_null(key_index < MAX_KEY);
1031
1032     CSCLWindows *windows = CSCLWindows::get_instance();
1033     if (windows->get_base_window() == window) {
1034         if (key_index < MAX_KEY) {
1035             return &mCurBaseButtonContext[key_index];
1036         }
1037     } else {
1038         sclbyte popupindex = windows->find_popup_window_index(window);
1039         scl_assert_return_null(popupindex < MAX_POPUP_WINDOW);
1040         if (key_index < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
1041             return &mCurPopupButtonContext[popupindex][key_index];
1042         }
1043     }
1044
1045     return NULL;
1046 }
1047
1048 /* Generate and fill autopopup layout data */
1049 void CSCLResourceCache::generate_autopopup_layout( const SclLayoutKeyCoordinate *coordination,
1050         SclLayout *pCurLayout, SclLayoutKeyCoordinate (*pCurLayoutKeyCoordination)[MAX_KEY],
1051         SclButtonContext (*pCurButtonContext)[MAX_KEY] )
1052 {
1053     SCL_DEBUG();
1054
1055     CSCLUtils *utils = CSCLUtils::get_instance();
1056     CSCLContext *context = CSCLContext::get_instance();
1057
1058     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1059     PSclAutoPopupConfigure autopopup_configure = NULL;
1060     if (sclres_manager) {
1061         autopopup_configure = sclres_manager->get_autopopup_configure();
1062     }
1063
1064     int loop;
1065     if (coordination && autopopup_configure) {
1066         sclbyte num_keys, num_columns, num_rows;
1067         sclint x, y, width, height;
1068         SCLShiftState shiftidx = context->get_shift_state();
1069         if (shiftidx < 0 || shiftidx >= SCL_SHIFT_STATE_MAX) shiftidx = SCL_SHIFT_STATE_OFF;
1070         if (utils->get_autopopup_window_variables(coordination->autopopup_key_labels[shiftidx], &num_keys, &num_columns, &num_rows, &width, &height)) {
1071             int row = 0, column = 0;
1072
1073             pCurLayout->use_magnifier_window = FALSE;
1074             pCurLayout->valid = TRUE;
1075             pCurLayout->style = LAYOUT_STYLE_POPUP_GRAB;
1076             pCurLayout->name = NULL;
1077             pCurLayout->width = width;
1078             pCurLayout->height = height;
1079             memset(pCurLayout->image_path, 0x00, sizeof(pCurLayout->image_path));
1080             pCurLayout->use_sw_background = TRUE;
1081             if (autopopup_configure->bg_image_path != NULL) {
1082                 pCurLayout->image_path[0] = autopopup_configure->bg_image_path;
1083                 pCurLayout->use_sw_background = FALSE;
1084             }
1085             pCurLayout->use_sw_button = TRUE;
1086             /* If button image path is set, use images instead of SW buttons */
1087             if (autopopup_configure->button_image_path[0] != NULL) {
1088                 pCurLayout->use_sw_button = FALSE;
1089             }
1090             pCurLayout->use_magnifier_window = FALSE;
1091             pCurLayout->extract_background = FALSE;
1092             pCurLayout->bg_color = autopopup_configure->bg_color;
1093             pCurLayout->bg_line_width = autopopup_configure->bg_line_width;
1094             pCurLayout->bg_line_color = autopopup_configure->bg_line_color;
1095             pCurLayout->add_grab_left = autopopup_configure->add_grab_left;
1096             pCurLayout->add_grab_right = autopopup_configure->add_grab_right;
1097             pCurLayout->add_grab_top = autopopup_configure->add_grab_top;
1098             pCurLayout->add_grab_bottom = autopopup_configure->add_grab_bottom;
1099             pCurLayout->mouse_manipulate_x = 0;
1100             pCurLayout->mouse_manipulate_y = (autopopup_configure->button_height * -1);
1101
1102             memset((*pCurLayoutKeyCoordination), 0x00, sizeof(SclLayoutKeyCoordinate) * MAX_KEY);
1103
1104             memset((*pCurButtonContext), 0x00, sizeof(SclButtonContext) * MAX_KEY);
1105
1106             for (loop = 0;loop < (num_columns * num_rows) && loop < MAX_KEY && loop < MAX_SIZE_OF_AUTOPOPUP_STRING;loop++) {
1107                 column = (loop % num_columns);
1108                 row = loop / num_columns;
1109                 x = autopopup_configure->bg_padding + (autopopup_configure->button_width * column) +
1110                     (autopopup_configure->button_spacing * column);
1111                 y = autopopup_configure->bg_padding + (autopopup_configure->button_height * (num_rows - row - 1)) +
1112                     (autopopup_configure->button_spacing * row);
1113
1114                 (*pCurLayoutKeyCoordination)[loop].valid = TRUE;
1115                 (*pCurLayoutKeyCoordination)[loop].x = x + autopopup_configure->decoration_size;
1116                 (*pCurLayoutKeyCoordination)[loop].y = y + autopopup_configure->decoration_size;
1117                 (*pCurLayoutKeyCoordination)[loop].width = autopopup_configure->button_width;
1118                 (*pCurLayoutKeyCoordination)[loop].height = autopopup_configure->button_height;
1119                 (*pCurLayoutKeyCoordination)[loop].popup_relative_x = 0;
1120                 (*pCurLayoutKeyCoordination)[loop].popup_relative_y = 0;
1121                 (*pCurLayoutKeyCoordination)[loop].extract_offset_x = 0;
1122                 (*pCurLayoutKeyCoordination)[loop].extract_offset_y = 0;
1123                 (*pCurLayoutKeyCoordination)[loop].sub_layout = NULL;
1124
1125                 (*pCurLayoutKeyCoordination)[loop].valid = TRUE;
1126                 if (loop < num_keys) {
1127                     (*pCurLayoutKeyCoordination)[loop].button_type = BUTTON_TYPE_NORMAL;
1128                 } else {
1129                     (*pCurLayoutKeyCoordination)[loop].button_type = BUTTON_TYPE_UIITEM;
1130                 }
1131                 (*pCurLayoutKeyCoordination)[loop].key_type = KEY_TYPE_STRING;
1132                 (*pCurLayoutKeyCoordination)[loop].popup_type = POPUP_TYPE_NONE;
1133                 (*pCurLayoutKeyCoordination)[loop].use_magnifier = FALSE;
1134                 (*pCurLayoutKeyCoordination)[loop].use_long_key_magnifier = TRUE;
1135                 memset((*pCurLayoutKeyCoordination)[loop].popup_input_mode, NOT_USED, sizeof((*pCurLayoutKeyCoordination)[loop].popup_input_mode));
1136
1137                 (*pCurLayoutKeyCoordination)[loop].valid = TRUE;
1138                 (*pCurLayoutKeyCoordination)[loop].label_count = 1;
1139                 (*pCurLayoutKeyCoordination)[loop].label[0][0] = coordination->autopopup_key_labels[0][loop];
1140                 (*pCurLayoutKeyCoordination)[loop].label[1][0] = coordination->autopopup_key_labels[1][loop];
1141                 (*pCurLayoutKeyCoordination)[loop].label[2][0] = coordination->autopopup_key_labels[2][loop];
1142                 //(*pCurLayoutKeyProperties)[loop].labelPropId = SCL_LABEL_PROPERTY_AUTOPOPUP;
1143                 (*pCurLayoutKeyCoordination)[loop].label_type = autopopup_configure->label_type;
1144                 memset((*pCurLayoutKeyCoordination)[loop].image_label_path, 0x00, sizeof((*pCurLayoutKeyCoordination)[loop].image_label_path));
1145                 memset((*pCurLayoutKeyCoordination)[loop].bg_image_path, 0x00, sizeof((*pCurLayoutKeyCoordination)[loop].bg_image_path));
1146                 for (int innerLoop = 0;innerLoop < SCL_BUTTON_STATE_MAX;innerLoop++) {
1147                     (*pCurLayoutKeyCoordination)[loop].bg_image_path[SCL_SHIFT_STATE_OFF][innerLoop] =
1148                         (*pCurLayoutKeyCoordination)[loop].bg_image_path[SCL_SHIFT_STATE_ON][innerLoop] =
1149                         (*pCurLayoutKeyCoordination)[loop].bg_image_path[SCL_SHIFT_STATE_LOCK][innerLoop] =
1150                             autopopup_configure->button_image_path[innerLoop];
1151                 }
1152
1153                 (*pCurLayoutKeyCoordination)[loop].key_value_count = 1;
1154
1155                 if (coordination->autopopup_key_values[0][loop] == NULL) {
1156                     (*pCurLayoutKeyCoordination)[loop].key_value[0][0] = coordination->autopopup_key_labels[0][loop];
1157                 } else {
1158                     (*pCurLayoutKeyCoordination)[loop].key_value[0][0] = coordination->autopopup_key_values[0][loop];
1159                 }
1160                 if (coordination->autopopup_key_values[1][loop] == NULL) {
1161                     (*pCurLayoutKeyCoordination)[loop].key_value[1][0] = coordination->autopopup_key_labels[1][loop];
1162                 } else {
1163                     (*pCurLayoutKeyCoordination)[loop].key_value[1][0] = coordination->autopopup_key_values[1][loop];
1164                 }
1165                 if (coordination->autopopup_key_values[2][loop] == NULL) {
1166                     (*pCurLayoutKeyCoordination)[loop].key_value[2][0] = coordination->autopopup_key_labels[2][loop];
1167                 } else {
1168                     (*pCurLayoutKeyCoordination)[loop].key_value[2][0] = coordination->autopopup_key_values[2][loop];
1169                 }
1170                 (*pCurLayoutKeyCoordination)[loop].key_event[0][0] = coordination->autopopup_key_events[0][loop];
1171                 (*pCurLayoutKeyCoordination)[loop].key_event[1][0] = coordination->autopopup_key_events[1][loop];
1172                 (*pCurLayoutKeyCoordination)[loop].key_event[2][0] = coordination->autopopup_key_events[2][loop];
1173                 (*pCurLayoutKeyCoordination)[loop].long_key_type = KEY_TYPE_NONE;
1174                 (*pCurLayoutKeyCoordination)[loop].long_key_value = NULL;
1175                 (*pCurLayoutKeyCoordination)[loop].long_key_event = 0;
1176
1177                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_labels[0][0] = NULL;
1178                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_labels[1][0] = NULL;
1179                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_labels[2][0] = NULL;
1180                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_events[0][0] = 0;
1181                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_events[1][0] = 0;
1182                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_events[2][0] = 0;
1183                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_values[0][0] = NULL;
1184                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_values[1][0] = NULL;
1185                 (*pCurLayoutKeyCoordination)[loop].autopopup_key_values[2][0] = NULL;
1186                 (*pCurLayoutKeyCoordination)[loop].extra_option = 0;
1187
1188                 /* If the keyvalue is in between the SCL_ISCHAR range, consider this to be a KEY_TYPE_CHAR */
1189                 if ((*pCurLayoutKeyCoordination)[loop].key_value[0][0]) {
1190                     if (strlen((*pCurLayoutKeyCoordination)[loop].key_value[0][0]) == 1) {
1191                         if (SCL_ISCHAR(*(*pCurLayoutKeyCoordination)[loop].key_value[0][0])) {
1192                             (*pCurLayoutKeyCoordination)[loop].key_type = KEY_TYPE_CHAR;
1193                         }
1194                     }
1195                 }
1196
1197                 (*pCurButtonContext)[loop].used = TRUE;
1198             }
1199             if (autopopup_configure->decoration_size > 0) {
1200                 sclbyte decoidx;
1201                 for (decoidx = 0;decoidx < MAX_WND_DECORATOR;decoidx++) {
1202                     if (loop + decoidx < MAX_KEY) {
1203                         (*pCurLayoutKeyCoordination)[loop + decoidx].valid = TRUE;
1204                         switch (decoidx) {
1205                             case WND_DECORATOR_TOP_LEFT:
1206                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1207                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
1208                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1209                                     autopopup_configure->decoration_size;
1210                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1211                                     autopopup_configure->decoration_size;
1212                             break;
1213                             case WND_DECORATOR_TOP_CENTER:
1214                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1215                                     autopopup_configure->decoration_size;
1216                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
1217                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1218                                     width - (2 * autopopup_configure->decoration_size);
1219                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1220                                     autopopup_configure->decoration_size;
1221                                 break;
1222                             case WND_DECORATOR_TOP_RIGHT:
1223                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1224                                     width - autopopup_configure->decoration_size;
1225                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
1226                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1227                                     autopopup_configure->decoration_size;
1228                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1229                                     autopopup_configure->decoration_size;
1230                                 break;
1231                             case WND_DECORATOR_MIDDLE_LEFT:
1232                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1233                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1234                                     autopopup_configure->decoration_size;
1235                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1236                                     autopopup_configure->decoration_size;
1237                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1238                                     height - (2 * autopopup_configure->decoration_size);
1239                                 break;
1240                             case WND_DECORATOR_MIDDLE_RIGHT:
1241                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1242                                     width - autopopup_configure->decoration_size;
1243                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1244                                     autopopup_configure->decoration_size;
1245                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1246                                     autopopup_configure->decoration_size;
1247                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1248                                     height - (2 * autopopup_configure->decoration_size);
1249                                 break;
1250                             case WND_DECORATOR_BOTTOM_LEFT:
1251                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1252                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1253                                     height - autopopup_configure->decoration_size;
1254                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1255                                     autopopup_configure->decoration_size;
1256                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1257                                     autopopup_configure->decoration_size;
1258                                 break;
1259                             case WND_DECORATOR_BOTTOM_CENTER:
1260                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1261                                     autopopup_configure->decoration_size;
1262                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1263                                     height - autopopup_configure->decoration_size;
1264                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1265                                     width - (2 * autopopup_configure->decoration_size);
1266                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1267                                     autopopup_configure->decoration_size;
1268                                 break;
1269                             case WND_DECORATOR_BOTTOM_RIGHT:
1270                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 
1271                                     width - autopopup_configure->decoration_size;
1272                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 
1273                                     height - autopopup_configure->decoration_size;
1274                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width = 
1275                                     autopopup_configure->decoration_size;
1276                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height = 
1277                                     autopopup_configure->decoration_size;
1278                                 break;
1279                         }
1280                         
1281                         (*pCurButtonContext)[loop + decoidx].used = TRUE;
1282                         (*pCurLayoutKeyCoordination)[loop + decoidx].valid = TRUE;
1283                         (*pCurLayoutKeyCoordination)[loop + decoidx].button_type = BUTTON_TYPE_UIITEM;
1284                         (*pCurLayoutKeyCoordination)[loop + decoidx].valid = TRUE;
1285                         (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[0][0] =
1286                             (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[0][1] =
1287                             (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[1][0] =
1288                             (*pCurLayoutKeyCoordination)[loop + decoidx].bg_image_path[1][1] =
1289                             autopopup_configure->decoration_image_path[decoidx];
1290                     }
1291                 }
1292             }
1293         }
1294     }
1295 }
1296
1297 /**
1298 * Sets the current theme name
1299 */
1300 sclboolean
1301 CSCLResourceCache::set_cur_themename( const sclchar *themename )
1302 {
1303     /*SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1304     const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
1305     assert(sclres_label_properties != NULL);*/
1306     if (themename) {
1307         strncpy(mCurThemename, themename, _POSIX_PATH_MAX - 1);
1308         mCurThemename[_POSIX_PATH_MAX - 1] = '\0';
1309
1310         /*CSCLUtils *utils = CSCLUtils::get_instance();
1311         utils->get_composed_path(fontprop_path, FONT_PROPERTIES_FILE);
1312         FILE *fp = fopen(fontprop_path, "r");
1313         if (fp) {
1314             sclint index = 0;
1315             sclint r,g,b,a;
1316             if (!feof(fp)) {
1317                 for(sclint shiftstate = 0;shiftstate < SCL_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1318                     char comment[_POSIX_PATH_MAX];
1319                     for(sclint buttonstate = 0;buttonstate < SCL_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1320                         fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1321                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].r = r;
1322                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].g = g;
1323                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].b = b;
1324                         scl_autopopup_configure.labelProp.font_color[shiftstate][buttonstate].a = a;
1325                     }
1326                     fscanf(fp, "%s", comment);
1327                 }
1328             }
1329             if (!feof(fp)) {
1330                 sclint subindex = 0;
1331                 while (subindex < MAX_SIZE_OF_LABEL_FOR_ONE && !feof(fp) && scl_magnifier_configure.labelProp[subindex].valid) {
1332                     for(sclint shiftstate = 0;shiftstate < SCL_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1333                         char comment[_POSIX_PATH_MAX];
1334                         for(sclint buttonstate = 0;buttonstate < SCL_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1335                             fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1336                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].r = r;
1337                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].g = g;
1338                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].b = b;
1339                             scl_magnifier_configure.labelProp[subindex].font_color[shiftstate][buttonstate].a = a;
1340                         }
1341                         fscanf(fp, "%s", comment);
1342                     }
1343                     subindex++;
1344                 }
1345             }
1346             index = 0;
1347             while (index < MAX_LABEL_PROPERTIES && !feof(fp)) {
1348                 sclint subindex = 0;
1349                 while (subindex < MAX_SIZE_OF_LABEL_FOR_ONE && !feof(fp) && sclres_label_properties[index][subindex].valid) {
1350                     for(sclint shiftstate = 0;shiftstate < SCL_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1351                         char comment[_POSIX_PATH_MAX];
1352                         for(sclint buttonstate = 0;buttonstate < SCL_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1353                             fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1354                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].r = r;
1355                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].g = g;
1356                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].b = b;
1357                             sclres_label_properties[index][subindex].font_color[shiftstate][buttonstate].a = a;
1358                         }
1359                         fscanf(fp, "%s", comment);
1360                     }
1361                     subindex++;
1362                 }
1363                 index++;
1364             }
1365             fclose(fp);
1366         }*/
1367     }
1368
1369     return TRUE;
1370 }
1371
1372 const sclchar*
1373 CSCLResourceCache::get_cur_themename()
1374 {
1375     return mCurThemename;
1376 }
1377
1378 /**
1379  * Returns a template private key properties using key properties of the given context
1380  */
1381 void
1382 CSCLResourceCache::clone_keyproperties(SclPrivateKeyProperties* priv, sclbyte input_mode_index, sclbyte layout_index, sclbyte key_index)
1383 {
1384     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1385     const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
1386
1387     SCL_DEBUG();
1388     if (priv && sclres_layout_key_coordinate_pointer_frame) {
1389         CSCLResourceCache *cache = CSCLResourceCache::get_instance();
1390         clear_privatekeyproperties(priv);
1391
1392         /* gets the value of the previous key properties */
1393         sclint loop;
1394         SclLayoutKeyCoordinate keyCoordination = { 0 };
1395         if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT) &&
1396             scl_check_arrindex_unsigned(key_index, MAX_KEY)) {
1397             SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][key_index];
1398             if (p) {
1399                 memcpy(&keyCoordination, p, sizeof(SclLayoutKeyCoordinate));
1400             }
1401         }
1402
1403         scl_assert_return(keyCoordination.valid == TRUE);
1404
1405         /* Sets the default properties base on the properties values of the given context */
1406         cache->copy_to_privatekeyproperties(&keyCoordination, priv);
1407     }
1408 }
1409
1410 /**
1411  * Sets a private key to the current context
1412  *
1413  * @Usage
1414  *       SclPrivateKeyProperties privProperties;
1415  *       gCore->clone_keyproperties(&privProperties, INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
1416  *       // change
1417  *       gCore->set_private_key(&privProperties, TRUE);
1418  */
1419 sclint
1420 CSCLResourceCache::set_private_key(SclPrivateKeyProperties* properties, sclboolean fRedraw, sclboolean fPendingUpdate)
1421 {
1422     SCL_DEBUG();
1423     CSCLContext *context = CSCLContext::get_instance();
1424     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
1425     sclint privateId = NOT_USED;
1426     sclboolean isNeedUpdate = FALSE;
1427     if (cache && context && properties) {
1428         privateId = cache->add_private_key(properties, &isNeedUpdate);
1429         if (fRedraw && isNeedUpdate && !fPendingUpdate && privateId != NOT_USED) {
1430             CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
1431             CSCLWindows *windows = CSCLWindows::get_instance();
1432             if (builder && windows) {
1433                 /* Fix me (we should consider popupwindow later)*/
1434                 sclwindow window = windows->get_base_window();
1435                 /* Let's draw this private key only if the key's sublayout ID is active */
1436                 SclLayoutKeyCoordinate *coordination = get_cur_layout_key_coordinate(window, properties->key_index);
1437                 if (coordination) {
1438                     sclboolean redraw = TRUE;
1439                     if (coordination->sub_layout && context->get_cur_sublayout()) {
1440                         if (strncmp(coordination->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
1441                             redraw = FALSE;
1442                         }
1443                     }
1444                     if (redraw) {
1445                         windows->update_window(window,
1446                             coordination->x, coordination->y, coordination->width, coordination->height);
1447                         //builder->draw_button(window, NULL, properties->key_index, mCurBaseButtonContext[properties->key_index].state);
1448                     }
1449                 }
1450                 /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
1451                 //windows->update_window(windows->get_base_window());
1452             }
1453         }
1454     }
1455     return privateId;
1456 }
1457
1458 /**
1459  * Sets a private key to the current context
1460  * The other properties except given parameters will keep to the orginal value.
1461  * @Usage
1462  * gCore->set_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0, "private", 999, TRUE);
1463  *
1464  * @param fRedraw If true, it will redraw the current key
1465  */
1466 sclint
1467 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)
1468 {
1469     SCL_DEBUG();
1470
1471     SclPrivateKeyProperties privProperties;
1472     clear_privatekeyproperties(&privProperties);
1473
1474     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1475     PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
1476     assert(sclres_layout_key_coordinate_pointer_frame != NULL);
1477
1478     sclint loop;
1479
1480     privProperties.valid = TRUE;
1481     privProperties.custom_id = custom_id;
1482
1483     privProperties.key_event[SCL_SHIFT_STATE_LOCK][0] = privProperties.key_event[SCL_SHIFT_STATE_ON][0] =
1484         privProperties.key_event[SCL_SHIFT_STATE_OFF][0] = key_event;
1485     if (label) {
1486         privProperties.label[SCL_SHIFT_STATE_LOCK][0] = label;
1487         privProperties.label[SCL_SHIFT_STATE_ON][0] = label;
1488         privProperties.label[SCL_SHIFT_STATE_OFF][0] = label;
1489         privProperties.label_count = 1;
1490     }
1491     if (key_value) {
1492         privProperties.key_value[SCL_SHIFT_STATE_LOCK][0] = privProperties.key_value[SCL_SHIFT_STATE_ON][0] =
1493             privProperties.key_value[SCL_SHIFT_STATE_OFF][0] = key_value;
1494     }
1495     if (imagelabel) {
1496         for (loop =0;loop < SCL_BUTTON_STATE_MAX;loop++) {
1497             if (imagelabel[loop])
1498                 privProperties.image_label_path[SCL_SHIFT_STATE_LOCK][loop] =
1499                     privProperties.image_label_path[SCL_SHIFT_STATE_ON][loop] =
1500                     privProperties.image_label_path[SCL_SHIFT_STATE_OFF][loop] = imagelabel[loop];
1501             }
1502         }
1503     if (imagebg) {
1504         for (loop =0;loop < SCL_BUTTON_STATE_MAX;loop++) {
1505             if (imagebg[loop]) {
1506                 privProperties.bg_image_path[SCL_SHIFT_STATE_LOCK][loop] =
1507                     privProperties.bg_image_path[SCL_SHIFT_STATE_ON][loop] =
1508                     privProperties.bg_image_path[SCL_SHIFT_STATE_OFF][loop] = imagebg[loop];
1509             }
1510         }
1511     }
1512     return set_private_key(&privProperties, fRedraw, fPendingUpdate);
1513 }
1514
1515 /**
1516 * Unset private key for specific key
1517 * @Usage
1518 * gCore->unset_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
1519 */
1520 void
1521 CSCLResourceCache::unset_private_key(sclshort input_mode_index, sclbyte layout_index, sclbyte key_index)
1522 {
1523     sclint loop = 0;
1524     for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
1525         if ((mPrivateKeyProperties[loop].input_mode_index == input_mode_index) &&
1526             mPrivateKeyProperties[loop].layout_index == layout_index &&
1527             mPrivateKeyProperties[loop].key_index == key_index) {
1528                 remove_private_key(loop);
1529         }
1530     }
1531 }
1532
1533 /**
1534 * Unset private by custom_id, effective when removing all private keys with same custom_id
1535 * @Usage
1536 * gCore->unset_private_key(3);
1537 */
1538 void
1539 CSCLResourceCache::unset_private_key(const sclchar* custom_id)
1540 {
1541     int loop;
1542     if (custom_id) {
1543         for(loop = 0;loop < MAX_PRIVATE_KEY;loop++) {
1544             if (mPrivateKeyProperties[loop].valid &&
1545                 mPrivateKeyProperties[loop].custom_id.compare(custom_id) == 0) {
1546                 remove_private_key(loop);
1547             }
1548         }
1549     }
1550 }
1551
1552 /**
1553 * Find appropriate index of the key specified by custom_id
1554 */
1555 sclbyte
1556 CSCLResourceCache::find_keyidx_by_customid(const sclchar* custom_id)
1557 {
1558     sclbyte ret = NOT_USED;
1559     sclint loop;
1560
1561     CSCLContext *context = CSCLContext::get_instance();
1562     SclResParserManager *sclres_manager = SclResParserManager::get_instance();
1563     PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
1564
1565     assert(sclres_layout_key_coordinate_pointer_frame != NULL);
1566
1567     sclshort input_mode_index = NOT_USED;
1568     sclbyte layout_index = NOT_USED;
1569     if (context) {
1570         input_mode_index = context->get_input_mode();
1571         layout_index = context->get_base_layout();
1572     }
1573
1574     if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT) && custom_id) {
1575         for (loop = 0;loop < MAX_KEY;loop++) {
1576             SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][loop];
1577             if (!p || !(p->valid)) break;
1578             if (p->custom_id) {
1579                 if (strcmp(p->custom_id, custom_id) == 0) {
1580                     ret = loop;
1581                     break;
1582                 }
1583             }
1584         }
1585     }
1586
1587     return ret;
1588 }
1589
1590 /**
1591 * Enable/disable button for handling mouse events
1592 */
1593 void CSCLResourceCache::enable_button(const sclchar *custom_id, sclboolean enabled)
1594 {
1595     SCL_DEBUG();
1596
1597     sclint loop;
1598     if (custom_id) {
1599         sclbyte key_index = find_keyidx_by_customid(custom_id);
1600         if (scl_check_arrindex_unsigned(key_index, MAX_KEY)) {
1601             if (enabled) {
1602                 mCurBaseButtonContext[key_index].state = BUTTON_STATE_NORMAL;
1603             } else {
1604                 mCurBaseButtonContext[key_index].state = BUTTON_STATE_DISABLED;
1605             }
1606
1607             CSCLWindows *windows = CSCLWindows::get_instance();
1608             /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
1609             windows->update_window(windows->get_base_window());
1610         }
1611
1612         sclboolean found = FALSE;
1613         sclint empty_index = -1;
1614
1615         for (loop = 0;loop < MAX_DISABLED_KEY;loop++) {
1616             if (!(mDisabledKeyList[loop].empty())) {
1617                 if (mDisabledKeyList[loop].compare(custom_id) == 0) {
1618                     if (enabled) {
1619                         /* Erase this item from the disabled key list */
1620                         mDisabledKeyList[loop].clear();
1621                     }
1622                     found = TRUE;
1623                 }
1624             } else {
1625                 empty_index = loop;
1626             }
1627         }
1628
1629         if (!found) {
1630             if (!enabled) {
1631                 if (scl_check_arrindex(empty_index, MAX_DISABLED_KEY)) {
1632                     /* Add to the disabled key */
1633                     mDisabledKeyList[empty_index] = custom_id;
1634                 }
1635             }
1636         }
1637     }
1638 }
1639
1640 void
1641 CSCLResourceCache::set_string_substitution(const sclchar *original, const sclchar *substitute)
1642 {
1643     if (original && substitute) {
1644         mStringSubstitutor[std::string(original)] = std::string(substitute);
1645     }
1646 }
1647
1648 void
1649 CSCLResourceCache::unset_string_substitution(const sclchar *original)
1650 {
1651     if (original) {
1652         mStringSubstitutor.erase(std::string(original));
1653     }
1654 }
1655
1656 const sclchar*
1657 CSCLResourceCache::find_substituted_string(const sclchar *original)
1658 {
1659     const sclchar* ret = original;
1660
1661     if (original) {
1662         std::map<std::string, std::string>::iterator iter = mStringSubstitutor.find(std::string(original));
1663         if (iter != mStringSubstitutor.end()) {
1664             ret = iter->second.c_str();
1665         }
1666     }
1667
1668     return ret;
1669 }