Keyboard settings Blank screen issue fixed
[framework/uifw/ise-default.git] / mcf / mcfresourcecache.cpp
1 /*
2  * Copyright 2012  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://www.tizenopensource.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
21 #include "mcfresourcecache.h"
22 #include "mcfdebug.h"
23 #include "mcfcontext.h"
24
25 #include "mcfresourcekeys.h"
26 #include "mcfuibuilder.h"
27
28 using namespace mcf;
29
30 CMCFResourceCache* CMCFResourceCache::sInstance = NULL; /* For singleton */
31
32 CMCFResourceCache::CMCFResourceCache()
33 {
34     MCF_DEBUG();
35     resize_resource_elements_by_resolution();
36     clear_private_keys();
37     memset(mCurThemename, 0x00, sizeof(mCurThemename));
38 }
39
40 CMCFResourceCache::~CMCFResourceCache()
41 {
42     MCF_DEBUG();
43 }
44
45 CMCFResourceCache*
46 CMCFResourceCache::get_instance()
47 {
48     if (!sInstance) {
49         sInstance = new CMCFResourceCache();
50     }
51     return (CMCFResourceCache*)sInstance;
52 }
53
54
55 #ifdef ENABLE_RESOURCE_DATA_FILE
56
57 mcfchar*
58 CMCFResourceCache::copy_string(const mcfchar *str)
59 {
60     mcfchar *new_str;
61     mcfint length;
62
63     if (str) {
64         std::string s(str);
65         std::set<std::string>::iterator it =  mLayoutKeyPropertiesStrings.find(s);
66         if (it != mLayoutKeyPropertiesStrings.end()) {
67             s =* it;
68             new_str = (mcfchar *)s.c_str();
69         } else {
70             length = strlen(str) + 1;
71             new_str = (mcfchar*)malloc(length);
72             if (new_str) {
73                 memcpy(new_str, str, length);
74                 new_str[length - 1] = '\0';
75                 s.assign(new_str);
76                 mLayoutKeyPropertiesStrings.insert(s);
77             }
78         }
79     } else {
80         new_str = NULL;
81     }
82
83     return new_str;
84 }
85
86
87 mcfint
88 CMCFResourceCache::copy_from_stored(McfLayoutKeyProperties *prop, StoredMcfLayoutKeyProperties *stored)
89 {
90         int i,j;
91
92         prop->fValid = stored->fValid;
93         prop->labelCnt = stored->labelCnt;
94         prop->labelPropId = stored->labelPropId;
95         prop->keyValueCnt = stored->keyValueCnt;
96         prop->longKeyEvent = stored->longKeyEvent;
97         prop->useRepeatKey = stored->useRepeatKey;
98         prop->dontClosePopup = stored->dontClosePopup;
99         prop->extraOption = stored->extraOption;
100         prop->multitouchType = stored->multitouchType;
101         prop->modifierDecorationId = stored->modifierDecorationId;
102
103         memcpy(prop->keyEvent, stored->keyEvent, sizeof(stored->keyEvent));
104
105         prop->longKeyValue = copy_string((mcfchar *)stored->longKeyValue);
106
107         for (i=0; i < MCF_SHIFT_STATE_MAX; i++) {
108                 for (j=0; j < MAX_SIZE_OF_LABEL_FOR_ONE; j++) {
109                         if (stored->label[i][j][0]) {
110                                 prop->label[i][j] = copy_string((mcfchar *)stored->label[i][j]);
111                         } else {
112                                 prop->label[i][j] = NULL;
113                         }
114                 }
115
116                 for (j=0; j < MCF_BUTTON_STATE_MAX; j++) {
117                         if (stored->labelImgPath[i][j][0]) {
118                                 prop->labelImgPath[i][j] = copy_string((mcfchar *)stored->labelImgPath[i][j]);
119                         } else {
120                                 prop->labelImgPath[i][j] = NULL;
121                         }
122
123                         if (stored->bgImgPath[i][j][0]) {
124                                 prop->bgImgPath[i][j] = copy_string((mcfchar *)stored->bgImgPath[i][j]);
125                         } else {
126                                 prop->bgImgPath[i][j] = NULL;
127                         }
128                 }
129
130                 for (j=0; j < MAX_SIZE_OF_MULTITAP_CHAR; j++) {
131                         if (stored->keyValue[i][j][0]) {
132                                 prop->keyValue[i][j] = copy_string((mcfchar *)stored->keyValue[i][j]);
133                         } else {
134                                 prop->keyValue[i][j] = NULL;
135                         }
136                 }
137
138                 for (j=0; j < MAX_SIZE_OF_AUTOPOPUP_STRING; j++) {
139                         if (stored->autopopupKeys[i][j][0]) {
140                                 prop->autopopupKeys[i][j] = copy_string((mcfchar *)stored->autopopupKeys[i][j]);
141                         } else {
142                                 prop->autopopupKeys[i][j] = NULL;
143                         }
144                 }
145         }
146
147         return 0;
148 }
149
150
151
152 mcfboolean
153 CMCFResourceCache::load_layoutkey_properties(mcfint keyset, McfLayoutKeyProperties (*pLayoutKeyProperties)[MAX_KEY])
154 {
155     FILE *fp;
156     int i;
157
158     StoredMcfLayoutKeyPropertiesHeader header;
159     StoredMcfLayoutKeyProperties stored;
160
161     fp = fopen(KEY_PROPERTIES_FILE, "r");
162     if (!fp) {
163         return FALSE;
164     }
165
166     fread(&header, sizeof(StoredMcfLayoutKeyPropertiesHeader), 1, fp);
167     if (!header.addrKey[keyset][0]) {
168             return FALSE;
169     }
170
171     fseek(fp, header.addrKey[keyset][0], SEEK_SET);
172     memset((*pLayoutKeyProperties), 0x00, sizeof(McfLayoutKeyProperties)*MAX_KEY);
173     for (i=0; i < MAX_KEY; i++) {
174             if (header.addrKey[keyset][i]) {
175                     fseek(fp, header.addrKey[keyset][i], SEEK_SET);
176                     fread(&stored, sizeof(StoredMcfLayoutKeyProperties), 1, fp);
177                     copy_from_stored(&(*pLayoutKeyProperties)[i], &stored);
178             } else {
179                     break;
180             }
181     }
182
183     fclose(fp);
184
185     return TRUE;
186 }
187
188 mcfboolean
189 CMCFResourceCache::load_layoutkey_properties(mcfint keyset, mcfint keyidx, McfLayoutKeyProperties *pLayoutKeyProperties)
190 {
191     FILE *fp;
192     int i;
193
194     StoredMcfLayoutKeyPropertiesHeader header;
195     StoredMcfLayoutKeyProperties stored;
196
197     fp = fopen(KEY_PROPERTIES_FILE, "r");
198     if (!fp) {
199         return FALSE;
200     }
201
202     fread(&header, sizeof(StoredMcfLayoutKeyPropertiesHeader), 1, fp);
203     if (!header.addrKey[keyset][keyidx]) {
204             return FALSE;
205     }
206
207     memset(pLayoutKeyProperties, 0x00, sizeof(McfLayoutKeyProperties));
208
209     fseek(fp, header.addrKey[keyset][keyidx], SEEK_SET);
210     fread(&stored, sizeof(StoredMcfLayoutKeyProperties), 1, fp);
211     copy_from_stored(pLayoutKeyProperties, &stored);
212
213     fclose(fp);
214
215     return TRUE;
216
217 }
218
219
220 #endif
221
222
223 /**
224  * Returns the current layout data
225  */
226 const McfLayout*
227 CMCFResourceCache::get_cur_layout(mcfwindow window) const
228 {
229     MCF_DEBUG();
230
231     const McfLayout *ret = NULL;
232     CMCFWindows *windows = CMCFWindows::get_instance();
233
234     if(windows) {
235         if (windows->get_base_window() == window) {
236             ret = &mCurBaseLayout;
237         } else {
238             mcfbyte popupindex = windows->find_popup_window_index(window);
239             mcf_assert_return_false(popupindex < MAX_POPUP_WINDOW);
240             if (popupindex < MAX_POPUP_WINDOW) {
241                 ret = &mCurPopupLayout[popupindex];
242             }
243         }
244     }
245     return ret;
246 }
247
248 /**
249  * Translates the current x,y,width,height by the current screen resolution
250  * This func should be called when the class init
251  */
252 mcfboolean
253 CMCFResourceCache::resize_resource_elements_by_resolution()
254 {
255     mcfint loop, innerLoop;
256     CMCFUtils *utils = CMCFUtils::get_instance();
257
258     mcfboolean invert_display = FALSE;
259     if(MCF_AUTO_DETECT_PORTRAIT_LANDSCAPE) {
260         mcfint x, y;
261         utils->get_screen_resolution(&x, &y);
262         /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
263         if(x > y) {
264             invert_display = TRUE;
265         }
266     }
267
268     /* First we recaculate all the coordinations of each keys and sizes of layouts structure */
269     for (loop = 0;loop < MAX_LAYOUT;loop++) {
270         mcffloat scale_value_x, scale_value_y;
271         if(invert_display) {
272             if(mcf_layout[loop].displayType == MCFDISPLAY_PORTRAIT) {
273                 scale_value_x = utils->get_scale_rate_y();
274                 scale_value_y = utils->get_scale_rate_x();
275             } else {
276                 scale_value_x = utils->get_scale_rate_x();
277                 scale_value_y = utils->get_scale_rate_y();
278             }
279         } else {
280             if(mcf_layout[loop].displayType == MCFDISPLAY_PORTRAIT) {
281                 scale_value_x = utils->get_scale_rate_x();
282                 scale_value_y = utils->get_scale_rate_y();
283             } else {
284                 scale_value_x = utils->get_scale_rate_y();
285                 scale_value_y = utils->get_scale_rate_x();
286             }
287         }
288         mcf_layout[loop].width *= scale_value_x;
289         mcf_layout[loop].height *= scale_value_y;
290         for (innerLoop = 0;innerLoop < MAX_KEY;innerLoop++) {
291             if (mcf_layout_key_coordination[loop][innerLoop].fValid == USED) {
292                 mcf_layout_key_coordination[loop][innerLoop].x *= scale_value_x;
293                 mcf_layout_key_coordination[loop][innerLoop].y *= scale_value_y;
294                 mcf_layout_key_coordination[loop][innerLoop].width *= scale_value_x;
295                 mcf_layout_key_coordination[loop][innerLoop].height *= scale_value_y;
296                 mcf_layout_key_coordination[loop][innerLoop].addHitLeft *= scale_value_x;
297                 mcf_layout_key_coordination[loop][innerLoop].addHitRight *= scale_value_x;
298                 mcf_layout_key_coordination[loop][innerLoop].addHitTop *= scale_value_y;
299                 mcf_layout_key_coordination[loop][innerLoop].addHitBottom *= scale_value_y;
300                 mcf_layout_key_coordination[loop][innerLoop].popXOffset *= scale_value_x;
301                 mcf_layout_key_coordination[loop][innerLoop].popYOffset *= scale_value_y;
302                 mcf_layout_key_coordination[loop][innerLoop].popImageX *= scale_value_x;
303                 mcf_layout_key_coordination[loop][innerLoop].popImageY *= scale_value_y;
304             }
305         }
306     }
307
308     /* And resize the font labels, adjusting the size of padding also */
309     for (loop = 0;loop < MAX_LABEL_PROPERTIES;loop++) {
310         for (innerLoop = 0;innerLoop < MAX_SIZE_OF_LABEL_FOR_ONE;innerLoop++) {
311             if (mcf_key_label_properties[loop][innerLoop].fValid) {
312                 mcf_key_label_properties[loop][innerLoop].fontSize *= utils->get_smallest_scale_rate();
313             }
314             mcf_key_label_properties[loop][innerLoop].paddingX *= utils->get_smallest_scale_rate();
315             mcf_key_label_properties[loop][innerLoop].paddingY *= utils->get_smallest_scale_rate();
316             mcf_key_label_properties[loop][innerLoop].shadowDistance *= utils->get_smallest_scale_rate();
317         }
318     }
319
320     /* Predefined font labels */
321     CAND_LABEL_PROP.fontSize *= utils->get_smallest_scale_rate();
322     CAND_LABEL_PROP.paddingX *= utils->get_smallest_scale_rate();
323     CAND_LABEL_PROP.paddingY *= utils->get_smallest_scale_rate();
324
325     ZOOMING_LABEL_PROP.fontSize *= utils->get_smallest_scale_rate();
326     ZOOMING_LABEL_PROP.paddingX *= utils->get_smallest_scale_rate();
327     ZOOMING_LABEL_PROP.paddingY *= utils->get_smallest_scale_rate();
328
329     mcf_autopopup_configure.labelProp.fontSize *= utils->get_smallest_scale_rate();
330     mcf_autopopup_configure.labelProp.paddingX *= utils->get_smallest_scale_rate();
331     mcf_autopopup_configure.labelProp.paddingY *= utils->get_smallest_scale_rate();
332
333     mcf_autopopup_configure.wndDecoSize *= utils->get_smallest_scale_rate();
334     mcf_autopopup_configure.bgPadding *= utils->get_smallest_scale_rate();
335     mcf_autopopup_configure.btnSpacing *= utils->get_smallest_scale_rate();
336     utils->scale_x(&(mcf_autopopup_configure.btnWidth));
337     utils->scale_y(&(mcf_autopopup_configure.btnHeight));
338
339     if(MCF_AUTO_DETECT_PORTRAIT_LANDSCAPE) {
340         mcfint x, y;
341         utils->get_screen_resolution(&x, &y);
342         /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
343         if(x > y) {
344             for (loop = 0;loop < MAX_INPUT_MODE;loop++) {
345                 mcfbyte temp = mcf_input_mode_configure[loop].layoutId[0];
346                 mcf_input_mode_configure[loop].layoutId[0] = mcf_input_mode_configure[loop].layoutId[1];
347                 mcf_input_mode_configure[loop].layoutId[1] = temp;
348             }
349             for (loop = 0;loop < MAX_INPUT_MODE_POPUP;loop++) {
350                 mcfbyte temp = mcf_input_mode_popup_configure[loop].layoutId[0];
351                 mcf_input_mode_popup_configure[loop].layoutId[0] = mcf_input_mode_popup_configure[loop].layoutId[1];
352                 mcf_input_mode_popup_configure[loop].layoutId[1] = temp;
353             }
354             for (loop = 0;loop < MODIFIER_DECORATION_NUM;loop++) {
355                 for(innerLoop = 0;innerLoop < KEY_MODIFIER_MAX;innerLoop++) {
356                     mcfchar *temp;
357                     temp = mcf_modifier_decoration[loop].bgImgPath[0][innerLoop];
358                     mcf_modifier_decoration[loop].bgImgPath[0][innerLoop] = mcf_modifier_decoration[loop].bgImgPath[1][innerLoop];
359                     mcf_modifier_decoration[loop].bgImgPath[1][innerLoop] = temp;
360                 }
361             }
362         }
363     }
364 }
365
366 /**
367  * Changes the current key properties by the current screen resolution
368  * This func should be called when the class init
369  */
370 mcfboolean
371 CMCFResourceCache::change_by_privatekey(const mcfbyte inputModeIdx, const mcfbyte layoutIdx, const mcfbyte keyIdx,
372                                                 McfLayoutKeyProperties* properties, McfLayoutKeyConfigure* configure)
373 {
374     MCF_DEBUG();
375     mcf_assert_return_false(properties);
376     mcf_assert_return_false(configure);
377
378     if(properties && configure) {
379         for (int loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
380             if (mPrivateKeyProperties[loop].fValid == USED) {
381                 if (((inputModeIdx == mPrivateKeyProperties[loop].inputModeIdx ||
382                         mPrivateKeyProperties[loop].inputModeIdx == -1)  &&
383                     layoutIdx == mPrivateKeyProperties[loop].layoutIdx &&
384                     keyIdx == mPrivateKeyProperties[loop].keyIdx) ||
385                     (mPrivateKeyProperties[loop].inputModeIdx == -1 &&
386                     mPrivateKeyProperties[loop].layoutIdx == -1 &&
387                     configure->customID == mPrivateKeyProperties[loop].customID) ) {
388                     /* sets the current properties to private key properties */
389                       copy_from_privatekeyproperties(&mPrivateKeyProperties[loop], properties, configure);
390                       break;
391                 }
392             }
393         }
394     }
395
396     return TRUE;
397 }
398
399 /**
400  * Copys the given private properties data to the given key properties
401  */
402 mcfboolean
403 CMCFResourceCache::copy_from_privatekeyproperties(const McfPrivateKeyProperties* privProperties,
404                                                           McfLayoutKeyProperties* properties, McfLayoutKeyConfigure *configure)
405 {
406     MCF_DEBUG();
407     mcf_assert_return_false(privProperties);
408     mcf_assert_return_false(properties);
409     mcf_assert_return_false(configure);
410
411     if(privProperties && configure && properties) {
412         /* Configure */
413         configure->customID = privProperties->customID;
414         configure->buttonType = privProperties->buttonType;
415         configure->keyType = privProperties->keyType;
416         configure->popupType = privProperties->popupType;
417         configure->fUseMagnifier = privProperties->fUseMagnifier;
418         configure->fEnable = privProperties->fEnable;
419
420         memcpy(configure->popupInputMode, privProperties->popupInputMode, sizeof(configure->popupInputMode));
421
422         /* Properties */
423         properties->labelCnt = privProperties->labelCnt;
424         properties->labelPropId = privProperties->labelPropId;
425         properties->keyValueCnt = privProperties->keyValueCnt;
426         properties->longKeyValue = privProperties->longKeyValue;
427         properties->longKeyEvent = privProperties->longKeyEvent;
428         properties->useRepeatKey = privProperties->useRepeatKey;
429         properties->dontClosePopup = privProperties->dontClosePopup;
430         properties->extraOption = privProperties->extraOption;
431
432         memcpy(properties->label, privProperties->label, sizeof(properties->label));
433         memcpy(properties->labelImgPath, privProperties->labelImgPath, sizeof(properties->labelImgPath));
434         memcpy(properties->bgImgPath, privProperties->bgImgPath, sizeof(properties->bgImgPath));
435         memcpy(properties->keyValue, privProperties->keyValue, sizeof(properties->keyValue));
436         memcpy(properties->keyEvent, privProperties->keyEvent, sizeof(properties->keyEvent));
437         memcpy(properties->autopopupKeys, privProperties->autopopupKeys, sizeof(properties->autopopupKeys));
438     }
439
440     return TRUE;
441 }
442
443 /**
444  * Copys the given properties data to the given private key properties
445  */
446 mcfboolean
447 CMCFResourceCache::copy_to_privatekeyproperties(const McfLayoutKeyProperties* properties,
448                                                         const McfLayoutKeyConfigure *configure, McfPrivateKeyProperties* privProperties)
449 {
450     MCF_DEBUG();
451     mcf_assert_return_false(privProperties);
452     mcf_assert_return_false(properties);
453         mcf_assert_return_false(configure);
454
455     /* sets the current key Properties to private key privProperties */
456
457     if(privProperties && configure && properties) {
458         /* Configure */
459         privProperties->customID = configure->customID;
460         privProperties->buttonType = configure->buttonType;
461         privProperties->keyType = configure->keyType;
462         privProperties->popupType = configure->popupType;
463         privProperties->fUseMagnifier = configure->fUseMagnifier;
464         privProperties->fEnable = configure->fEnable;
465
466         memcpy(privProperties->popupInputMode, configure->popupInputMode, sizeof(privProperties->popupInputMode));
467
468         /* Properties */
469         privProperties->labelCnt = properties->labelCnt;
470         privProperties->labelPropId = properties->labelPropId;
471         privProperties->keyValueCnt = properties->keyValueCnt;
472         privProperties->longKeyValue = properties->longKeyValue;
473         privProperties->longKeyEvent = properties->longKeyEvent;
474         privProperties->useRepeatKey = properties->useRepeatKey;
475         privProperties->dontClosePopup = properties->dontClosePopup;
476         privProperties->extraOption = properties->extraOption;
477
478         memcpy(privProperties->label, properties->label, sizeof(privProperties->label));
479         memcpy(privProperties->labelImgPath, properties->labelImgPath, sizeof(privProperties->labelImgPath));
480         memcpy(privProperties->bgImgPath, properties->bgImgPath, sizeof(privProperties->bgImgPath));
481         memcpy(privProperties->keyValue, properties->keyValue, sizeof(privProperties->keyValue));
482         memcpy(privProperties->keyEvent, properties->keyEvent, sizeof(privProperties->keyEvent));
483         memcpy(privProperties->autopopupKeys, properties->autopopupKeys, sizeof(privProperties->autopopupKeys));
484     }
485
486     return TRUE;
487 }
488
489
490 /**
491  * Adds a new private key
492  * It will update it to the current cache properties context because the application can call it anytime
493  * For adapting it in realtime, you should explictly call the draw_button function.
494  *
495  * @param[out] fNeedInvalid It will return true if the current private can be adapt into the current display.
496  * @return id an array index of the private key
497  */
498 mcfint
499 CMCFResourceCache::add_private_key(McfPrivateKeyProperties* privProperties, mcfboolean *fNeedInvaild)
500 {
501     MCF_DEBUG();
502     mcf_assert_return_false(privProperties);
503     mcfint ret = NOT_USED;
504     *fNeedInvaild = FALSE; /* don't need to update now */
505
506     if(!mcf_check_arrindex(privProperties->keyIdx, MAX_KEY))
507         return -1;
508
509     /* Finds an index to be set */
510     mcfint loop = 0;
511     for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
512         if ((mPrivateKeyProperties[loop].inputModeIdx == privProperties->inputModeIdx) &&
513             (mPrivateKeyProperties[loop].layoutIdx == privProperties->layoutIdx) &&
514             mPrivateKeyProperties[loop].keyIdx == privProperties->keyIdx) {
515             break;
516         } else if ((mPrivateKeyProperties[loop].inputModeIdx == privProperties->inputModeIdx) &&
517                    (mPrivateKeyProperties[loop].layoutIdx == privProperties->layoutIdx) &&
518                    (privProperties->inputModeIdx == -1 && privProperties->layoutIdx == -1) &&
519                    mPrivateKeyProperties[loop].customID == privProperties->customID) {
520             break;
521         } else if (mPrivateKeyProperties[loop].fValid == FALSE) {
522                 break;
523         }
524     }
525
526     if (loop == MAX_PRIVATE_KEY) {
527         printf("Out of buffer!! could not insert new private data into buffer \n");
528         return -1;
529     }
530
531     memcpy(&mPrivateKeyProperties[loop], privProperties, sizeof(McfPrivateKeyProperties));
532     mPrivateKeyProperties[loop].fValid = USED;
533     ret = loop;
534
535     /* Checks whether it's the same with the current context */
536     CMCFContext *context = CMCFContext::get_instance();
537
538     /* For baselayout */
539     mcfbyte layout = context->get_base_layout();
540     mcfbyte inputmode = context->get_input_mode();
541     if ((privProperties->inputModeIdx == inputmode && privProperties->layoutIdx == layout) ||
542                 (privProperties->inputModeIdx == -1 && privProperties->layoutIdx == -1 &&
543                 privProperties->customID == mCurBaseLayoutKeyConfigure[privProperties->keyIdx].customID)) {
544         /* sets the current properties to private key properties */
545         copy_from_privatekeyproperties(privProperties,
546                                        &mCurBaseLayoutKeyProperties[privProperties->keyIdx],
547                                        &mCurBaseLayoutKeyConfigure[privProperties->keyIdx]);
548         *fNeedInvaild = TRUE;
549         return ret;
550     }
551
552     if (ret == NOT_USED) {
553         printf("Failed!. Out of private data buffer\n");
554     }
555     return ret;
556 }
557
558 /**
559  * Removes the private data of the given id from McfPrivateKeyProperties buffer
560  */
561 mcfboolean
562 CMCFResourceCache::remove_private_key(mcfint id)
563 {
564     MCF_DEBUG();
565     mcfint loop;
566     CMCFContext *context = CMCFContext::get_instance();
567
568
569     /* resets the current properties to predefined properties */
570     mcfbyte keyidx = mPrivateKeyProperties[id].keyIdx;
571     clone_keyproperties(&(mPrivateKeyProperties[id]),
572                         mPrivateKeyProperties[id].inputModeIdx,
573                         mPrivateKeyProperties[id].layoutIdx,
574                         keyidx);
575     copy_from_privatekeyproperties(&(mPrivateKeyProperties[id]),
576                                    &mCurBaseLayoutKeyProperties[keyidx],
577                                    &mCurBaseLayoutKeyConfigure[keyidx]);
578
579     /* Shift all the privatekey properties to the left by 1, starting from the item next to the id th element */
580     for (loop = id;loop < MAX_PRIVATE_KEY - 1; loop++) {
581         memcpy(&mPrivateKeyProperties[loop], &mPrivateKeyProperties[loop + 1], sizeof(&mPrivateKeyProperties[loop]));
582     }
583     /* Fill 0x00 to the last element */
584     memset(&mPrivateKeyProperties[MAX_PRIVATE_KEY - 1], 0x00, sizeof(McfPrivateKeyProperties));
585     return TRUE;
586 }
587
588 /**
589  * Clears all private keys
590  */
591 mcfboolean
592 CMCFResourceCache::clear_private_keys()
593 {
594     MCF_DEBUG();
595     memset(mPrivateKeyProperties, 0x00, sizeof(McfPrivateKeyProperties) * MAX_PRIVATE_KEY);
596     return TRUE;
597 }
598
599 /**
600  * Re-computes the cache data of the given window. The cache data has been including the current key properties, button context, layout etc,,
601  * Another role of this func is to adjust the current coordination according to the current resolution.
602  * This func will be called when a newly window is created
603  */
604 mcfboolean
605 CMCFResourceCache::recompute_layout(mcfwindow window)
606 {
607     MCF_DEBUG();
608
609     mcfint loop;
610
611     CMCFWindows *windows = CMCFWindows::get_instance();
612     CMCFContext *context = CMCFContext::get_instance();
613     mcfbyte display = context->get_display();
614     mcfbyte inputmode = context->get_input_mode();
615     mcfint sublayoutidx = context->get_cur_sublayout_id();
616
617     McfKeyset keyset = MAX_KEYSET;
618     mcf8 popupindex = NOT_USED;
619
620     McfLayout *pCurLayout = NULL;
621     McfLayoutKeyCoordination (*pCurLayoutKeyCoordination)[MAX_KEY] = NULL;
622     McfLayoutKeyConfigure (*pCurLayoutKeyConfigure)[MAX_KEY] = NULL;
623     McfLayoutKeyProperties (*pCurLayoutKeyProperties)[MAX_KEY] = NULL;
624     McfButtonContext (*pCurButtonContext)[MAX_KEY] = NULL;
625
626     mcfshort layout =  NOT_USED;
627     if(windows && context) {
628         if (windows->is_base_window(window)) {
629             layout = mcf_input_mode_configure[inputmode].layoutId[context->get_display()];
630
631             pCurLayout = &mCurBaseLayout;
632             pCurLayoutKeyCoordination = &mCurBaseLayoutKeyCoordination;
633             pCurLayoutKeyConfigure = &mCurBaseLayoutKeyConfigure;
634             pCurLayoutKeyProperties = &mCurBaseLayoutKeyProperties;
635             pCurButtonContext = &mCurBaseButtonContext;
636
637         } else {
638             popupindex = windows->find_popup_window_index(window);
639             /* Check if the popup index is in valid range */
640             mcf_assert_return_false(popupindex >= 0 && popupindex < MAX_POPUP_WINDOW);
641
642             if (popupindex >= 0 && popupindex < MAX_POPUP_WINDOW) {
643                 layout = context->get_popup_layout(window);
644
645                 pCurLayout = &mCurPopupLayout[popupindex];
646                 pCurLayoutKeyCoordination = &mCurPopupLayoutKeyCoordination[popupindex];
647                 pCurLayoutKeyConfigure = &mCurPopupLayoutKeyConfigure[popupindex];
648                 pCurLayoutKeyProperties = &mCurPopupLayoutKeyProperties[popupindex];
649
650                 pCurButtonContext = &mCurPopupButtonContext[popupindex];
651             }
652         }
653
654         if (pCurLayout && pCurLayoutKeyCoordination && pCurLayoutKeyConfigure &&
655                 pCurLayoutKeyProperties && pCurButtonContext) {
656             /* If the layout index represents system-defined autopopup, generate layout and key properties data */
657             if (layout == MCF_LAYOUT_AUTOPOPUP) {
658                 const McfLayoutKeyProperties *properties =
659                     get_cur_layout_key_properties(context->get_cur_pressed_window(context->get_last_touch_device_id()),
660                 context->get_cur_pressed_key(context->get_last_touch_device_id()));
661
662                 generate_autopopup_layout(properties, pCurLayout, pCurLayoutKeyCoordination,
663                                           pCurLayoutKeyConfigure, pCurLayoutKeyProperties, pCurButtonContext);
664             } else {
665                 mcf_assert_return_false(layout >= 0 && layout < MAX_LAYOUT);
666
667                 if (mcf_check_arrindex(layout, MAX_LAYOUT)) {
668                     memcpy(pCurLayout, &mcf_layout[layout], sizeof(McfLayout));
669
670                     for (loop = 0;loop < (sizeof(mcf_layout_keyset) / sizeof(McfLayoutKeyset));loop++) {
671                         if (mcf_layout_keyset[loop].inputmodeID == inputmode && mcf_layout_keyset[loop].layoutID == layout) {
672                             keyset = static_cast<McfKeyset>(mcf_layout_keyset[loop].keysetID);
673                             break;
674                         }
675                     }
676
677                     mcf_assert_return_false(keyset >= 0 && keyset < MAX_KEYSET);
678
679                     if (mcf_check_arrindex(keyset, MAX_KEYSET)) {
680                         memcpy(pCurLayoutKeyCoordination, mcf_layout_key_coordination[layout],
681                                    sizeof(McfLayoutKeyCoordination) * MAX_KEY);
682                         memcpy(pCurLayoutKeyConfigure, mcf_layout_key_configure[keyset],
683                                    sizeof(McfLayoutKeyConfigure) * MAX_KEY);
684 #ifdef ENABLE_RESOURCE_DATA_FILE
685                         load_layoutkey_properties(keyset, pCurLayoutKeyProperties);
686 #else
687                         memcpy(pCurLayoutKeyProperties, mcf_layout_key_properties[keyset],
688                                    sizeof(McfLayoutKeyProperties) * MAX_KEY);
689 #endif
690
691                         memset(pCurButtonContext, 0x00, sizeof(McfButtonContext) * MAX_KEY);
692
693                         for (loop = 0;loop < MAX_KEY;loop++) {
694                             if (mcf_layout_key_configure[keyset][loop].fValid == USED) {
695                                 (*pCurButtonContext)[loop].used = TRUE;
696                                 if (popupindex != NOT_USED) {
697                                     change_by_privatekey(inputmode, layout, loop, &(mCurPopupLayoutKeyProperties[popupindex][loop]),
698                                                          &(mCurPopupLayoutKeyConfigure[popupindex][loop]));
699                                 } else {
700                                     change_by_privatekey(inputmode, layout, loop, &(mCurBaseLayoutKeyProperties[loop]),
701                                                          &(mCurBaseLayoutKeyConfigure[loop]));
702                                 }
703                             }
704                         }
705                     }
706                 }
707             }
708
709             /* Resize window */
710             if (windows->is_base_window(window)) {
711                 windows->resize_window(window, mCurBaseLayout.width, mCurBaseLayout.height);
712                 windows->resize_window(windows->get_dim_window(), mCurBaseLayout.width, mCurBaseLayout.height);
713             }
714
715             /* EFL testing */
716             windows->update_window(window);
717         }
718     }
719
720     return TRUE;
721 }
722
723 /**
724  * Returns the current key_coordination data
725  */
726 McfLayoutKeyCoordination*
727 CMCFResourceCache::get_cur_layout_key_coordination(mcfwindow window, mcfbyte keyindex)
728 {
729     MCF_DEBUG();
730     mcf_assert_return_null(keyindex < MAX_KEY);
731
732     CMCFWindows *windows = CMCFWindows::get_instance();
733     if (windows->get_base_window() == window) {
734         if (keyindex < MAX_KEY) {
735             return &mCurBaseLayoutKeyCoordination[keyindex];
736         }
737     } else {
738         mcfbyte popupindex = windows->find_popup_window_index(window);
739         mcf_assert_return_false(popupindex < MAX_POPUP_WINDOW);
740         if (keyindex < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
741             return &mCurPopupLayoutKeyCoordination[popupindex][keyindex];
742         }
743     }
744
745     return NULL;
746 }
747
748 /**
749  * Returns the current key_configure data
750  */
751 McfLayoutKeyConfigure*
752 CMCFResourceCache::get_cur_layout_key_configure(mcfwindow window, mcfbyte keyindex)
753 {
754     MCF_DEBUG();
755     mcf_assert_return_null(keyindex < MAX_KEY);
756
757     CMCFWindows *windows = CMCFWindows::get_instance();
758     if (windows->get_base_window() == window) {
759         if (keyindex < MAX_KEY) {
760             return &mCurBaseLayoutKeyConfigure[keyindex];
761         }
762     } else {
763         mcfbyte popupindex = windows->find_popup_window_index(window);
764         mcf_assert_return_false(popupindex < MAX_POPUP_WINDOW);
765         if (keyindex < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
766             return &mCurPopupLayoutKeyConfigure[popupindex][keyindex];
767         }
768     }
769
770     return NULL;
771 }
772
773 /**
774  * Returns the current key_properties data
775  */
776 McfLayoutKeyProperties*
777 CMCFResourceCache::get_cur_layout_key_properties(mcfwindow window, mcfbyte keyindex)
778 {
779     MCF_DEBUG();
780     mcf_assert_return_null(keyindex < MAX_KEY);
781
782     CMCFWindows *windows = CMCFWindows::get_instance();
783     if (windows->get_base_window() == window) {
784         if (keyindex < MAX_KEY) {
785             return &mCurBaseLayoutKeyProperties[keyindex];
786         }
787     } else {
788         mcfbyte popupindex = windows->find_popup_window_index(window);
789         mcf_assert_return_false(popupindex < MAX_POPUP_WINDOW);
790         if (keyindex < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
791             return &mCurPopupLayoutKeyProperties[popupindex][keyindex];
792         }
793     }
794
795     return NULL;
796 }
797
798 /**
799  * Returns the current label_properties data
800  */
801 const McfLabelProperties*
802 CMCFResourceCache::get_label_properties(mcfshort labeltype, mcfbyte index) const
803 {
804     MCF_DEBUG();
805
806     if (labeltype == MCF_LABEL_PROPERTY_AUTOPOPUP) {
807         return &mcf_autopopup_configure.labelProp;
808     } else if (labeltype == MCF_LABEL_PROPERTY_CANDIDATE) {
809         return &CAND_LABEL_PROP;
810     } else if (labeltype == MCF_LABEL_PROPERTY_ZOOMING) {
811         return &ZOOMING_LABEL_PROP;
812     } else {
813         if(mcf_check_arrindex(labeltype, MAX_LABEL_PROPERTIES) &&
814            mcf_check_arrindex(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
815           return &mcf_key_label_properties[labeltype][index];
816         }
817     }
818
819     return NULL;
820 }
821
822 /**
823  * Returns the current button_context data
824  */
825 McfButtonContext*
826 CMCFResourceCache::get_cur_button_context(mcfwindow window, mcfbyte keyindex)
827 {
828     MCF_DEBUG();
829     mcf_assert_return_null(keyindex < MAX_KEY);
830
831     CMCFWindows *windows = CMCFWindows::get_instance();
832     if (windows->get_base_window() == window) {
833         if (keyindex < MAX_KEY) {
834             return &mCurBaseButtonContext[keyindex];
835         }
836     } else {
837         mcfbyte popupindex = windows->find_popup_window_index(window);
838         mcf_assert_return_null(popupindex < MAX_POPUP_WINDOW);
839         if (keyindex < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
840             return &mCurPopupButtonContext[popupindex][keyindex];
841         }
842     }
843
844     return NULL;
845 }
846
847 /* Generate and fill autopopup layout data */
848 void CMCFResourceCache::generate_autopopup_layout(const McfLayoutKeyProperties *properties,
849                                                   McfLayout *pCurLayout,
850                                                   McfLayoutKeyCoordination (*pCurLayoutKeyCoordination)[MAX_KEY],
851                                                   McfLayoutKeyConfigure (*pCurLayoutKeyConfigure)[MAX_KEY],
852                                                   McfLayoutKeyProperties (*pCurLayoutKeyProperties)[MAX_KEY],
853                                                   McfButtonContext (*pCurButtonContext)[MAX_KEY])
854 {
855     MCF_DEBUG();
856
857     CMCFUtils *utils = CMCFUtils::get_instance();
858     CMCFContext *context = CMCFContext::get_instance();
859
860     int loop;
861     if (properties) {
862         mcfbyte numKeys, numColumns, numRows;
863         mcfint x, y, width, height;
864         MCFShiftState shiftidx = context->get_shift_state();
865         if(shiftidx < 0 || shiftidx >= MCF_SHIFT_STATE_MAX) shiftidx = MCF_SHIFT_STATE_OFF;
866         if (utils->get_autopopup_window_variables(properties->autopopupKeys[shiftidx], &numKeys, &numColumns,
867                                                           &numRows, &width, &height)) {
868             int row = 0, column = 0;
869
870             pCurLayout->fValid = TRUE;
871             pCurLayout->style = LAYOUT_STYLE_POPUP_GRAB;
872             pCurLayout->name = NULL;
873             pCurLayout->width = width;
874             pCurLayout->height = height;
875             memset(pCurLayout->imgPath, 0x00, sizeof(pCurLayout->imgPath));
876             pCurLayout->fUseSWbg = TRUE;
877             if (mcf_autopopup_configure.bgImgPath != NULL) {
878                 pCurLayout->imgPath[0] = mcf_autopopup_configure.bgImgPath;
879                 pCurLayout->fUseSWbg = FALSE;
880             }
881             pCurLayout->fUseSWBtn = TRUE;
882             /* If button image path is set, use images instead of SW buttons */
883             if (mcf_autopopup_configure.btnImgPath[0] != NULL) {
884                 pCurLayout->fUseSWBtn = FALSE;
885             }
886             pCurLayout->fUseZoomWnd = FALSE;
887             pCurLayout->linkedLayoutId = NOT_USED;
888             pCurLayout->fExtractBG = FALSE;
889             pCurLayout->bgColor = mcf_autopopup_configure.bgColor;
890             pCurLayout->bgLineWidth = mcf_autopopup_configure.bgLineWidth;
891             pCurLayout->bgLineColor = mcf_autopopup_configure.bgLineColor;
892             pCurLayout->addGrabLeft = mcf_autopopup_configure.addGrabLeft;
893             pCurLayout->addGrabRight = mcf_autopopup_configure.addGrabRight;
894             pCurLayout->addGrabTop = mcf_autopopup_configure.addGrabTop;
895             pCurLayout->addGrabBottom = mcf_autopopup_configure.addGrabBottom;
896
897             memset((*pCurLayoutKeyCoordination), 0x00, sizeof(McfLayoutKeyCoordination) * MAX_KEY);
898             memset((*pCurLayoutKeyConfigure), 0x00, sizeof(McfLayoutKeyConfigure) * MAX_KEY);
899             memset((*pCurLayoutKeyProperties), 0x00, sizeof(McfLayoutKeyProperties) * MAX_KEY);
900
901             memset((*pCurButtonContext), 0x00, sizeof(McfButtonContext) * MAX_KEY);
902
903             for (loop = 0;loop < (numColumns * numRows) && loop < MAX_KEY && loop < MAX_SIZE_OF_AUTOPOPUP_STRING;loop++) {
904                 char tempstr[2];
905                 column = (loop % numColumns);
906                 row = loop / numColumns;
907                 x = mcf_autopopup_configure.bgPadding + (mcf_autopopup_configure.btnWidth * column) +
908                     (mcf_autopopup_configure.btnSpacing * column);
909                 y = mcf_autopopup_configure.bgPadding + (mcf_autopopup_configure.btnHeight * row) +
910                     (mcf_autopopup_configure.btnSpacing * row);
911
912                 (*pCurLayoutKeyCoordination)[loop].fValid = TRUE;
913                 (*pCurLayoutKeyCoordination)[loop].x = x + utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
914                 (*pCurLayoutKeyCoordination)[loop].y = y + utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
915                 (*pCurLayoutKeyCoordination)[loop].width = mcf_autopopup_configure.btnWidth;
916                 (*pCurLayoutKeyCoordination)[loop].height = mcf_autopopup_configure.btnHeight;
917                 (*pCurLayoutKeyCoordination)[loop].popXOffset = 0;
918                 (*pCurLayoutKeyCoordination)[loop].popYOffset = 0;
919                 (*pCurLayoutKeyCoordination)[loop].popImageX = 0;
920                 (*pCurLayoutKeyCoordination)[loop].popImageY = 0;
921                 (*pCurLayoutKeyCoordination)[loop].subLayoutID = SUBLAYOUTID_NONE;
922
923                 (*pCurLayoutKeyConfigure)[loop].fValid = TRUE;
924                 if(loop < numKeys) {
925                     (*pCurLayoutKeyConfigure)[loop].buttonType = BUTTON_TYPE_NORMAL;
926                 } else {
927                     (*pCurLayoutKeyConfigure)[loop].buttonType = BUTTON_TYPE_UIITEM;
928                 }
929                 (*pCurLayoutKeyConfigure)[loop].keyType = KEY_TYPE_UNICODE;
930                 (*pCurLayoutKeyConfigure)[loop].popupType = POPUP_TYPE_NONE;
931                 (*pCurLayoutKeyConfigure)[loop].fUseMagnifier = FALSE;
932                 (*pCurLayoutKeyConfigure)[loop].fEnable = TRUE;
933                 memset((*pCurLayoutKeyConfigure)[loop].popupInputMode, NOT_USED,
934                            sizeof((*pCurLayoutKeyConfigure)[loop].popupInputMode));
935
936                 (*pCurLayoutKeyProperties)[loop].fValid = TRUE;
937                 (*pCurLayoutKeyProperties)[loop].labelCnt = 1;
938                 (*pCurLayoutKeyProperties)[loop].label[0][0] = properties->autopopupKeys[0][loop];
939                 (*pCurLayoutKeyProperties)[loop].label[1][0] = properties->autopopupKeys[1][loop];
940                 (*pCurLayoutKeyProperties)[loop].label[2][0] = properties->autopopupKeys[2][loop];
941                 (*pCurLayoutKeyProperties)[loop].labelPropId = MCF_LABEL_PROPERTY_AUTOPOPUP;
942                 memset((*pCurLayoutKeyProperties)[loop].labelImgPath, 0x00, sizeof((*pCurLayoutKeyProperties)[loop].labelImgPath));
943                 memset((*pCurLayoutKeyProperties)[loop].bgImgPath, 0x00, sizeof((*pCurLayoutKeyProperties)[loop].bgImgPath));
944                 for (int innerLoop = 0;innerLoop < MCF_BUTTON_STATE_MAX;innerLoop++) {
945                     (*pCurLayoutKeyProperties)[loop].bgImgPath[0][innerLoop] =
946                         (*pCurLayoutKeyProperties)[loop].bgImgPath[1][innerLoop] =
947                             mcf_autopopup_configure.btnImgPath[innerLoop];
948                 }
949
950                 (*pCurLayoutKeyProperties)[loop].keyValueCnt = 1;
951                 (*pCurLayoutKeyProperties)[loop].keyValue[0][0] = properties->autopopupKeys[0][loop];
952                 (*pCurLayoutKeyProperties)[loop].keyValue[1][0] = properties->autopopupKeys[1][loop];
953                 (*pCurLayoutKeyProperties)[loop].keyValue[2][0] = properties->autopopupKeys[2][loop];
954                 (*pCurLayoutKeyProperties)[loop].keyEvent[0][0] = 0;
955                 (*pCurLayoutKeyProperties)[loop].keyEvent[1][0] = 0;
956                 (*pCurLayoutKeyProperties)[loop].longKeyValue = NULL;
957                 (*pCurLayoutKeyProperties)[loop].longKeyEvent = 0;
958
959                 (*pCurLayoutKeyProperties)[loop].autopopupKeys[0][0] = NULL;
960                 (*pCurLayoutKeyProperties)[loop].autopopupKeys[1][0] = NULL;
961                 (*pCurLayoutKeyProperties)[loop].autopopupKeys[2][0] = NULL;
962                 (*pCurLayoutKeyProperties)[loop].extraOption = 0;
963
964                 (*pCurButtonContext)[loop].used = TRUE;
965             }
966             if(mcf_autopopup_configure.wndDecoSize > 0) {
967                 mcfbyte decoidx;
968                 for (decoidx = 0;decoidx < MAX_WND_DECORATOR;decoidx++) {
969                     if(loop + decoidx < MAX_KEY) {
970                         (*pCurLayoutKeyCoordination)[loop + decoidx].fValid = TRUE;
971                         switch(decoidx) {
972                             case WND_DECORATOR_TOP_LEFT:
973                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
974                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
975                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
976                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
977                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
978                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
979                             break;
980                             case WND_DECORATOR_TOP_CENTER:
981                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x =
982                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
983                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
984                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
985                                     width - (2 * utils->get_scale_x(mcf_autopopup_configure.wndDecoSize));
986                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
987                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
988                                 break;
989                             case WND_DECORATOR_TOP_RIGHT:
990                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x =
991                                     width - utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
992                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y = 0;
993                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
994                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
995                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
996                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
997                                 break;
998                             case WND_DECORATOR_MIDDLE_LEFT:
999                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1000                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y =
1001                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1002                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
1003                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1004                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
1005                                     height - (2 * utils->get_scale_y(mcf_autopopup_configure.wndDecoSize));
1006                                 break;
1007                             case WND_DECORATOR_MIDDLE_RIGHT:
1008                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x =
1009                                     width - utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1010                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y =
1011                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1012                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
1013                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1014                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
1015                                     height - (2 * utils->get_scale_y(mcf_autopopup_configure.wndDecoSize));
1016                                 break;
1017                             case WND_DECORATOR_BOTTOM_LEFT:
1018                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x = 0;
1019                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y =
1020                                     height - utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1021                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
1022                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1023                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
1024                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1025                                 break;
1026                             case WND_DECORATOR_BOTTOM_CENTER:
1027                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x =
1028                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1029                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y =
1030                                     height - utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1031                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
1032                                     width - (2 * utils->get_scale_x(mcf_autopopup_configure.wndDecoSize));
1033                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
1034                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1035                                 break;
1036                             case WND_DECORATOR_BOTTOM_RIGHT:
1037                                 (*pCurLayoutKeyCoordination)[loop + decoidx].x =
1038                                     width - utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1039                                 (*pCurLayoutKeyCoordination)[loop + decoidx].y =
1040                                     height - utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1041                                 (*pCurLayoutKeyCoordination)[loop + decoidx].width =
1042                                     utils->get_scale_x(mcf_autopopup_configure.wndDecoSize);
1043                                 (*pCurLayoutKeyCoordination)[loop + decoidx].height =
1044                                     utils->get_scale_y(mcf_autopopup_configure.wndDecoSize);
1045                                 break;
1046                         }
1047
1048                         (*pCurButtonContext)[loop + decoidx].used = TRUE;
1049                         (*pCurLayoutKeyConfigure)[loop + decoidx].fValid = TRUE;
1050                         (*pCurLayoutKeyConfigure)[loop + decoidx].buttonType = BUTTON_TYPE_UIITEM;
1051                         (*pCurLayoutKeyProperties)[loop + decoidx].fValid = TRUE;
1052                         (*pCurLayoutKeyProperties)[loop + decoidx].bgImgPath[0][0] =
1053                         (*pCurLayoutKeyProperties)[loop + decoidx].bgImgPath[0][1] =
1054                         (*pCurLayoutKeyProperties)[loop + decoidx].bgImgPath[1][0] =
1055                         (*pCurLayoutKeyProperties)[loop + decoidx].bgImgPath[1][1] =
1056                             mcf_autopopup_configure.wndDecoImgPath[decoidx];
1057                     }
1058                 }
1059             }
1060         }
1061     }
1062 }
1063
1064 /**
1065 * Sets the current theme name
1066 */
1067 mcfboolean
1068 CMCFResourceCache::set_cur_themename( const mcfchar *themename )
1069 {
1070     if (themename) {
1071         strncpy(mCurThemename, themename, _POSIX_PATH_MAX - 1);
1072         mCurThemename[_POSIX_PATH_MAX - 1] = '\0';
1073
1074         char fontprop_path[_POSIX_PATH_MAX] = { 0 };
1075         CMCFUtils *utils = CMCFUtils::get_instance();
1076         utils->get_composed_path(fontprop_path, sizeof(fontprop_path), FONT_PROPERTIES_FILE);
1077         FILE *fp = fopen(fontprop_path, "r");
1078         if(fp) {
1079             mcfint index = 0;
1080             mcfint r,g,b,a;
1081             if(!feof(fp)) {
1082                 for(mcfint shiftstate = 0;shiftstate < MCF_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1083                     char comment[_POSIX_PATH_MAX];
1084                     for(mcfint buttonstate = 0;buttonstate < MCF_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1085                         fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1086                         mcf_autopopup_configure.labelProp.fontColor[shiftstate][buttonstate].r = r;
1087                         mcf_autopopup_configure.labelProp.fontColor[shiftstate][buttonstate].g = g;
1088                         mcf_autopopup_configure.labelProp.fontColor[shiftstate][buttonstate].b = b;
1089                         mcf_autopopup_configure.labelProp.fontColor[shiftstate][buttonstate].a = a;
1090                     }
1091                     fscanf(fp, "%s", comment);
1092                 }
1093             }
1094             if(!feof(fp)) {
1095                 mcfint subindex = 0;
1096             }
1097             index = 0;
1098             while(index < MAX_LABEL_PROPERTIES && !feof(fp)) {
1099                 mcfint subindex = 0;
1100                 while(subindex < MAX_SIZE_OF_LABEL_FOR_ONE && !feof(fp) &&
1101                           mcf_key_label_properties[index][subindex].fValid) {
1102                     for(mcfint shiftstate = 0;shiftstate < MCF_SHIFT_STATE_MAX && !feof(fp);shiftstate++) {
1103                         char comment[_POSIX_PATH_MAX];
1104                         for(mcfint buttonstate = 0;buttonstate < MCF_BUTTON_STATE_MAX && !feof(fp);buttonstate++) {
1105                             fscanf(fp, "%d%d%d%d", &r, &g, &b, &a);
1106                             mcf_key_label_properties[index][subindex].fontColor[shiftstate][buttonstate].r = r;
1107                             mcf_key_label_properties[index][subindex].fontColor[shiftstate][buttonstate].g = g;
1108                             mcf_key_label_properties[index][subindex].fontColor[shiftstate][buttonstate].b = b;
1109                             mcf_key_label_properties[index][subindex].fontColor[shiftstate][buttonstate].a = a;
1110                         }
1111                         fscanf(fp, "%s", comment);
1112                     }
1113                     subindex++;
1114                 }
1115                 index++;
1116             }
1117         }
1118     }
1119
1120     return TRUE;
1121 }
1122
1123 const mcfchar*
1124 CMCFResourceCache::get_cur_themename()
1125 {
1126     return mCurThemename;
1127 }
1128
1129 /**
1130  * Returns a template private key properties using key properties of the given context
1131  */
1132 void
1133 CMCFResourceCache::clone_keyproperties(McfPrivateKeyProperties* priv, mcfbyte inputModeIdx, mcfbyte layoutIdx, mcfbyte keyIdx)
1134 {
1135     MCF_DEBUG();
1136     if (priv) {
1137         CMCFResourceCache *cache = CMCFResourceCache::get_instance();
1138         memset(priv, 0x00, sizeof(McfPrivateKeyProperties));
1139
1140         /* gets the value of the previous key properties */
1141         mcfint loop;
1142         McfKeyset keyset = MAX_KEYSET;
1143         McfLayoutKeyProperties keyProperties = { 0 };
1144         McfLayoutKeyConfigure keyConfigure = { 0 };
1145         for (loop = 0;loop < (int)((sizeof(mcf_layout_keyset) / sizeof(McfLayoutKeyset)));loop++)  {
1146             if (mcf_layout_keyset[loop].inputmodeID == inputModeIdx && mcf_layout_keyset[loop].layoutID == layoutIdx) {
1147                 keyset = static_cast<McfKeyset>(mcf_layout_keyset[loop].keysetID);
1148                 break;
1149             }
1150         }
1151         mcf_assert_return(keyset >= 0 && keyset < MAX_KEYSET);
1152         if (mcf_check_arrindex(keyset, MAX_KEYSET) && mcf_check_arrindex(keyIdx, MAX_KEY)) {
1153 #ifdef ENABLE_RESOURCE_DATA_FILE
1154             load_layoutkey_properties(keyset, keyIdx, &keyProperties);
1155 #else
1156             memcpy(&keyProperties, &mcf_layout_key_properties[keyset][keyIdx], sizeof(McfLayoutKeyProperties));
1157 #endif
1158             memcpy(&keyConfigure, &mcf_layout_key_configure[keyset][keyIdx], sizeof(McfLayoutKeyConfigure));
1159         }
1160
1161         mcf_assert_return(keyProperties.fValid == TRUE);
1162
1163         /* Sets the default properties base on the properties values of the given context */
1164         cache->copy_to_privatekeyproperties(&keyProperties, &keyConfigure, priv);
1165
1166         priv->inputModeIdx = inputModeIdx;
1167         priv->layoutIdx = layoutIdx;
1168         priv->keyIdx = keyIdx;
1169         priv->fValid = TRUE;
1170     }
1171 }
1172
1173 /**
1174  * Sets a private key to the current context
1175  *
1176  * @Usage
1177  *       McfPrivateKeyProperties privProperties;
1178  *       gCore->clone_keyproperties(&privProperties, INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
1179  *       // change
1180  *       gCore->set_private_key(&privProperties, TRUE);
1181  */
1182 mcfint
1183 CMCFResourceCache::set_private_key(McfPrivateKeyProperties* properties, mcfboolean fRedraw, mcfboolean fPendingUpdate)
1184 {
1185     MCF_DEBUG();
1186     CMCFContext *context = CMCFContext::get_instance();
1187     CMCFResourceCache *cache = CMCFResourceCache::get_instance();
1188     mcfint privateId = NOT_USED;
1189     mcfboolean isNeedUpdate = FALSE;
1190     if(cache && context && properties) {
1191         privateId = cache->add_private_key(properties, &isNeedUpdate);
1192         if (fRedraw && isNeedUpdate && !fPendingUpdate) {
1193             CMCFUIBuilder *builder = CMCFUIBuilder::get_instance();
1194             CMCFWindows *windows = CMCFWindows::get_instance();
1195             if(builder && windows) {
1196                 /* Fix me (we should consider popupwindow later)*/
1197                 mcfwindow window = windows->get_base_window();
1198                 /* Let's draw this private key only if the key's sublayout ID is active */
1199                 McfLayoutKeyCoordination *coordination = get_cur_layout_key_coordination(window, properties->keyIdx);
1200                 if(coordination) {
1201                     if(coordination->subLayoutID == SUBLAYOUTID_NONE ||
1202                        coordination->subLayoutID == context->get_cur_sublayout_id()) {
1203                         builder->draw_button(window, NULL, properties->keyIdx, mCurBaseButtonContext[properties->keyIdx].state);
1204                     }
1205                 }
1206             }
1207         }
1208     }
1209     return privateId;
1210 }
1211
1212 /**
1213  * Sets a private key to the current context
1214  * The other properties except given parameters will keep to the orginal value.
1215  * @Usage
1216  * gCore->set_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0, "private", 999, TRUE);
1217  *
1218  * @param fRedraw If true, it will redraw the current key
1219  */
1220 mcfint
1221 CMCFResourceCache::set_private_key(mcfshort inputModeIdx, mcfbyte layoutIdx, mcfbyte keyIdx, mcfchar* label,
1222                                            mcfchar* imagelabel[MCF_BUTTON_STATE_MAX], mcfchar* imagebg[MCF_BUTTON_STATE_MAX],
1223                                            mcfulong keyEvent, mcfchar *keyValue, mcfboolean fRedraw, mcfboolean fPendingUpdate)
1224 {
1225     MCF_DEBUG();
1226     McfPrivateKeyProperties privProperties;
1227     CMCFResourceCache *cache = CMCFResourceCache::get_instance();
1228     memset(&privProperties, 0x00, sizeof(McfPrivateKeyProperties));
1229
1230     /* If inputModeIx and layoutIdx both are NOT_USED, find current input mode and layout of base window */
1231     if (inputModeIdx == (mcfshort)NOT_USED && layoutIdx == (mcfbyte)NOT_USED) {
1232         CMCFContext *context = CMCFContext::get_instance();
1233         inputModeIdx = context->get_input_mode();
1234         layoutIdx = context->get_base_layout();
1235     }
1236
1237     /* gets the value of the previous key properties */
1238     mcfint loop;
1239     McfKeyset keyset = MAX_KEYSET;
1240     McfLayoutKeyProperties keyProperties = { 0 };
1241     McfLayoutKeyConfigure keyConfigure = { 0 };
1242     for (loop = 0;loop < (int)((sizeof(mcf_layout_keyset) / sizeof(McfLayoutKeyset)));loop++) {
1243         if ((mcf_layout_keyset[loop].inputmodeID == inputModeIdx || inputModeIdx == -1) &&
1244             mcf_layout_keyset[loop].layoutID == layoutIdx) {
1245             keyset = static_cast<McfKeyset>(mcf_layout_keyset[loop].keysetID);
1246             break;
1247         }
1248     }
1249     mcf_assert_return_false(keyset >= 0 && keyset < MAX_KEYSET);
1250     if (mcf_check_arrindex(keyset, MAX_KEYSET) && mcf_check_arrindex(keyIdx, MAX_KEY)) {
1251 #ifdef ENABLE_RESOURCE_DATA_FILE
1252             load_layoutkey_properties(keyset, keyIdx, &keyProperties);
1253 #else
1254         memcpy(&keyProperties, &mcf_layout_key_properties[keyset][keyIdx], sizeof(McfLayoutKeyProperties));
1255 #endif
1256         memcpy(&keyConfigure, &mcf_layout_key_configure[keyset][keyIdx], sizeof(McfLayoutKeyConfigure));
1257     }
1258
1259     mcf_assert_return_false(keyProperties.fValid == TRUE);
1260
1261     /* Sets the default properties base on the properties values of the given context */
1262     cache->copy_to_privatekeyproperties(&keyProperties, &keyConfigure, &privProperties);
1263
1264     privProperties.fValid = TRUE;
1265     privProperties.inputModeIdx = inputModeIdx;
1266     privProperties.layoutIdx = layoutIdx;
1267     privProperties.keyIdx = keyIdx;
1268     privProperties.labelCnt = 1;
1269     privProperties.keyEvent[MCF_SHIFT_STATE_LOCK][0] = privProperties.keyEvent[MCF_SHIFT_STATE_ON][0] =
1270     privProperties.keyEvent[MCF_SHIFT_STATE_OFF][0] = keyEvent;
1271     privProperties.label[MCF_SHIFT_STATE_LOCK][0] = privProperties.label[MCF_SHIFT_STATE_ON][0] =
1272     privProperties.label[MCF_SHIFT_STATE_OFF][0] = label;
1273     privProperties.keyValue[MCF_SHIFT_STATE_LOCK][0] = privProperties.keyValue[MCF_SHIFT_STATE_ON][0] =
1274     privProperties.keyValue[MCF_SHIFT_STATE_OFF][0] = keyValue;
1275     for (loop =0;loop < MCF_BUTTON_STATE_MAX;loop++) {
1276         if (imagelabel) {
1277             privProperties.labelImgPath[MCF_SHIFT_STATE_LOCK][loop] =
1278             privProperties.labelImgPath[MCF_SHIFT_STATE_ON][loop] =
1279             privProperties.labelImgPath[MCF_SHIFT_STATE_OFF][loop] = imagelabel[loop];
1280         }
1281     }
1282     for (loop =0;loop < MCF_BUTTON_STATE_MAX;loop++) {
1283         if (imagebg) {
1284             privProperties.bgImgPath[MCF_SHIFT_STATE_LOCK][loop] =
1285             privProperties.bgImgPath[MCF_SHIFT_STATE_ON][loop] =
1286             privProperties.bgImgPath[MCF_SHIFT_STATE_OFF][loop] = imagebg[loop];
1287         }
1288     }
1289     return set_private_key(&privProperties, fRedraw, fPendingUpdate);
1290 }
1291
1292 /**
1293 * Unset private key for specific key
1294 * @Usage
1295 * gCore->unset_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
1296 */
1297 void
1298 CMCFResourceCache::unset_private_key(mcfshort inputModeIdx, mcfbyte layoutIdx, mcfbyte keyIdx)
1299 {
1300     /* Since removed private key buffer will be shifted left, increase index only for successful deletion */
1301     mcfint loop = 0;
1302     mcfint count = 0;
1303     while (count++ < MAX_PRIVATE_KEY) {
1304         if ((mPrivateKeyProperties[loop].fValid &&
1305             mPrivateKeyProperties[loop].inputModeIdx == inputModeIdx) &&
1306             mPrivateKeyProperties[loop].layoutIdx == layoutIdx &&
1307             mPrivateKeyProperties[loop].keyIdx == keyIdx) {
1308                 remove_private_key(loop);
1309         } else {
1310             loop++;
1311         }
1312     }
1313 }
1314
1315 /**
1316 * Unset private by customID, effective when removing all private keys with same customID
1317 * @Usage
1318 * gCore->unset_private_key(3);
1319 */
1320 void
1321 CMCFResourceCache::unset_private_key(mcfint customID)
1322 {
1323     /* Since removed private key buffer will be shifted left, increase index only for successful deletion */
1324     mcfint loop = 0;
1325     mcfint count = 0;
1326     while (count++ < MAX_PRIVATE_KEY) {
1327         if(mPrivateKeyProperties[loop].fValid &&
1328             mPrivateKeyProperties[loop].customID == customID) {
1329             remove_private_key(loop);
1330         } else {
1331             loop++;
1332         }
1333     }
1334 }
1335
1336 /**
1337 * Find appropriate index of the key specified by customID
1338 */
1339 mcfbyte
1340 CMCFResourceCache::find_keyidx_by_customid(mcfshort inputModeIdx, mcfbyte layoutIdx, mcfshort customID)
1341 {
1342     mcfbyte ret = NOT_USED;
1343     mcfint loop;
1344     McfKeyset keyset = MAX_KEYSET;
1345
1346     /* If inputModeIx and layoutIdx both are NOT_USED, find current input mode and layout of base window */
1347     if (inputModeIdx == (mcfshort)NOT_USED && layoutIdx == (mcfbyte)NOT_USED) {
1348         CMCFContext *context = CMCFContext::get_instance();
1349         inputModeIdx = context->get_input_mode();
1350         layoutIdx = context->get_base_layout();
1351     }
1352
1353     for (loop = 0;loop < (sizeof(mcf_layout_keyset) / sizeof(McfLayoutKeyset));loop++) {
1354         if ((mcf_layout_keyset[loop].inputmodeID == inputModeIdx || inputModeIdx == -1) &&
1355                 mcf_layout_keyset[loop].layoutID == layoutIdx) {
1356             keyset = static_cast<McfKeyset>(mcf_layout_keyset[loop].keysetID);
1357             break;
1358         }
1359     }
1360     if (mcf_check_arrindex(keyset, MAX_KEYSET)) {
1361         for (loop = 0;loop < MAX_KEY;loop++) {
1362             if (mcf_layout_key_configure[keyset][loop].fValid != USED) break;
1363             if (mcf_layout_key_configure[keyset][loop].customID == customID) {
1364                 ret = loop;
1365                 break;
1366             }
1367         }
1368     }
1369
1370     return ret;
1371 }
1372
1373 /**
1374 * Enable button for handling mouse events
1375 */
1376 void CMCFResourceCache::enable_button(mcfbyte keyIdx)
1377 {
1378     MCF_DEBUG();
1379
1380     if (mcf_check_arrindex(keyIdx, MAX_KEY)) {
1381         mCurBaseButtonContext[keyIdx].state = BUTTON_STATE_NORMAL;
1382
1383         CMCFWindows *windows = CMCFWindows::get_instance();
1384         /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
1385         windows->update_window(windows->get_base_window());
1386     }
1387 }
1388
1389 /**
1390 * Disable button to ignore mouse events
1391 */
1392 void CMCFResourceCache::disable_button(mcfbyte keyIdx)
1393 {
1394     MCF_DEBUG();
1395
1396     if (mcf_check_arrindex(keyIdx, MAX_KEY)) {
1397         mCurBaseButtonContext[keyIdx].state = BUTTON_STATE_DISABLED;
1398
1399         CMCFWindows *windows = CMCFWindows::get_instance();
1400         /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
1401         windows->update_window(windows->get_base_window());
1402     }
1403 }