Add new feature for "auto_align"
[apps/native/widget/widget-edje.git] / src / script_port.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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 #include <stdio.h>
18 #include <libgen.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <ctype.h>
22
23 #include <Elementary.h>
24 #include <Evas.h>
25 #include <Edje.h>
26 #include <Eina.h>
27 #include <Ecore.h>
28 #include <Ecore_Evas.h>
29 #include <Eet.h>
30 #include <efl_assist.h>
31
32 #include <system_settings.h>
33
34 #include <dlog.h>
35 #include <debug.h>
36 #include <vconf.h>
37 #include <livebox-errno.h>
38 #include <livebox-service.h>
39
40 #include "script_port.h"
41 #include "abi.h"
42
43 #define TEXT_CLASS      "tizen"
44 #define DEFAULT_FONT_SIZE       -100
45
46 #define PUBLIC __attribute__((visibility("default")))
47
48 struct image_option {
49         int orient;
50         int aspect;
51         enum {
52                 FILL_DISABLE,
53                 FILL_IN_SIZE,
54                 FILL_OVER_SIZE
55         } fill;
56
57         struct shadow {
58                 int enabled;
59                 int angle;
60                 int offset;
61                 int softness;
62                 int color;
63         } shadow;
64
65         int width;
66         int height;
67 };
68
69 struct info {
70         char *file;
71         char *group;
72         char *category;
73
74         int is_mouse_down;
75         void *buffer_handle;
76
77         Ecore_Evas *ee;
78         Evas *e;
79
80         Evas_Object *parent;
81
82         Eina_List *obj_list;
83
84         int (*render_pre)(void *buffer_handle, void *data);
85         int (*render_post)(void *render_handle, void *data);
86         void *render_data;
87 };
88
89 struct child {
90         Evas_Object *obj;
91         char *part;
92 };
93
94 struct obj_info {
95         char *id;
96         Eina_List *children;
97         Evas_Object *parent;
98         int delete_me;
99 };
100
101 static struct {
102         char *font_name;
103         int font_size;
104         int access_on;
105
106         Eina_List *handle_list;
107         int premultiplied;
108 } s_info = {
109         .font_name = NULL,
110         .font_size = -100,
111
112         .handle_list = NULL,
113         .access_on = 0,
114         .premultiplied = 1,
115 };
116
117 static inline Evas_Object *find_edje(struct info *handle, const char *id)
118 {
119         Eina_List *l;
120         Evas_Object *edje;
121         struct obj_info *obj_info;
122
123         EINA_LIST_FOREACH(handle->obj_list, l, edje) {
124                 obj_info = evas_object_data_get(edje, "obj_info");
125                 if (!obj_info) {
126                         ErrPrint("Object info is not valid\n");
127                         continue;
128                 }
129
130                 if (!id) {
131                         if (!obj_info->id) {
132                                 return edje;
133                         }
134
135                         continue;
136                 } else if (!obj_info->id) {
137                         continue;
138                 }
139
140                 if (!strcmp(obj_info->id, id)) {
141                         return edje;
142                 }
143         }
144
145         DbgPrint("EDJE[%s] is not found\n", id);
146         return NULL;
147 }
148
149 PUBLIC const char *script_magic_id(void)
150 {
151         return "edje";
152 }
153
154 PUBLIC int script_update_color(void *h, const char *id, const char *part, const char *rgba)
155 {
156         struct info *handle = h;
157         Evas_Object *edje;
158         int r[3], g[3], b[3], a[3];
159         int ret;
160
161         edje = find_edje(handle, id);
162         if (!edje) {
163                 return LB_STATUS_ERROR_NOT_EXIST;
164         }
165
166         ret = sscanf(rgba, "%d %d %d %d %d %d %d %d %d %d %d %d",
167                                         r, g, b, a,                     /* OBJECT */
168                                         r + 1, g + 1, b + 1, a + 1,     /* OUTLINE */
169                                         r + 2, g + 2, b + 2, a + 2);    /* SHADOW */
170         if (ret != 12) {
171                 DbgPrint("id[%s] part[%s] rgba[%s]\n", id, part, rgba);
172                 return LB_STATUS_ERROR_INVALID;
173         }
174
175         ret = edje_object_color_class_set(elm_layout_edje_get(edje), part,
176                                 r[0], g[0], b[0], a[0], /* OBJECT */
177                                 r[1], g[1], b[1], a[1], /* OUTLINE */
178                                 r[2], g[2], b[2], a[2]); /* SHADOW */
179
180         DbgPrint("EDJE[%s] color class is %s changed", id, ret == EINA_TRUE ? "successfully" : "not");
181         return LB_STATUS_SUCCESS;
182 }
183
184 static void activate_cb(void *data, Evas_Object *part_obj, Elm_Object_Item *item)
185 {
186         Evas *e;
187         int x;
188         int y;
189         int w;
190         int h;
191         double timestamp;
192
193         e = evas_object_evas_get(part_obj);
194         evas_object_geometry_get(part_obj, &x, &y, &w, &h);
195         x += w / 2;
196         y += h / 2;
197
198 #if defined(_USE_ECORE_TIME_GET)
199         timestamp = ecore_time_get();
200 #else
201         struct timeval tv;
202         if (gettimeofday(&tv, NULL) < 0) {
203                 ErrPrint("Failed to get time\n");
204                 timestamp = 0.0f;
205         } else {
206                 timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
207         }
208 #endif
209
210         DbgPrint("Cursor is on %dx%d\n", x, y);
211         evas_event_feed_mouse_move(e, x, y, timestamp * 1000, NULL);
212         evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
213         evas_event_feed_mouse_move(e, x, y, (timestamp + 0.02f) * 1000, NULL);
214         evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.03f) * 1000, NULL);
215 }
216
217 static void update_focus_chain(struct info *handle, Evas_Object *ao)
218 {
219         const Eina_List *list;
220
221         list = elm_object_focus_custom_chain_get(handle->parent);
222         if (!eina_list_data_find(list, ao)) {
223                 DbgPrint("Append again to the focus chain\n");
224                 elm_object_focus_custom_chain_append(handle->parent, ao, NULL);
225         }
226 }
227
228 PUBLIC int script_update_text(void *h, const char *id, const char *part, const char *text)
229 {
230         struct obj_info *obj_info;
231         struct info *handle = h;
232         Evas_Object *edje;
233         Evas_Object *edje_part;
234
235         edje = find_edje(handle, id);
236         if (!edje) {
237                 ErrPrint("Failed to find EDJE\n");
238                 return LB_STATUS_ERROR_NOT_EXIST;
239         }
240
241         obj_info = evas_object_data_get(edje, "obj_info");
242         if (!obj_info) {
243                 ErrPrint("Object info is not available\n");
244                 return LB_STATUS_ERROR_FAULT;
245         }
246
247         elm_object_part_text_set(edje, part, text ? text : "");
248
249         edje_part = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
250         if (edje_part) {
251                 Evas_Object *ao;
252                 char *utf8;
253
254                 ao = evas_object_data_get(edje_part, "ao");
255                 if (!ao) {
256                         ao = elm_access_object_register(edje_part, handle->parent);
257                         if (!ao) {
258                                 ErrPrint("Unable to register an access object(%s)\n", part);
259                                 goto out;
260                         }
261
262                         evas_object_data_set(edje_part, "ao", ao);
263                         elm_access_activate_cb_set(ao, activate_cb, NULL);
264                         elm_object_focus_custom_chain_append(handle->parent, ao, NULL);
265
266                         DbgPrint("[%s] Register access info: (%s) to, %p\n", part, text, handle->parent);
267                 }
268
269                 if (!text || !strlen(text)) {
270                         /*!
271                          * \note
272                          * Delete callback will be called
273                          */
274                         DbgPrint("[%s] Remove access object(%p)\n", part, ao);
275                         elm_access_object_unregister(ao);
276
277                         goto out;
278                 }
279
280                 utf8 = elm_entry_markup_to_utf8(text);
281                 if ((!utf8 || !strlen(utf8))) {
282                         free(utf8);
283                         /*!
284                          * \note
285                          * Delete callback will be called
286                          */
287                         DbgPrint("[%s] Remove access object(%p)\n", part, ao);
288                         elm_access_object_unregister(ao);
289
290                         goto out;
291                 }
292
293                 elm_access_info_set(ao, ELM_ACCESS_INFO, utf8);
294                 free(utf8);
295
296                 update_focus_chain(handle, ao);
297         } else {
298                 ErrPrint("Unable to get text part[%s]\n", part);
299         }
300
301 out:
302         return LB_STATUS_SUCCESS;
303 }
304
305 static void parse_aspect(struct image_option *img_opt, const char *value, int len)
306 {
307         while (len > 0 && *value == ' ') {
308                 value++;
309                 len--;
310         }
311
312         if (len < 4) {
313                 return;
314         }
315
316         img_opt->aspect = !strncasecmp(value, "true", 4);
317         DbgPrint("Parsed ASPECT: %d (%s)\n", img_opt->aspect, value);
318 }
319
320 static void parse_orient(struct image_option *img_opt, const char *value, int len)
321 {
322         while (len > 0 && *value == ' ') {
323                 value++;
324                 len--;
325         }
326
327         if (len < 4) {
328                 return;
329         }
330
331         img_opt->orient = !strncasecmp(value, "true", 4);
332         DbgPrint("Parsed ORIENT: %d (%s)\n", img_opt->orient, value);
333 }
334
335 static void parse_size(struct image_option *img_opt, const char *value, int len)
336 {
337         int width;
338         int height;
339         char *buf;
340
341         while (len > 0 && *value == ' ') {
342                 value++;
343                 len--;
344         }
345
346         buf = strndup(value, len);
347         if (!buf) {
348                 ErrPrint("Heap: %s\n", strerror(errno));
349                 return;
350         }
351
352         if (sscanf(buf, "%dx%d", &width, &height) == 2) {
353                 img_opt->width = width;
354                 img_opt->height = height;
355                 DbgPrint("Parsed size : %dx%d (%s)\n", width, height, buf);
356         } else {
357                 DbgPrint("Invalid size tag[%s]\n", buf);
358         }
359
360         free(buf);
361 }
362
363 static void parse_shadow(struct image_option *img_opt, const char *value, int len)
364 {
365         int angle;
366         int offset;
367         int softness;
368         int color;
369
370         if (sscanf(value, "%d,%d,%d,%x", &angle, &offset, &softness, &color) != 4) {
371                 ErrPrint("Invalid shadow [%s]\n", value);
372         } else {
373                 img_opt->shadow.enabled = 1;
374                 img_opt->shadow.angle = angle;
375                 img_opt->shadow.offset = offset;
376                 img_opt->shadow.softness = softness;
377                 img_opt->shadow.color = color;
378         }
379 }
380
381 static void parse_fill(struct image_option *img_opt, const char *value, int len)
382 {
383         while (len > 0 && *value == ' ') {
384                 value++;
385                 len--;
386         }
387
388         if (!strncasecmp(value, "in-size", len)) {
389                 img_opt->fill = FILL_IN_SIZE;
390         } else if (!strncasecmp(value, "over-size", len)) {
391                 img_opt->fill = FILL_OVER_SIZE;
392         } else {
393                 img_opt->fill = FILL_DISABLE;
394         }
395
396         DbgPrint("Parsed FILL: %d (%s)\n", img_opt->fill, value);
397 }
398
399 static inline void parse_image_option(const char *option, struct image_option *img_opt)
400 {
401         const char *ptr;
402         const char *cmd;
403         const char *value;
404         struct {
405                 const char *cmd;
406                 void (*handler)(struct image_option *img_opt, const char *value, int len);
407         } cmd_list[] = {
408                 {
409                         .cmd = "aspect", /* Keep the aspect ratio */
410                         .handler = parse_aspect,
411                 },
412                 {
413                         .cmd = "orient", /* Keep the orientation value: for the rotated images */
414                         .handler = parse_orient,
415                 },
416                 {
417                         .cmd = "fill", /* Fill the image to its container */
418                         .handler = parse_fill, /* Value: in-size, over-size, disable(default) */
419                 },
420                 {
421                         .cmd = "size",
422                         .handler = parse_size,
423                 },
424                 {
425                         .cmd = "shadow",
426                         .handler = parse_shadow,
427                 },
428         };
429         enum {
430                 STATE_START,
431                 STATE_TOKEN,
432                 STATE_DATA,
433                 STATE_IGNORE,
434                 STATE_ERROR,
435                 STATE_END
436         } state;
437         int idx;
438         int tag;
439
440         if (!option || !*option) {
441                 return;
442         }
443
444         state = STATE_START;
445         /*!
446          * \note
447          * GCC 4.7 warnings uninitialized idx and tag value.
448          * But it will be initialized by the state machine. :(
449          * Anyway, I just reset idx and tag for reducing the GCC4.7 complains.
450          */
451         idx = 0;
452         tag = 0;
453         cmd = NULL;
454         value = NULL;
455
456         for (ptr = option; state != STATE_END; ptr++) {
457                 switch (state) {
458                 case STATE_START:
459                         if (*ptr == '\0') {
460                                 state = STATE_END;
461                                 continue;
462                         }
463
464                         if (isalpha(*ptr)) {
465                                 state = STATE_TOKEN;
466                                 ptr--;
467                         }
468                         tag = 0;
469                         idx = 0;
470
471                         cmd = cmd_list[tag].cmd;
472                         break;
473                 case STATE_IGNORE:
474                         if (*ptr == '=') {
475                                 state = STATE_DATA;
476                                 value = ptr;
477                         } else if (*ptr == '\0') {
478                                 state = STATE_END;
479                         }
480                         break;
481                 case STATE_TOKEN:
482                         if (cmd[idx] == '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '=')) {
483                                 if (*ptr == '=') {
484                                         value = ptr;
485                                         state = STATE_DATA;
486                                 } else {
487                                         state = STATE_IGNORE;
488                                 }
489                                 idx = 0;
490                         } else if (*ptr == '\0') {
491                                 state = STATE_END;
492                         } else if (cmd[idx] == *ptr) {
493                                 idx++;
494                         } else {
495                                 ptr -= (idx + 1);
496
497                                 tag++;
498                                 if (tag == sizeof(cmd_list) / sizeof(cmd_list[0])) {
499                                         tag = 0;
500                                         state = STATE_ERROR;
501                                 } else {
502                                         cmd = cmd_list[tag].cmd;
503                                 }
504                                 idx = 0;
505                         }
506                         break;
507                 case STATE_DATA:
508                         if (*ptr == ';' || *ptr == '\0') {
509                                 cmd_list[tag].handler(img_opt, value + 1, idx);
510                                 state = *ptr ? STATE_START : STATE_END;
511                         } else {
512                                 idx++;
513                         }
514                         break;
515                 case STATE_ERROR:
516                         if (*ptr == ';') {
517                                 state = STATE_START;
518                         } else if (*ptr == '\0') {
519                                 state = STATE_END;
520                         }
521                         break;
522                 default:
523                         break;
524                 }
525         }
526 }
527
528 PUBLIC int script_update_access(void *_h, const char *id, const char *part, const char *text, const char *option)
529 {
530         struct info *handle = _h;
531         Evas_Object *edje;
532         struct obj_info *obj_info;
533         Evas_Object *edje_part;
534
535         edje = find_edje(handle, id);
536         if (!edje) {
537                 ErrPrint("No such object: %s\n", id);
538                 return LB_STATUS_ERROR_NOT_EXIST;
539         }
540
541         obj_info = evas_object_data_get(edje, "obj_info");
542         if (!obj_info) {
543                 ErrPrint("Object info is not available\n");
544                 return LB_STATUS_ERROR_FAULT;
545         }
546
547         edje_part = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
548         if (edje_part) {
549                 Evas_Object *ao;
550
551                 ao = evas_object_data_get(edje_part, "ao");
552                 if (ao) {
553                         if (text && strlen(text)) {
554                                 elm_access_info_set(ao, ELM_ACCESS_INFO, text);
555                                 DbgPrint("Access info is updated: %s [%s], %p\n", part, text, ao);
556                                 update_focus_chain(handle, ao);
557                         } else {
558                                 /*!
559                                  * \note
560                                  * Delete clalback will be called
561                                  */
562                                 DbgPrint("[%s] Remove access object(%p)\n", part, ao);
563                                 elm_access_object_unregister(ao);
564                         }
565                 } else if (text && strlen(text)) {
566                         ao = elm_access_object_register(edje_part, handle->parent);
567                         if (!ao) {
568                                 ErrPrint("Unable to register an access object(%s)\n", part);
569                         } else {
570                                 elm_access_info_set(ao, ELM_ACCESS_INFO, text);
571
572                                 evas_object_data_set(edje_part, "ao", ao);
573                                 elm_object_focus_custom_chain_append(handle->parent, ao, NULL);
574                                 elm_access_activate_cb_set(ao, activate_cb, NULL);
575                                 DbgPrint("[%s] Register access info: (%s) to, %p (%p)\n", part, text, handle->parent, ao);
576                         }
577                 }
578         } else {
579                 ErrPrint("[%s] is not exists\n", part);
580         }
581
582         return LB_STATUS_SUCCESS;
583 }
584
585 PUBLIC int script_operate_access(void *_h, const char *id, const char *part, const char *operation, const char *option)
586 {
587         struct info *handle = _h;
588         Evas_Object *edje;
589         struct obj_info *obj_info;
590         Elm_Access_Action_Info action_info;
591         int ret;
592
593         if (!operation || !strlen(operation)) {
594                 return LB_STATUS_ERROR_INVALID;
595         }
596
597         edje = find_edje(handle, id);
598         if (!edje) {
599                 ErrPrint("No such object: %s\n", id);
600                 return LB_STATUS_ERROR_NOT_EXIST;
601         }
602
603         obj_info = evas_object_data_get(edje, "obj_info");
604         if (!obj_info) {
605                 ErrPrint("Object info is not available\n");
606                 return LB_STATUS_ERROR_FAULT;
607         }
608
609         memset(&action_info, 0, sizeof(action_info));
610
611         /* OPERATION is defined in liblivebox package */
612         if (!strcasecmp(operation, "set,hl")) {
613                 if (part) {
614                         Evas_Object *edje_part;
615                         Evas_Coord x;
616                         Evas_Coord y;
617                         Evas_Coord w;
618                         Evas_Coord h;
619
620                         edje_part = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
621                         if (!edje_part) {
622                                 ErrPrint("Invalid part: %s\n", part);
623                                 goto out;
624                         }
625
626                         evas_object_geometry_get(edje_part, &x, &y, &w, &h);
627
628                         action_info.x = x + w / 2;
629                         action_info.y = x + h / 2;
630                 } else if (option && sscanf(option, "%dx%d", &action_info.x, &action_info.y) == 2) {
631                 } else {
632                         ErrPrint("Insufficient info for HL\n");
633                         goto out;
634                 }
635
636                 DbgPrint("TXxTY: %dx%d\n", action_info.x, action_info.y);
637                 ret = elm_access_action(edje, ELM_ACCESS_ACTION_HIGHLIGHT, &action_info);
638                 if (ret == EINA_FALSE) {
639                         ErrPrint("Action error\n");
640                 }
641         } else if (!strcasecmp(operation, "unset,hl")) {
642                 ret = elm_access_action(edje, ELM_ACCESS_ACTION_UNHIGHLIGHT, &action_info);
643                 if (ret == EINA_FALSE) {
644                         ErrPrint("Action error\n");
645                 }
646         } else if (!strcasecmp(operation, "next,hl")) {
647                 action_info.highlight_cycle = (!!option) && (!!strcasecmp(option, "no,cycle"));
648
649                 ret = elm_access_action(edje, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, &action_info);
650                 if (ret == EINA_FALSE) {
651                         ErrPrint("Action error\n");
652                 }
653         } else if (!strcasecmp(operation, "prev,hl")) {
654                 action_info.highlight_cycle = EINA_TRUE;
655                 ret = elm_access_action(edje, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, &action_info);
656                 if (ret == EINA_FALSE) {
657                         ErrPrint("Action error\n");
658                 }
659         } else if (!strcasecmp(operation, "reset,focus")) {
660                 DbgPrint("Reset Focus\n");
661                 elm_object_focus_custom_chain_set(edje, NULL);
662         }
663
664 out:
665         return LB_STATUS_SUCCESS;
666 }
667
668 static inline void apply_shadow_effect(struct image_option *img_opt, Evas_Object *img)
669 {
670         ea_effect_h *ea_effect;
671
672         if (!img_opt->shadow.enabled) {
673                 return;
674         }
675
676         ea_effect = ea_image_effect_create();
677         if (!ea_effect) {
678                 return;
679         }
680
681         // -90, 2, 4, 0x99000000
682         ea_image_effect_add_outer_shadow(ea_effect, img_opt->shadow.angle, img_opt->shadow.offset, img_opt->shadow.softness, img_opt->shadow.color);
683         ea_object_image_effect_set(img, ea_effect);
684
685         ea_image_effect_destroy(ea_effect);
686 }
687
688 PUBLIC int script_update_image(void *_h, const char *id, const char *part, const char *path, const char *option)
689 {
690         struct info *handle = _h;
691         Evas_Load_Error err;
692         Evas_Object *edje;
693         Evas_Object *img;
694         Evas_Coord w, h;
695         struct obj_info *obj_info;
696         struct image_option img_opt = {
697                 .aspect = 0,
698                 .orient = 0,
699                 .fill = FILL_DISABLE,
700                 .width = -1,
701                 .height = -1,
702                 .shadow = {
703                         .enabled = 0,
704                 },
705         };
706
707         edje = find_edje(handle, id);
708         if (!edje) {
709                 ErrPrint("No such object: %s\n", id);
710                 return LB_STATUS_ERROR_NOT_EXIST;
711         }
712
713         obj_info = evas_object_data_get(edje, "obj_info");
714         if (!obj_info) {
715                 ErrPrint("Object info is not available\n");
716                 return LB_STATUS_ERROR_FAULT;
717         }
718
719         img = elm_object_part_content_unset(edje, part);
720         if (img) {
721                 DbgPrint("delete object %s %p\n", part, img);
722                 evas_object_del(img);
723         }
724
725         if (!path || !strlen(path) || access(path, R_OK) != 0) {
726                 DbgPrint("SKIP - Path: [%s]\n", path);
727                 return LB_STATUS_SUCCESS;
728         }
729
730         img = evas_object_image_add(handle->e);
731         if (!img) {
732                 ErrPrint("Failed to add an image object\n");
733                 return LB_STATUS_ERROR_FAULT;
734         }
735
736         evas_object_image_preload(img, EINA_FALSE);
737         parse_image_option(option, &img_opt);
738         evas_object_image_load_orientation_set(img, img_opt.orient);
739
740         evas_object_image_file_set(img, path, NULL);
741         err = evas_object_image_load_error_get(img);
742         if (err != EVAS_LOAD_ERROR_NONE) {
743                 ErrPrint("Load error: %s\n", evas_load_error_str(err));
744                 evas_object_del(img);
745                 return LB_STATUS_ERROR_IO;
746         }
747
748         apply_shadow_effect(&img_opt, img);
749
750         evas_object_image_size_get(img, &w, &h);
751         if (img_opt.aspect) {
752                 if (img_opt.fill == FILL_OVER_SIZE) {
753                         Evas_Coord part_w;
754                         Evas_Coord part_h;
755
756                         if (img_opt.width >= 0 && img_opt.height >= 0) {
757                                 part_w = img_opt.width * elm_config_scale_get();
758                                 part_h = img_opt.height * elm_config_scale_get();
759                         } else {
760                                 part_w = 0;
761                                 part_h = 0;
762                                 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
763                         }
764                         DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
765
766                         if (part_w > w || part_h > h) {
767                                 double fw;
768                                 double fh;
769
770                                 fw = (double)part_w / (double)w;
771                                 fh = (double)part_h / (double)h;
772
773                                 if (fw > fh) {
774                                         w = part_w;
775                                         h = (double)h * fw;
776                                 } else {
777                                         h = part_h;
778                                         w = (double)w * fh;
779                                 }
780                         }
781
782                         if (!part_w || !part_h || !w || !h) {
783                                 evas_object_del(img);
784                                 return LB_STATUS_ERROR_INVALID;
785                         }
786
787                         if (evas_object_image_region_support_get(img)) {
788                                 evas_object_image_load_region_set(img, (w - part_w) / 2, (h - part_h) / 2, part_w, part_h);
789                                 evas_object_image_load_size_set(img, part_w, part_h);
790                                 evas_object_image_filled_set(img, EINA_TRUE);
791                                 //evas_object_image_fill_set(img, 0, 0, part_w, part_h);
792                                 DbgPrint("Size: %dx%d (region: %dx%d - %dx%d)\n", w, h, (w - part_w) / 2, (h - part_h) / 2, part_w, part_h);
793                         } else {
794                                 Ecore_Evas *ee;
795                                 Evas *e;
796                                 Evas_Object *src_img;
797                                 Evas_Coord rw, rh;
798                                 const void *data;
799
800                                 DbgPrint("Part loading is not supported\n");
801                                 ee = ecore_evas_buffer_new(part_w, part_h);
802                                 if (!ee) {
803                                         ErrPrint("Failed to create a EE\n");
804                                         evas_object_del(img);
805                                         return LB_STATUS_ERROR_FAULT;
806                                 }
807
808                                 ecore_evas_alpha_set(ee, EINA_TRUE);
809
810                                 e = ecore_evas_get(ee);
811                                 if (!e) {
812                                         ErrPrint("Unable to get Evas\n");
813                                         ecore_evas_free(ee);
814                                         evas_object_del(img);
815                                         return LB_STATUS_ERROR_FAULT;
816                                 }
817
818                                 src_img = evas_object_image_filled_add(e);
819                                 if (!src_img) {
820                                         ErrPrint("Unable to add an image\n");
821                                         ecore_evas_free(ee);
822                                         evas_object_del(img);
823                                         return LB_STATUS_ERROR_FAULT;
824                                 }
825
826                                 evas_object_image_alpha_set(src_img, EINA_TRUE);
827                                 evas_object_image_colorspace_set(src_img, EVAS_COLORSPACE_ARGB8888);
828                                 evas_object_image_smooth_scale_set(src_img, EINA_TRUE);
829                                 evas_object_image_load_orientation_set(src_img, img_opt.orient);
830                                 evas_object_image_file_set(src_img, path, NULL);
831                                 err = evas_object_image_load_error_get(src_img);
832                                 if (err != EVAS_LOAD_ERROR_NONE) {
833                                         ErrPrint("Load error: %s\n", evas_load_error_str(err));
834                                         evas_object_del(src_img);
835                                         ecore_evas_free(ee);
836                                         evas_object_del(img);
837                                         return LB_STATUS_ERROR_IO;
838                                 }
839                                 evas_object_image_size_get(src_img, &rw, &rh);
840                                 evas_object_image_fill_set(src_img, 0, 0, rw, rh);
841                                 evas_object_resize(src_img, w, h);
842                                 evas_object_move(src_img, -(w - part_w) / 2, -(h - part_h) / 2);
843                                 evas_object_show(src_img);
844
845                                 data = ecore_evas_buffer_pixels_get(ee);
846                                 if (!data) {
847                                         ErrPrint("Unable to get pixels\n");
848                                         evas_object_del(src_img);
849                                         ecore_evas_free(ee);
850                                         evas_object_del(img);
851                                         return LB_STATUS_ERROR_IO;
852                                 }
853
854                                 e = evas_object_evas_get(img);
855                                 evas_object_del(img);
856                                 img = evas_object_image_filled_add(e);
857                                 if (!img) {
858                                         evas_object_del(src_img);
859                                         ecore_evas_free(ee);
860                                         return LB_STATUS_ERROR_MEMORY;
861                                 }
862
863                                 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
864                                 evas_object_image_smooth_scale_set(img, EINA_TRUE);
865                                 evas_object_image_alpha_set(img, EINA_TRUE);
866                                 evas_object_image_data_set(img, NULL);
867                                 evas_object_image_size_set(img, part_w, part_h);
868                                 evas_object_resize(img, part_w, part_h);
869                                 evas_object_image_data_copy_set(img, (void *)data);
870                                 evas_object_image_fill_set(img, 0, 0, part_w, part_h);
871                                 evas_object_image_data_update_add(img, 0, 0, part_w, part_h);
872
873                                 evas_object_del(src_img);
874                                 ecore_evas_free(ee);
875
876                                 apply_shadow_effect(&img_opt, img);
877                         }
878                 } else if (img_opt.fill == FILL_IN_SIZE) {
879                         Evas_Coord part_w;
880                         Evas_Coord part_h;
881
882                         if (img_opt.width >= 0 && img_opt.height >= 0) {
883                                 part_w = img_opt.width * elm_config_scale_get();
884                                 part_h = img_opt.height * elm_config_scale_get();
885                         } else {
886                                 part_w = 0;
887                                 part_h = 0;
888                                 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
889                         }
890                         DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
891
892                         if (part_w > w || part_h > h) {
893                                 double fw;
894                                 double fh;
895
896                                 fw = (double)part_w / (double)w;
897                                 fh = (double)part_h / (double)h;
898
899                                 if (fw > fh) {
900                                         w = part_w;
901                                         h = (double)h * fw;
902                                 } else {
903                                         h = part_h;
904                                         w = (double)w * fh;
905                                 }
906                         }
907                         DbgPrint("Size: %dx%d\n", w, h);
908                         evas_object_image_fill_set(img, 0, 0, part_w, part_h);
909                         evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
910                         evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
911                 } else {
912                         evas_object_image_fill_set(img, 0, 0, w, h);
913                         evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
914                         evas_object_size_hint_aspect_set(img, EVAS_ASPECT_CONTROL_BOTH, w, h);
915                 }
916         } else {
917                 if (img_opt.width >= 0 && img_opt.height >= 0) {
918                         w = img_opt.width;
919                         h = img_opt.height;
920                         DbgPrint("Using given image size: %dx%d\n", w, h);
921                 }
922
923                 evas_object_image_fill_set(img, 0, 0, w, h);
924                 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
925                 evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
926                 evas_object_image_filled_set(img, EINA_TRUE);
927         }
928
929
930         /*!
931          * \note
932          * object will be shown by below statement automatically
933          */
934         DbgPrint("%s part swallow image %p (%dx%d)\n", part, img, w, h);
935         elm_object_part_content_set(edje, part, img);
936
937         /*!
938          * \note
939          * This object is not registered as an access object.
940          * So the developer should add it to access list manually, using DESC_ACCESS block.
941          */
942         return LB_STATUS_SUCCESS;
943 }
944
945 static void script_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
946 {
947         struct info *handle = data;
948         Evas_Coord w;
949         Evas_Coord h;
950         Evas_Coord px = 0;
951         Evas_Coord py = 0;
952         Evas_Coord pw = 0;
953         Evas_Coord ph = 0;
954         double sx;
955         double sy;
956         double ex;
957         double ey;
958
959         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
960         edje_object_part_geometry_get(elm_layout_edje_get(obj), source, &px, &py, &pw, &ph);
961
962         sx = ex = 0.0f;
963         if (w) {
964                 sx = (double)px / (double)w;
965                 ex = (double)(px + pw) / (double)w;
966         }
967
968         sy = ey = 0.0f;
969         if (h) {
970                 sy = (double)py / (double)h;
971                 ey = (double)(py + ph) / (double)h;
972         }
973
974         DbgPrint("[%s] [%s]\n", emission, source);
975
976         script_buffer_signal_emit(handle->buffer_handle, source, emission, sx, sy, ex, ey);
977 }
978
979 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
980 {
981         struct info *handle = _info;
982         struct obj_info *obj_info;
983         struct obj_info *parent_obj_info;
984         struct child *child;
985
986         handle->obj_list = eina_list_remove(handle->obj_list, obj);
987
988         obj_info = evas_object_data_get(obj, "obj_info");
989         if (!obj_info) {
990                 ErrPrint("Object info is not valid\n");
991                 return;
992         }
993
994         elm_object_signal_callback_del(obj, "*", "*", script_signal_cb);
995
996         DbgPrint("delete object %s %p\n", obj_info->id, obj);
997         if (obj_info->parent == obj) {
998                 DbgPrint("Parent EDJE\n");
999         } else if (obj_info->parent) {
1000                 Eina_List *l;
1001                 Eina_List *n;
1002
1003                 parent_obj_info = evas_object_data_get(obj_info->parent, "obj_info");
1004                 if (parent_obj_info) {
1005                         EINA_LIST_FOREACH_SAFE(parent_obj_info->children, l, n, child) {
1006                                 if (child->obj != obj) {
1007                                         continue;
1008                                 }
1009
1010                                 /*!
1011                                  * \note
1012                                  * If this code is executed,
1013                                  * The parent is not deleted by desc, this object is deleted by itself.
1014                                  * It is not possible, but we care it.
1015                                  */
1016                                 DbgPrint("Children is updated: %s (%s)\n", child->part, parent_obj_info->id);
1017                                 parent_obj_info->children = eina_list_remove(parent_obj_info->children, child);
1018                                 free(child->part);
1019                                 free(child);
1020                                 break;
1021                         }
1022
1023                         if (!parent_obj_info->children && parent_obj_info->delete_me == 1) {
1024                                 DbgPrint("Children is cleared: %s (by a child)\n", parent_obj_info->id);
1025                                 evas_object_data_del(obj_info->parent, "obj_info");
1026                                 free(parent_obj_info->id);
1027                                 free(parent_obj_info);
1028                         }
1029                 }
1030         } else {
1031                 DbgPrint("obj_info->parent is NULL (skipped)\n");
1032         }
1033
1034         if (!obj_info->children) {
1035                 DbgPrint("Children is cleared: %s\n", obj_info->id);
1036                 evas_object_data_del(obj, "obj_info");
1037                 free(obj_info->id);
1038                 free(obj_info);
1039         } else {
1040                 DbgPrint("Children is remained: %s\n", obj_info->id);
1041                 obj_info->delete_me = 1;
1042         }
1043 }
1044
1045 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
1046 {
1047         Evas_Object *o, *ho;
1048
1049         o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
1050         if (!o) {
1051                 return NULL;      
1052         }
1053
1054         ho = evas_object_data_get(o, "_elm_access_target");
1055         return ho;
1056 }
1057
1058 /*!
1059         LB_ACCESS_HIGHLIGHT             0
1060         LB_ACCESS_HIGHLIGHT_NEXT        1
1061         LB_ACCESS_HIGHLIGHT_PREV        2
1062         LB_ACCESS_ACTIVATE              3
1063         LB_ACCESS_ACTION                4
1064         LB_ACCESS_SCROLL                5
1065 */
1066 PUBLIC int script_feed_event(void *h, int event_type, int x, int y, int down, unsigned int keycode, double timestamp)
1067 {
1068         struct info *handle = h;
1069         Evas_Object *edje;
1070         struct obj_info *obj_info;
1071         int ret = LB_STATUS_SUCCESS;
1072
1073         edje = find_edje(handle, NULL); /*!< Get the base layout */
1074         if (!edje) {
1075                 ErrPrint("Base layout is not exist\n");
1076                 return LB_STATUS_ERROR_NOT_EXIST;
1077         }
1078
1079         obj_info = evas_object_data_get(edje, "obj_info");
1080         if (!obj_info) {
1081                 ErrPrint("Object info is not valid\n");
1082                 return LB_STATUS_ERROR_INVALID;
1083         }
1084
1085         if (event_type & LB_SCRIPT_ACCESS_EVENT) {
1086                 Elm_Access_Action_Info info;
1087                 Elm_Access_Action_Type action;
1088
1089                 memset(&info, 0, sizeof(info));
1090
1091                 if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT) == LB_SCRIPT_ACCESS_HIGHLIGHT) {
1092                         action = ELM_ACCESS_ACTION_HIGHLIGHT;
1093                         info.x = x;
1094                         info.y = y;
1095                         ret = elm_access_action(edje, action, &info);
1096                         DbgPrint("ACCESS_HIGHLIGHT: %dx%d returns %d\n", x, y, ret);
1097                         if (ret == EINA_TRUE) {
1098                                 if (!get_highlighted_object(edje)) {
1099                                         ErrPrint("Highlighted object is not found\n");
1100                                         ret = LB_ACCESS_STATUS_ERROR;
1101                                 } else {
1102                                         DbgPrint("Highlighted object is found\n");
1103                                         ret = LB_ACCESS_STATUS_DONE;
1104                                 }
1105                         } else {
1106                                 ErrPrint("Action error\n");
1107                                 ret = LB_ACCESS_STATUS_ERROR;
1108                         }
1109                 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) == LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) {
1110                         action = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
1111                         info.highlight_cycle = EINA_FALSE;
1112                         ret = elm_access_action(edje, action, &info);
1113                         DbgPrint("ACCESS_HIGHLIGHT_NEXT, returns %d\n", ret);
1114                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
1115                 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) == LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) {
1116                         action = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
1117                         info.highlight_cycle = EINA_FALSE;
1118                         ret = elm_access_action(edje, action, &info);
1119                         DbgPrint("ACCESS_HIGHLIGHT_PREV, returns %d\n", ret);
1120                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
1121                 } else if ((event_type & LB_SCRIPT_ACCESS_ACTIVATE) == LB_SCRIPT_ACCESS_ACTIVATE) {
1122                         action = ELM_ACCESS_ACTION_ACTIVATE;
1123                         ret = elm_access_action(edje, action, &info);
1124                         DbgPrint("ACCESS_ACTIVATE, returns %d\n", ret);
1125                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1126                 } else if ((event_type & LB_SCRIPT_ACCESS_ACTION) == LB_SCRIPT_ACCESS_ACTION) {
1127                         if (down == 0) {
1128                                 action = ELM_ACCESS_ACTION_UP;
1129                                 ret = elm_access_action(edje, action, &info);
1130                                 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
1131                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1132                         } else if (down == 1) {
1133                                 action = ELM_ACCESS_ACTION_DOWN;
1134                                 ret = elm_access_action(edje, action, &info);
1135                                 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
1136                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1137                         } else {
1138                                 ErrPrint("Invalid access event\n");
1139                                 ret = LB_ACCESS_STATUS_ERROR;
1140                         }
1141                 } else if ((event_type & LB_SCRIPT_ACCESS_SCROLL) == LB_SCRIPT_ACCESS_SCROLL) {
1142                         action = ELM_ACCESS_ACTION_SCROLL;
1143                         info.x = x;
1144                         info.y = y;
1145                         switch (down) {
1146                         case 0:
1147                                 info.mouse_type = 0;
1148                                 ret = elm_access_action(edje, action, &info);
1149                                 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1150                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1151                                 break;
1152                         case -1:
1153                                 info.mouse_type = 1;
1154                                 ret = elm_access_action(edje, action, &info);
1155                                 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1156                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1157                                 break;
1158                         case 1:
1159                                 info.mouse_type = 2;
1160                                 ret = elm_access_action(edje, action, &info);
1161                                 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1162                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1163                                 break;
1164                         default:
1165                                 ret = LB_ACCESS_STATUS_ERROR;
1166                                 break;
1167                         }
1168                 } else if ((event_type & LB_SCRIPT_ACCESS_UNHIGHLIGHT) == LB_SCRIPT_ACCESS_UNHIGHLIGHT) {
1169                         action = ELM_ACCESS_ACTION_UNHIGHLIGHT;
1170                         ret = elm_access_action(edje, action, &info);
1171                         DbgPrint("ACCESS_UNHIGHLIGHT, returns %d\n", ret);
1172                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1173                 } else {
1174                         DbgPrint("Invalid event\n");
1175                         ret = LB_ACCESS_STATUS_ERROR;
1176                 }
1177
1178         } else if (event_type & LB_SCRIPT_MOUSE_EVENT) {
1179                 double cur_timestamp;
1180                 unsigned int flags;
1181
1182 #if defined(_USE_ECORE_TIME_GET)
1183                 cur_timestamp = ecore_time_get();
1184 #else
1185                 struct timeval tv;
1186                 if (gettimeofday(&tv, NULL) < 0) {
1187                         ErrPrint("Failed to get time\n");
1188                         cur_timestamp = 0.0f;
1189                 } else {
1190                         cur_timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
1191                 }
1192 #endif
1193                 if (cur_timestamp - timestamp > 0.1f && handle->is_mouse_down == 0) {
1194                         DbgPrint("Discard lazy event : %lf\n", cur_timestamp - timestamp);
1195                         return LB_STATUS_SUCCESS;
1196                 }
1197
1198                 switch (event_type) {
1199                 case LB_SCRIPT_MOUSE_DOWN:
1200                         if (handle->is_mouse_down == 0) {
1201                                 evas_event_feed_mouse_move(handle->e, x, y, timestamp * 1000, NULL);
1202                                 evas_event_feed_mouse_down(handle->e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
1203                                 handle->is_mouse_down = 1;
1204                         }
1205                         break;
1206                 case LB_SCRIPT_MOUSE_MOVE:
1207                         evas_event_feed_mouse_move(handle->e, x, y, timestamp * 1000, NULL);
1208                         break;
1209                 case LB_SCRIPT_MOUSE_UP:
1210                         if (handle->is_mouse_down == 1) {
1211                                 evas_event_feed_mouse_move(handle->e, x, y, timestamp * 1000, NULL);
1212                                 evas_event_feed_mouse_up(handle->e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
1213                                 handle->is_mouse_down = 0;
1214                         }
1215
1216                         flags = evas_event_default_flags_get(handle->e);
1217                         flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
1218                         flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
1219                         evas_event_default_flags_set(handle->e, flags);
1220                         break;
1221                 case LB_SCRIPT_MOUSE_IN:
1222                         evas_event_feed_mouse_in(handle->e, timestamp * 1000, NULL);
1223                         break;
1224                 case LB_SCRIPT_MOUSE_OUT:
1225                         evas_event_feed_mouse_out(handle->e, timestamp * 1000, NULL);
1226                         break;
1227                 case LB_SCRIPT_MOUSE_ON_SCROLL:
1228                         flags = evas_event_default_flags_get(handle->e);
1229                         flags |= EVAS_EVENT_FLAG_ON_SCROLL;
1230                         evas_event_default_flags_set(handle->e, flags);
1231                         break;
1232                 case LB_SCRIPT_MOUSE_ON_HOLD:   // To cancel the clicked, enable this
1233                         flags = evas_event_default_flags_get(handle->e);
1234                         flags |= EVAS_EVENT_FLAG_ON_HOLD;
1235                         evas_event_default_flags_set(handle->e, flags);
1236                         break;
1237                 case LB_SCRIPT_MOUSE_OFF_SCROLL:
1238                         flags = evas_event_default_flags_get(handle->e);
1239                         flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
1240                         evas_event_default_flags_set(handle->e, flags);
1241                         break;
1242                 case LB_SCRIPT_MOUSE_OFF_HOLD:
1243                         flags = evas_event_default_flags_get(handle->e);
1244                         flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
1245                         evas_event_default_flags_set(handle->e, flags);
1246                         break;
1247                 default:
1248                         return LB_STATUS_ERROR_INVALID;
1249                 }
1250         } else if (event_type & LB_SCRIPT_KEY_EVENT) {
1251                 const char *keyname = "";
1252                 const char *key = "";
1253                 const char *string = "";
1254                 const char *compose = "";
1255
1256                 switch (event_type) {
1257                 case LB_SCRIPT_KEY_DOWN:
1258                         evas_event_feed_key_down(handle->e, keyname, key, string, compose, timestamp * 1000, NULL);
1259                         ret = LB_KEY_STATUS_DONE;
1260                         /*!
1261                          * \TODO
1262                          * If the keyname == RIGHT, Need to check that
1263                          * Does it reach to the last focusable object?
1264                          */
1265
1266                         /*!
1267                          * if (REACH to the LAST) {
1268                          *    ret = LB_KEY_STATUS_LAST;
1269                          * } else {
1270                          *    ret = LB_KEY_STATUS_DONE;
1271                          * }
1272                          *
1273                          * if (REACH to the FIRST) {
1274                          *    ret = LB_KEY_STATUS_FIRST;
1275                          * } else {
1276                          *    ret = LB_KEY_STATUS_DONE;
1277                          * }
1278                          */
1279                         break;
1280                 case LB_SCRIPT_KEY_UP:
1281                         evas_event_feed_key_up(handle->e, keyname, key, string, compose, timestamp * 1000, NULL);
1282                         ret = LB_KEY_STATUS_DONE;
1283                         break;
1284                 case LB_SCRIPT_KEY_FOCUS_IN:
1285                         // evas_event_callback_call(handle->e, EVAS_CALLBACK_CANVAS_FOCUS_IN, NULL);
1286                         ret = LB_KEY_STATUS_DONE;
1287                         break;
1288                 case LB_SCRIPT_KEY_FOCUS_OUT:
1289                         // evas_event_callback_call(handle->e, EVAS_CALLBACK_CANVAS_FOCUS_OUT, NULL);
1290                         ret = LB_KEY_STATUS_DONE;
1291                         break;
1292                 default:
1293                         DbgPrint("Event is not implemented\n");
1294                         ret = LB_KEY_STATUS_ERROR;
1295                         break;
1296                 }
1297         }
1298
1299         return ret;
1300 }
1301
1302 PUBLIC int script_update_script(void *h, const char *src_id, const char *target_id, const char *part, const char *path, const char *group)
1303 {
1304         struct info *handle = h;
1305         Evas_Object *edje;
1306         Evas_Object *obj;
1307         struct obj_info *obj_info;
1308         struct child *child;
1309         char _target_id[32];
1310
1311         edje = find_edje(handle, src_id);
1312         if (!edje) {
1313                 ErrPrint("Edje is not exists (%s)\n", src_id);
1314                 return LB_STATUS_ERROR_NOT_EXIST;
1315         }
1316
1317         obj_info = evas_object_data_get(edje, "obj_info");
1318         if (!obj_info) {
1319                 ErrPrint("Object info is not valid\n");
1320                 return LB_STATUS_ERROR_INVALID;
1321         }
1322
1323         obj = elm_object_part_content_unset(edje, part);
1324         if (obj) {
1325                 DbgPrint("delete object %s %p\n", part, obj);
1326                 /*!
1327                  * \note
1328                  * This will call the edje_del_cb.
1329                  * It will delete all access objects
1330                  */
1331                 evas_object_del(obj);
1332         }
1333
1334         if (!path || !strlen(path) || access(path, R_OK) != 0) {
1335                 DbgPrint("SKIP - Path: [%s]\n", path);
1336                 return LB_STATUS_SUCCESS;
1337         }
1338
1339         if (!target_id) {
1340                 if (find_edje(handle, part)) {
1341                         double timestamp;
1342
1343                         do {
1344 #if defined(_USE_ECORE_TIME_GET)
1345                                 timestamp = ecore_time_get();
1346 #else
1347                                 struct timeval tv;
1348                                 if (gettimeofday(&tv, NULL) < 0) {
1349                                         static int local_idx = 0;
1350                                         timestamp = (double)(local_idx++);
1351                                 } else {
1352                                         timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
1353                                 }
1354 #endif
1355
1356                                 snprintf(_target_id, sizeof(_target_id), "%lf", timestamp);
1357                         } while (find_edje(handle, _target_id));
1358
1359                         target_id = _target_id;
1360                 } else {
1361                         target_id = part;
1362                 }
1363
1364                 DbgPrint("Anonymouse target id: %s\n", target_id);
1365         }
1366
1367         obj = elm_layout_add(edje);
1368         if (!obj) {
1369                 ErrPrint("Failed to add a new edje object\n");
1370                 return LB_STATUS_ERROR_FAULT;
1371         }
1372
1373         edje_object_scale_set(elm_layout_edje_get(obj), elm_config_scale_get());
1374
1375         if (!elm_layout_file_set(obj, path, group)) {
1376                 int err;
1377                 err = edje_object_load_error_get(elm_layout_edje_get(obj));
1378                 if (err != EDJE_LOAD_ERROR_NONE) {
1379                         ErrPrint("Could not load %s from %s: %s\n", group, path, edje_load_error_str(err));
1380                 }
1381                 evas_object_del(obj);
1382                 return LB_STATUS_ERROR_IO;
1383         }
1384
1385         evas_object_show(obj);
1386
1387         obj_info = calloc(1, sizeof(*obj_info));
1388         if (!obj_info) {
1389                 ErrPrint("Failed to add a obj_info\n");
1390                 evas_object_del(obj);
1391                 return LB_STATUS_ERROR_MEMORY;
1392         }
1393
1394         obj_info->id = strdup(target_id);
1395         if (!obj_info->id) {
1396                 ErrPrint("Failed to add a obj_info\n");
1397                 free(obj_info);
1398                 evas_object_del(obj);
1399                 return LB_STATUS_ERROR_MEMORY;
1400         }
1401
1402         obj_info->parent = edje;
1403
1404         child = malloc(sizeof(*child));
1405         if (!child) {
1406                 ErrPrint("Error: %s\n", strerror(errno));
1407                 free(obj_info->id);
1408                 free(obj_info);
1409                 evas_object_del(obj);
1410                 return LB_STATUS_ERROR_MEMORY;
1411         }
1412
1413         child->part = strdup(part);
1414         if (!child->part) {
1415                 ErrPrint("Error: %s\n", strerror(errno));
1416                 free(child);
1417                 free(obj_info->id);
1418                 free(obj_info);
1419                 evas_object_del(obj);
1420                 return LB_STATUS_ERROR_MEMORY;
1421         }
1422
1423         child->obj = obj;
1424
1425         evas_object_data_set(obj, "obj_info", obj_info);
1426         evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1427         elm_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
1428         handle->obj_list = eina_list_append(handle->obj_list, obj);
1429
1430         DbgPrint("%s part swallow edje %p\n", part, obj);
1431         elm_object_part_content_set(edje, part, obj);
1432
1433         obj_info = evas_object_data_get(edje, "obj_info");
1434         obj_info->children = eina_list_append(obj_info->children, child);
1435
1436         return LB_STATUS_SUCCESS;
1437 }
1438
1439 PUBLIC int script_update_signal(void *h, const char *id, const char *part, const char *signal)
1440 {
1441         struct info *handle = h;
1442         Evas_Object *edje;
1443
1444         edje = find_edje(handle, id);
1445         if (!edje) {
1446                 return LB_STATUS_ERROR_NOT_EXIST;
1447         }
1448
1449         elm_object_signal_emit(edje, signal, part);
1450         return LB_STATUS_SUCCESS;
1451 }
1452
1453 PUBLIC int script_update_drag(void *h, const char *id, const char *part, double x, double y)
1454 {
1455         struct info *handle = h;
1456         Evas_Object *edje;
1457
1458         edje = find_edje(handle, id);
1459         if (!edje) {
1460                 return LB_STATUS_ERROR_NOT_EXIST;
1461         }
1462
1463         edje_object_part_drag_value_set(elm_layout_edje_get(edje), part, x, y);
1464         return LB_STATUS_SUCCESS;
1465 }
1466
1467 PUBLIC int script_update_size(void *han, const char *id, int w, int h)
1468 {
1469         struct info *handle = han;
1470         Evas_Object *edje;
1471
1472         edje = find_edje(handle, id);
1473         if (!edje) {
1474                 return LB_STATUS_ERROR_NOT_EXIST;
1475         }
1476
1477         if (!id) {
1478                 /*!
1479                  * \note
1480                  * Need to resize the canvas too
1481                  */
1482                 ecore_evas_resize(handle->ee, w, h);
1483         }
1484
1485         DbgPrint("Resize object to %dx%d\n", w, h);
1486         evas_object_resize(edje, w, h);
1487         return LB_STATUS_SUCCESS;
1488 }
1489
1490 PUBLIC int script_update_category(void *h, const char *id, const char *category)
1491 {
1492         struct info *handle = h;
1493
1494         if (handle->category) {
1495                 free(handle->category);
1496                 handle->category = NULL;
1497         }
1498
1499         if (!category) {
1500                 return LB_STATUS_SUCCESS;
1501         }
1502
1503         handle->category = strdup(category);
1504         if (!handle->category) {
1505                 ErrPrint("Error: %s\n", strerror(errno));
1506                 return LB_STATUS_ERROR_MEMORY;
1507         }
1508
1509         return LB_STATUS_SUCCESS;
1510 }
1511
1512 PUBLIC void *script_create(void *buffer_handle, const char *file, const char *group)
1513 {
1514         struct info *handle;
1515
1516         handle = calloc(1, sizeof(*handle));
1517         if (!handle) {
1518                 ErrPrint("Error: %s\n", strerror(errno));
1519                 return NULL;
1520         }
1521
1522         handle->file = strdup(file);
1523         if (!handle->file) {
1524                 ErrPrint("Error: %s\n", strerror(errno));
1525                 free(handle);
1526                 return NULL;
1527         }
1528
1529         handle->group = strdup(group);
1530         if (!handle->group) {
1531                 ErrPrint("Error: %s\n", strerror(errno));
1532                 free(handle->file);
1533                 free(handle);
1534                 return NULL;
1535         }
1536
1537         handle->buffer_handle = buffer_handle;
1538
1539         s_info.handle_list = eina_list_append(s_info.handle_list, handle);
1540
1541         return handle;
1542 }
1543
1544 PUBLIC int script_destroy(void *_handle)
1545 {
1546         struct info *handle;
1547         Evas_Object *edje;
1548
1549         handle = _handle;
1550
1551         if (!eina_list_data_find(s_info.handle_list, handle)) {
1552                 DbgPrint("Not found (already deleted?)\n");
1553                 return LB_STATUS_ERROR_NOT_EXIST;
1554         }
1555
1556         s_info.handle_list = eina_list_remove(s_info.handle_list, handle);
1557
1558         edje = eina_list_nth(handle->obj_list, 0);
1559         if (edje) {
1560                 evas_object_del(edje);
1561         }
1562
1563         DbgPrint("Release handle\n");
1564         free(handle->category);
1565         free(handle->file);
1566         free(handle->group);
1567         free(handle);
1568         return LB_STATUS_SUCCESS;
1569 }
1570
1571 static void sw_render_pre_cb(void *data, Evas *e, void *event_info)
1572 {
1573         struct info *handle = data;
1574
1575         if (handle->render_pre) {
1576                 handle->render_pre(handle->buffer_handle, handle->render_data);
1577         }
1578
1579         script_buffer_lock(handle->buffer_handle);
1580
1581         if (s_info.premultiplied) {
1582                 int w;
1583                 int h;
1584
1585                 script_buffer_get_size(handle->buffer_handle, &w, &h);
1586                 evas_damage_rectangle_add(handle->e, 0, 0, w, h);
1587         }
1588 }
1589
1590 static void sw_render_post_cb(void *data, Evas *e, void *event_info)
1591 {
1592         struct info *handle = data;
1593
1594         if (s_info.premultiplied) {
1595                 void *canvas;
1596                 int x, y, w, h;
1597
1598                 // Get a pointer of a buffer of the virtual canvas
1599                 canvas = (void *)ecore_evas_buffer_pixels_get(handle->ee);
1600                 if (!canvas) {
1601                         ErrPrint("Failed to get pixel canvas\n");
1602                         return;
1603                 }
1604
1605                 ecore_evas_geometry_get(handle->ee, &x, &y, &w, &h);
1606                 evas_data_argb_unpremul(canvas, w * h);
1607         }
1608
1609         script_buffer_unlock(handle->buffer_handle);
1610
1611         if (handle->render_post) {
1612                 handle->render_post(handle->buffer_handle, handle->render_data);
1613         }
1614 }
1615
1616 static void render_pre_cb(void *data, Evas *e, void *event_info)
1617 {
1618         struct info *handle = data;
1619         void *canvas;
1620
1621         canvas = script_buffer_pixmap_acquire_buffer(handle->buffer_handle);
1622         if (!canvas) {
1623                 ErrPrint("Acquired buffer is NULL\n");
1624         }
1625
1626         sw_render_pre_cb(data, handle->e, event_info);
1627 }
1628
1629 static void render_post_cb(void *data, Evas *e, void *event_info)
1630 {
1631         struct info *handle = data;
1632         void *canvas;
1633
1634         sw_render_post_cb(data, handle->e, event_info);
1635         canvas = script_buffer_pixmap_buffer(handle->buffer_handle);
1636         if (!canvas) {
1637                 ErrPrint("Acquired buffer is NULL\n");
1638         } else {
1639                 script_buffer_pixmap_release_buffer(canvas);
1640         }
1641 }
1642
1643 #if AUTO_ALIGN
1644 static void *alloc_fb(void *data, int size)
1645 {
1646         struct info *handle = data;
1647
1648         if (script_buffer_load(handle->buffer_handle) < 0) {
1649                 ErrPrint("Failed to load buffer handler\n");
1650                 return NULL;
1651         }
1652
1653         return script_buffer_fb(handle->buffer_handle);
1654 }
1655 #else
1656 static void *alloc_fb(void *data, int size, int *stride, int *bpp)
1657 {
1658         struct info *handle = data;
1659         int _stride;
1660         int _bpp;
1661
1662         _bpp = script_buffer_pixels(handle->buffer_handle);
1663         if (_bpp < 0) {
1664                 ErrPrint("Failed to get pixel size, fallback to 4\n");
1665                 _bpp = sizeof(int);
1666         }
1667
1668         _stride = script_buffer_stride(handle->buffer_handle);
1669         if (_stride < 0) {
1670                 int w = 0;
1671
1672                 ecore_evas_geometry_get(handle->ee, NULL, NULL, &w, NULL);
1673
1674                 _stride = w * _bpp;
1675                 ErrPrint("Failed to get stride info, fallback to %d\n", _stride);
1676         }
1677
1678         *stride = _stride;
1679         *bpp = _bpp;
1680
1681         if (script_buffer_load(handle->buffer_handle) < 0) {
1682                 ErrPrint("Failed to load buffer handler\n");
1683                 return NULL;
1684         }
1685
1686         return script_buffer_fb(handle->buffer_handle);
1687 }
1688 #endif
1689
1690 static void free_fb(void *data, void *ptr)
1691 {
1692         struct info *handle = data;
1693
1694         if (!handle->buffer_handle) {
1695                 ErrPrint("Buffer is not valid (maybe already released)\n");
1696                 return;
1697         }
1698
1699         if (script_buffer_fb(handle->buffer_handle) != ptr) {
1700                 ErrPrint("Buffer pointer is not matched\n");
1701         }
1702
1703         (void)script_buffer_unload(handle->buffer_handle);
1704 }
1705
1706 static int destroy_ecore_evas(struct info *handle)
1707 {
1708         if (!handle->ee) {
1709                 return LB_STATUS_SUCCESS;
1710         }
1711         ecore_evas_free(handle->ee);
1712         handle->ee = NULL;
1713         handle->e = NULL;
1714         return LB_STATUS_SUCCESS;
1715 }
1716
1717 static int create_ecore_evas(struct info *handle, int *w, int *h)
1718 {
1719         script_buffer_get_size(handle->buffer_handle, w, h);
1720         if (*w == 0 && *h == 0) {
1721                 ErrPrint("ZERO size FB accessed\n");
1722                 return LB_STATUS_ERROR_INVALID;
1723         }
1724
1725         if (handle->ee) {
1726                 int ow = 0;
1727                 int oh = 0;
1728
1729                 ecore_evas_geometry_get(handle->ee, NULL, NULL, &ow, &oh);
1730                 if (*w != ow || *h != oh) {
1731                         ErrPrint("EE exists, But different size - buffer_handle(%dx%d) -> ee(%dx%d)\n", ow, oh, *w, *h);
1732                         ecore_evas_resize(handle->ee, *w, *h);
1733                 }
1734
1735                 return LB_STATUS_SUCCESS;
1736         }
1737
1738 #if AUTO_ALIGN
1739         handle->ee = ecore_evas_buffer_allocfunc_new(*w, *h, alloc_fb, free_fb, handle);
1740         if (!handle->ee) {
1741                 ErrPrint("Failed to create a buffer\n");
1742                 return LB_STATUS_ERROR_FAULT;
1743         }
1744 #else
1745         handle->ee = ecore_evas_buffer_allocfunc_with_stride_new(*w, *h, alloc_fb, free_fb, handle);
1746         if (!handle->ee) {
1747                 ErrPrint("Failed to create a buffer\n");
1748                 return LB_STATUS_ERROR_FAULT;
1749         }
1750 #endif
1751
1752         handle->e = ecore_evas_get(handle->ee);
1753         if (!handle->e) {
1754                 ErrPrint("Failed to get an Evas\n");
1755                 ecore_evas_free(handle->ee);
1756                 handle->ee = NULL;
1757                 return LB_STATUS_ERROR_FAULT;
1758         }
1759
1760         if (script_buffer_type(handle->buffer_handle) == BUFFER_TYPE_PIXMAP) {
1761                 void *canvas;
1762
1763                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb, handle);
1764                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_POST, render_post_cb, handle);
1765
1766                 /*
1767                  * \note
1768                  * ecore_evas_alpha_set tries to access the canvas buffer.
1769                  * Without any render_pre/render_post callback.
1770                  */
1771                 canvas = script_buffer_pixmap_acquire_buffer(handle->buffer_handle);
1772                 if (!canvas) {
1773                         ErrPrint("Acquired buffer is NULL\n");
1774                 } else {
1775                         ecore_evas_alpha_set(handle->ee, EINA_TRUE);
1776                         script_buffer_pixmap_release_buffer(canvas);
1777                 }
1778         } else {
1779                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_PRE, sw_render_pre_cb, handle);
1780                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_POST, sw_render_post_cb, handle);
1781                 ecore_evas_alpha_set(handle->ee, EINA_TRUE);
1782         }
1783
1784         ecore_evas_manual_render_set(handle->ee, EINA_FALSE);
1785         ecore_evas_resize(handle->ee, *w, *h);
1786         ecore_evas_show(handle->ee);
1787         ecore_evas_activate(handle->ee);
1788
1789         return LB_STATUS_SUCCESS;
1790 }
1791
1792 PUBLIC int script_load(void *_handle, int (*render_pre)(void *buffer_handle, void *data), int (*render_post)(void *render_handle, void *data), void *data)
1793 {
1794         struct info *handle;
1795         Evas_Object *edje;
1796         struct obj_info *obj_info;
1797         int ret;
1798         int w;
1799         int h;
1800
1801         /*!
1802          * \TODO
1803          * Create "Ecore_Evas *"
1804          */
1805
1806         handle = _handle;
1807
1808         handle->render_pre = render_pre;
1809         handle->render_post = render_post;
1810         handle->render_data = data;
1811
1812         ret = create_ecore_evas(handle, &w, &h);
1813         if (ret < 0) {
1814                 return ret;
1815         }
1816
1817         obj_info = calloc(1, sizeof(*obj_info));
1818         if (!obj_info) {
1819                 ErrPrint("Heap: %s\n", strerror(errno));
1820                 destroy_ecore_evas(handle);
1821                 return LB_STATUS_ERROR_MEMORY;
1822         }
1823
1824         obj_info->parent = evas_object_rectangle_add(handle->e);
1825         if (!obj_info->parent) {
1826                 ErrPrint("Unable to create a parent box\n");
1827                 free(obj_info);
1828                 destroy_ecore_evas(handle);
1829                 return LB_STATUS_ERROR_FAULT;
1830         }
1831
1832         edje = elm_layout_add(obj_info->parent);
1833         if (!edje) {
1834                 ErrPrint("Failed to create an edje object\n");
1835                 evas_object_del(obj_info->parent);
1836                 free(obj_info);
1837                 destroy_ecore_evas(handle);
1838                 return LB_STATUS_ERROR_FAULT;
1839         }
1840
1841         edje_object_scale_set(elm_layout_edje_get(edje), elm_config_scale_get());
1842
1843         if (!elm_layout_file_set(edje, handle->file, handle->group)) {
1844                 int err;
1845
1846                 err = edje_object_load_error_get(elm_layout_edje_get(edje));
1847                 if (err != EDJE_LOAD_ERROR_NONE) {
1848                         ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, edje_load_error_str(err));
1849                 }
1850                 evas_object_del(edje);
1851                 evas_object_del(obj_info->parent);
1852                 free(obj_info);
1853                 destroy_ecore_evas(handle);
1854                 return LB_STATUS_ERROR_IO;
1855         }
1856
1857         handle->parent = edje;
1858
1859         elm_object_signal_callback_add(edje, "*", "*", script_signal_cb, handle);
1860         evas_object_event_callback_add(edje, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1861         evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1862         evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1863         evas_object_resize(edje, w, h);
1864         evas_object_show(edje);
1865         evas_object_data_set(edje, "obj_info", obj_info);
1866
1867         handle->obj_list = eina_list_append(handle->obj_list, edje);
1868         return LB_STATUS_SUCCESS;
1869 }
1870
1871 PUBLIC int script_unload(void *_handle)
1872 {
1873         struct info *handle;
1874
1875         /*!
1876          * \TODO
1877          * Destroy "Ecore_Evas *"
1878          */
1879
1880         handle = _handle;
1881
1882         if (handle->parent) {
1883                 DbgPrint("Delete parent box\n");
1884                 evas_object_del(handle->parent);
1885         }
1886
1887         (void)destroy_ecore_evas(handle);
1888         return LB_STATUS_SUCCESS;
1889 }
1890
1891 static void access_cb(keynode_t *node, void *user_data)
1892 {
1893         int state;
1894
1895         if (!node) {
1896                 if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &state) != 0) {
1897                         ErrPrint("Idle lock state is not valid\n");
1898                         state = 0; /* DISABLED */
1899                 }
1900         } else {
1901                 state = vconf_keynode_get_bool(node);
1902         }
1903
1904         DbgPrint("ELM CONFIG ACCESS: %d\n", state);
1905         elm_config_access_set(state);
1906         s_info.access_on = state;
1907 }
1908
1909 static void update_font_cb(void *data)
1910 {
1911         elm_config_font_overlay_set(TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
1912         DbgPrint("Update text class %s (%s, %d)\n", TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
1913 }
1914
1915 static void font_changed_cb(keynode_t *node, void *user_data)
1916 {
1917         char *font_name;
1918
1919         evas_font_reinit();
1920
1921         if (s_info.font_name) {
1922                 font_name = vconf_get_str("db/setting/accessibility/font_name");
1923                 if (!font_name) {
1924                         ErrPrint("Invalid font name (NULL)\n");
1925                         return;
1926                 }
1927
1928                 if (!strcmp(s_info.font_name, font_name)) {
1929                         DbgPrint("Font is not changed (Old: %s(%p) <> New: %s(%p))\n", s_info.font_name, s_info.font_name, font_name, font_name);
1930                         free(font_name);
1931                         return;
1932                 }
1933
1934                 DbgPrint("Release old font name: %s(%p)\n", s_info.font_name, s_info.font_name);
1935                 free(s_info.font_name);
1936         } else {
1937                 int ret;
1938
1939                 /*!
1940                  * Get the first font name using system_settings API.
1941                  */
1942                 font_name = NULL;
1943                 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &font_name);
1944                 if (ret != SYSTEM_SETTINGS_ERROR_NONE || !font_name) {
1945                         ErrPrint("System setting get: %d, font_name[%p]\n", ret, font_name);
1946                         return;
1947                 }
1948         }
1949
1950         s_info.font_name = font_name;
1951         DbgPrint("Font name is changed to %s(%p)\n", s_info.font_name, s_info.font_name);
1952
1953         /*!
1954          * \NOTE
1955          * Try to update all liveboxes
1956          */
1957         update_font_cb(NULL);
1958 }
1959
1960 static inline int convert_font_size(int size)
1961 {
1962         switch (size) {
1963         case SYSTEM_SETTINGS_FONT_SIZE_SMALL:
1964                 size = -80;
1965                 break;
1966         case SYSTEM_SETTINGS_FONT_SIZE_NORMAL:
1967                 size = -100;
1968                 break;
1969         case SYSTEM_SETTINGS_FONT_SIZE_LARGE:
1970                 size = -150;
1971                 break;
1972         case SYSTEM_SETTINGS_FONT_SIZE_HUGE:
1973                 size = -190;
1974                 break;
1975         case SYSTEM_SETTINGS_FONT_SIZE_GIANT:
1976                 size = -250;
1977                 break;
1978         default:
1979                 size = -100;
1980                 break;
1981         }
1982
1983         DbgPrint("Return size: %d\n", size);
1984         return size;
1985 }
1986
1987 static void font_size_cb(system_settings_key_e key, void *user_data)
1988 {
1989         int size;
1990
1991         if (system_settings_get_value_int(SYSTEM_SETTINGS_KEY_FONT_SIZE, &size) != SYSTEM_SETTINGS_ERROR_NONE) {
1992                 return;
1993         }
1994
1995         size = convert_font_size(size);
1996
1997         if (size == s_info.font_size) {
1998                 DbgPrint("Font size is not changed\n");
1999                 return;
2000         }
2001
2002         s_info.font_size = size;
2003         DbgPrint("Font size is changed to %d, but don't update the font info\n", size);
2004 }
2005
2006 PUBLIC int script_init(double scale, int premultiplied)
2007 {
2008         int ret;
2009         char *argv[] = {
2010                 "livebox.edje",
2011                 NULL,
2012         };
2013
2014         s_info.premultiplied = premultiplied;
2015
2016         /* ecore is already initialized */
2017         elm_init(1, argv);
2018         elm_config_scale_set(scale);
2019         DbgPrint("Scale is updated: %lf\n", scale);
2020
2021         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb, NULL);
2022         if (ret < 0) {
2023                 DbgPrint("TTS changed: %d\n", ret);
2024         }
2025
2026         ret = vconf_notify_key_changed("db/setting/accessibility/font_name", font_changed_cb, NULL);
2027         DbgPrint("System font is changed: %d\n", ret);
2028         
2029         ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, font_size_cb, NULL);
2030         DbgPrint("System font size is changed: %d\n", ret);
2031
2032         access_cb(NULL, NULL);
2033         font_changed_cb(NULL, NULL);
2034         font_size_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, NULL);
2035         return LB_STATUS_SUCCESS;
2036 }
2037
2038 PUBLIC int script_fini(void)
2039 {
2040         int ret;
2041         Eina_List *l;
2042         Eina_List *n;
2043         struct info *handle;
2044
2045         EINA_LIST_FOREACH_SAFE(s_info.handle_list, l, n, handle) {
2046                 script_destroy(handle);
2047         }
2048
2049         ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE);
2050         if (ret < 0) {
2051                 DbgPrint("Unset font size change event callback: %d\n", ret);
2052         }
2053
2054         ret = vconf_ignore_key_changed("db/setting/accessibility/font_name", font_changed_cb);
2055         if (ret < 0) {
2056                 DbgPrint("Unset font name change event callback: %d\n", ret);
2057         }
2058
2059         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb);
2060         if (ret < 0) {
2061                 DbgPrint("Unset tts: %d\n", ret);
2062         }
2063
2064         elm_shutdown();
2065
2066         free(s_info.font_name);
2067         s_info.font_name = NULL;
2068         return LB_STATUS_SUCCESS;
2069 }
2070
2071 /* End of a file */