Remove unnecessary package dependencies
[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         script_buffer_signal_emit(handle->buffer_handle, source, emission, sx, sy, ex, ey);
975 }
976
977 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
978 {
979         struct info *handle = _info;
980         struct obj_info *obj_info;
981         struct obj_info *parent_obj_info;
982         struct child *child;
983
984         handle->obj_list = eina_list_remove(handle->obj_list, obj);
985
986         obj_info = evas_object_data_get(obj, "obj_info");
987         if (!obj_info) {
988                 ErrPrint("Object info is not valid\n");
989                 return;
990         }
991
992         elm_object_signal_callback_del(obj, "*", "*", script_signal_cb);
993
994         DbgPrint("delete object %s %p\n", obj_info->id, obj);
995         if (obj_info->parent == obj) {
996                 DbgPrint("Parent EDJE\n");
997         } else if (obj_info->parent) {
998                 Eina_List *l;
999                 Eina_List *n;
1000
1001                 parent_obj_info = evas_object_data_get(obj_info->parent, "obj_info");
1002                 if (parent_obj_info) {
1003                         EINA_LIST_FOREACH_SAFE(parent_obj_info->children, l, n, child) {
1004                                 if (child->obj != obj) {
1005                                         continue;
1006                                 }
1007
1008                                 /*!
1009                                  * \note
1010                                  * If this code is executed,
1011                                  * The parent is not deleted by desc, this object is deleted by itself.
1012                                  * It is not possible, but we care it.
1013                                  */
1014                                 DbgPrint("Children is updated: %s (%s)\n", child->part, parent_obj_info->id);
1015                                 parent_obj_info->children = eina_list_remove(parent_obj_info->children, child);
1016                                 free(child->part);
1017                                 free(child);
1018                                 break;
1019                         }
1020
1021                         if (!parent_obj_info->children && parent_obj_info->delete_me == 1) {
1022                                 DbgPrint("Children is cleared: %s (by a child)\n", parent_obj_info->id);
1023                                 evas_object_data_del(obj_info->parent, "obj_info");
1024                                 free(parent_obj_info->id);
1025                                 free(parent_obj_info);
1026                         }
1027                 }
1028         } else {
1029                 DbgPrint("obj_info->parent is NULL (skipped)\n");
1030         }
1031
1032         if (!obj_info->children) {
1033                 DbgPrint("Children is cleared: %s\n", obj_info->id);
1034                 evas_object_data_del(obj, "obj_info");
1035                 free(obj_info->id);
1036                 free(obj_info);
1037         } else {
1038                 DbgPrint("Children is remained: %s\n", obj_info->id);
1039                 obj_info->delete_me = 1;
1040         }
1041 }
1042
1043 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
1044 {
1045         Evas_Object *o, *ho;
1046
1047         o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
1048         if (!o) {
1049                 return NULL;      
1050         }
1051
1052         ho = evas_object_data_get(o, "_elm_access_target");
1053         return ho;
1054 }
1055
1056 /*!
1057         LB_ACCESS_HIGHLIGHT             0
1058         LB_ACCESS_HIGHLIGHT_NEXT        1
1059         LB_ACCESS_HIGHLIGHT_PREV        2
1060         LB_ACCESS_ACTIVATE              3
1061         LB_ACCESS_ACTION                4
1062         LB_ACCESS_SCROLL                5
1063 */
1064 PUBLIC int script_feed_event(void *h, int event_type, int x, int y, int down, unsigned int keycode, double timestamp)
1065 {
1066         struct info *handle = h;
1067         Evas_Object *edje;
1068         struct obj_info *obj_info;
1069         int ret = LB_STATUS_SUCCESS;
1070
1071         edje = find_edje(handle, NULL); /*!< Get the base layout */
1072         if (!edje) {
1073                 ErrPrint("Base layout is not exist\n");
1074                 return LB_STATUS_ERROR_NOT_EXIST;
1075         }
1076
1077         obj_info = evas_object_data_get(edje, "obj_info");
1078         if (!obj_info) {
1079                 ErrPrint("Object info is not valid\n");
1080                 return LB_STATUS_ERROR_INVALID;
1081         }
1082
1083         if (event_type & LB_SCRIPT_ACCESS_EVENT) {
1084                 Elm_Access_Action_Info info;
1085                 Elm_Access_Action_Type action;
1086
1087                 memset(&info, 0, sizeof(info));
1088
1089                 if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT) == LB_SCRIPT_ACCESS_HIGHLIGHT) {
1090                         action = ELM_ACCESS_ACTION_HIGHLIGHT;
1091                         info.x = x;
1092                         info.y = y;
1093                         ret = elm_access_action(edje, action, &info);
1094                         DbgPrint("ACCESS_HIGHLIGHT: %dx%d returns %d\n", x, y, ret);
1095                         if (ret == EINA_TRUE) {
1096                                 if (!get_highlighted_object(edje)) {
1097                                         ErrPrint("Highlighted object is not found\n");
1098                                         ret = LB_ACCESS_STATUS_ERROR;
1099                                 } else {
1100                                         DbgPrint("Highlighted object is found\n");
1101                                         ret = LB_ACCESS_STATUS_DONE;
1102                                 }
1103                         } else {
1104                                 ErrPrint("Action error\n");
1105                                 ret = LB_ACCESS_STATUS_ERROR;
1106                         }
1107                 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) == LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) {
1108                         action = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
1109                         info.highlight_cycle = EINA_FALSE;
1110                         ret = elm_access_action(edje, action, &info);
1111                         DbgPrint("ACCESS_HIGHLIGHT_NEXT, returns %d\n", ret);
1112                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
1113                 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) == LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) {
1114                         action = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
1115                         info.highlight_cycle = EINA_FALSE;
1116                         ret = elm_access_action(edje, action, &info);
1117                         DbgPrint("ACCESS_HIGHLIGHT_PREV, returns %d\n", ret);
1118                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
1119                 } else if ((event_type & LB_SCRIPT_ACCESS_ACTIVATE) == LB_SCRIPT_ACCESS_ACTIVATE) {
1120                         action = ELM_ACCESS_ACTION_ACTIVATE;
1121                         ret = elm_access_action(edje, action, &info);
1122                         DbgPrint("ACCESS_ACTIVATE, returns %d\n", ret);
1123                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1124                 } else if ((event_type & LB_SCRIPT_ACCESS_ACTION) == LB_SCRIPT_ACCESS_ACTION) {
1125                         if (down == 0) {
1126                                 action = ELM_ACCESS_ACTION_UP;
1127                                 ret = elm_access_action(edje, action, &info);
1128                                 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
1129                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1130                         } else if (down == 1) {
1131                                 action = ELM_ACCESS_ACTION_DOWN;
1132                                 ret = elm_access_action(edje, action, &info);
1133                                 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
1134                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1135                         } else {
1136                                 ErrPrint("Invalid access event\n");
1137                                 ret = LB_ACCESS_STATUS_ERROR;
1138                         }
1139                 } else if ((event_type & LB_SCRIPT_ACCESS_SCROLL) == LB_SCRIPT_ACCESS_SCROLL) {
1140                         action = ELM_ACCESS_ACTION_SCROLL;
1141                         info.x = x;
1142                         info.y = y;
1143                         switch (down) {
1144                         case 0:
1145                                 info.mouse_type = 0;
1146                                 ret = elm_access_action(edje, action, &info);
1147                                 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1148                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1149                                 break;
1150                         case -1:
1151                                 info.mouse_type = 1;
1152                                 ret = elm_access_action(edje, action, &info);
1153                                 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1154                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1155                                 break;
1156                         case 1:
1157                                 info.mouse_type = 2;
1158                                 ret = elm_access_action(edje, action, &info);
1159                                 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
1160                                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1161                                 break;
1162                         default:
1163                                 ret = LB_ACCESS_STATUS_ERROR;
1164                                 break;
1165                         }
1166                 } else if ((event_type & LB_SCRIPT_ACCESS_UNHIGHLIGHT) == LB_SCRIPT_ACCESS_UNHIGHLIGHT) {
1167                         action = ELM_ACCESS_ACTION_UNHIGHLIGHT;
1168                         ret = elm_access_action(edje, action, &info);
1169                         DbgPrint("ACCESS_UNHIGHLIGHT, returns %d\n", ret);
1170                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
1171                 } else {
1172                         DbgPrint("Invalid event\n");
1173                         ret = LB_ACCESS_STATUS_ERROR;
1174                 }
1175
1176         } else if (event_type & LB_SCRIPT_MOUSE_EVENT) {
1177                 double cur_timestamp;
1178
1179 #if defined(_USE_ECORE_TIME_GET)
1180                 cur_timestamp = ecore_time_get();
1181 #else
1182                 struct timeval tv;
1183                 if (gettimeofday(&tv, NULL) < 0) {
1184                         ErrPrint("Failed to get time\n");
1185                         cur_timestamp = 0.0f;
1186                 } else {
1187                         cur_timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
1188                 }
1189 #endif
1190                 if (cur_timestamp - timestamp > 0.1f && handle->is_mouse_down == 0) {
1191                         DbgPrint("Discard lazy event : %lf\n", cur_timestamp - timestamp);
1192                         return LB_STATUS_SUCCESS;
1193                 }
1194
1195                 switch (event_type) {
1196                 case LB_SCRIPT_MOUSE_DOWN:
1197                         if (handle->is_mouse_down == 0) {
1198                                 evas_event_feed_mouse_move(handle->e, x, y, timestamp * 1000, NULL);
1199                                 evas_event_feed_mouse_down(handle->e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
1200                                 handle->is_mouse_down = 1;
1201                         }
1202                         break;
1203                 case LB_SCRIPT_MOUSE_MOVE:
1204                         evas_event_feed_mouse_move(handle->e, x, y, timestamp * 1000, NULL);
1205                         break;
1206                 case LB_SCRIPT_MOUSE_UP:
1207                         if (handle->is_mouse_down == 1) {
1208                                 evas_event_feed_mouse_move(handle->e, x, y, timestamp * 1000, NULL);
1209                                 evas_event_feed_mouse_up(handle->e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL);
1210                                 handle->is_mouse_down = 0;
1211                         }
1212                         break;
1213                 case LB_SCRIPT_MOUSE_IN:
1214                         evas_event_feed_mouse_in(handle->e, timestamp * 1000, NULL);
1215                         break;
1216                 case LB_SCRIPT_MOUSE_OUT:
1217                         evas_event_feed_mouse_out(handle->e, timestamp * 1000, NULL);
1218                         break;
1219                 default:
1220                         return LB_STATUS_ERROR_INVALID;
1221                 }
1222         } else if (event_type & LB_SCRIPT_KEY_EVENT) {
1223                 const char *keyname = "";
1224                 const char *key = "";
1225                 const char *string = "";
1226                 const char *compose = "";
1227
1228                 switch (event_type) {
1229                 case LB_SCRIPT_KEY_DOWN:
1230                         evas_event_feed_key_down(handle->e, keyname, key, string, compose, timestamp * 1000, NULL);
1231                         ret = LB_KEY_STATUS_DONE;
1232                         /*!
1233                          * \TODO
1234                          * If the keyname == RIGHT, Need to check that
1235                          * Does it reach to the last focusable object?
1236                          */
1237
1238                         /*!
1239                          * if (REACH to the LAST) {
1240                          *    ret = LB_KEY_STATUS_LAST;
1241                          * } else {
1242                          *    ret = LB_KEY_STATUS_DONE;
1243                          * }
1244                          *
1245                          * if (REACH to the FIRST) {
1246                          *    ret = LB_KEY_STATUS_FIRST;
1247                          * } else {
1248                          *    ret = LB_KEY_STATUS_DONE;
1249                          * }
1250                          */
1251                         break;
1252                 case LB_SCRIPT_KEY_UP:
1253                         evas_event_feed_key_up(handle->e, keyname, key, string, compose, timestamp * 1000, NULL);
1254                         ret = LB_KEY_STATUS_DONE;
1255                         break;
1256                 case LB_SCRIPT_KEY_FOCUS_IN:
1257                         // evas_event_callback_call(handle->e, EVAS_CALLBACK_CANVAS_FOCUS_IN, NULL);
1258                         ret = LB_KEY_STATUS_DONE;
1259                         break;
1260                 case LB_SCRIPT_KEY_FOCUS_OUT:
1261                         // evas_event_callback_call(handle->e, EVAS_CALLBACK_CANVAS_FOCUS_OUT, NULL);
1262                         ret = LB_KEY_STATUS_DONE;
1263                         break;
1264                 default:
1265                         DbgPrint("Event is not implemented\n");
1266                         ret = LB_KEY_STATUS_ERROR;
1267                         break;
1268                 }
1269
1270         }
1271
1272         return ret;
1273 }
1274
1275 PUBLIC int script_update_script(void *h, const char *src_id, const char *target_id, const char *part, const char *path, const char *group)
1276 {
1277         struct info *handle = h;
1278         Evas_Object *edje;
1279         Evas_Object *obj;
1280         struct obj_info *obj_info;
1281         struct child *child;
1282         char _target_id[32];
1283
1284         edje = find_edje(handle, src_id);
1285         if (!edje) {
1286                 ErrPrint("Edje is not exists (%s)\n", src_id);
1287                 return LB_STATUS_ERROR_NOT_EXIST;
1288         }
1289
1290         obj_info = evas_object_data_get(edje, "obj_info");
1291         if (!obj_info) {
1292                 ErrPrint("Object info is not valid\n");
1293                 return LB_STATUS_ERROR_INVALID;
1294         }
1295
1296         obj = elm_object_part_content_unset(edje, part);
1297         if (obj) {
1298                 DbgPrint("delete object %s %p\n", part, obj);
1299                 /*!
1300                  * \note
1301                  * This will call the edje_del_cb.
1302                  * It will delete all access objects
1303                  */
1304                 evas_object_del(obj);
1305         }
1306
1307         if (!path || !strlen(path) || access(path, R_OK) != 0) {
1308                 DbgPrint("SKIP - Path: [%s]\n", path);
1309                 return LB_STATUS_SUCCESS;
1310         }
1311
1312         if (!target_id) {
1313                 if (find_edje(handle, part)) {
1314                         double timestamp;
1315
1316                         do {
1317 #if defined(_USE_ECORE_TIME_GET)
1318                                 timestamp = ecore_time_get();
1319 #else
1320                                 struct timeval tv;
1321                                 if (gettimeofday(&tv, NULL) < 0) {
1322                                         static int local_idx = 0;
1323                                         timestamp = (double)(local_idx++);
1324                                 } else {
1325                                         timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
1326                                 }
1327 #endif
1328
1329                                 snprintf(_target_id, sizeof(_target_id), "%lf", timestamp);
1330                         } while (find_edje(handle, _target_id));
1331
1332                         target_id = _target_id;
1333                 } else {
1334                         target_id = part;
1335                 }
1336
1337                 DbgPrint("Anonymouse target id: %s\n", target_id);
1338         }
1339
1340         obj = elm_layout_add(edje);
1341         if (!obj) {
1342                 ErrPrint("Failed to add a new edje object\n");
1343                 return LB_STATUS_ERROR_FAULT;
1344         }
1345
1346         edje_object_scale_set(elm_layout_edje_get(obj), elm_config_scale_get());
1347
1348         if (!elm_layout_file_set(obj, path, group)) {
1349                 int err;
1350                 err = edje_object_load_error_get(elm_layout_edje_get(obj));
1351                 if (err != EDJE_LOAD_ERROR_NONE) {
1352                         ErrPrint("Could not load %s from %s: %s\n", group, path, edje_load_error_str(err));
1353                 }
1354                 evas_object_del(obj);
1355                 return LB_STATUS_ERROR_IO;
1356         }
1357
1358         evas_object_show(obj);
1359
1360         obj_info = calloc(1, sizeof(*obj_info));
1361         if (!obj_info) {
1362                 ErrPrint("Failed to add a obj_info\n");
1363                 evas_object_del(obj);
1364                 return LB_STATUS_ERROR_MEMORY;
1365         }
1366
1367         obj_info->id = strdup(target_id);
1368         if (!obj_info->id) {
1369                 ErrPrint("Failed to add a obj_info\n");
1370                 free(obj_info);
1371                 evas_object_del(obj);
1372                 return LB_STATUS_ERROR_MEMORY;
1373         }
1374
1375         obj_info->parent = edje;
1376
1377         child = malloc(sizeof(*child));
1378         if (!child) {
1379                 ErrPrint("Error: %s\n", strerror(errno));
1380                 free(obj_info->id);
1381                 free(obj_info);
1382                 evas_object_del(obj);
1383                 return LB_STATUS_ERROR_MEMORY;
1384         }
1385
1386         child->part = strdup(part);
1387         if (!child->part) {
1388                 ErrPrint("Error: %s\n", strerror(errno));
1389                 free(child);
1390                 free(obj_info->id);
1391                 free(obj_info);
1392                 evas_object_del(obj);
1393                 return LB_STATUS_ERROR_MEMORY;
1394         }
1395
1396         child->obj = obj;
1397
1398         evas_object_data_set(obj, "obj_info", obj_info);
1399         evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1400         elm_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
1401         handle->obj_list = eina_list_append(handle->obj_list, obj);
1402
1403         DbgPrint("%s part swallow edje %p\n", part, obj);
1404         elm_object_part_content_set(edje, part, obj);
1405
1406         obj_info = evas_object_data_get(edje, "obj_info");
1407         obj_info->children = eina_list_append(obj_info->children, child);
1408
1409         return LB_STATUS_SUCCESS;
1410 }
1411
1412 PUBLIC int script_update_signal(void *h, const char *id, const char *part, const char *signal)
1413 {
1414         struct info *handle = h;
1415         Evas_Object *edje;
1416
1417         edje = find_edje(handle, id);
1418         if (!edje) {
1419                 return LB_STATUS_ERROR_NOT_EXIST;
1420         }
1421
1422         elm_object_signal_emit(edje, signal, part);
1423         return LB_STATUS_SUCCESS;
1424 }
1425
1426 PUBLIC int script_update_drag(void *h, const char *id, const char *part, double x, double y)
1427 {
1428         struct info *handle = h;
1429         Evas_Object *edje;
1430
1431         edje = find_edje(handle, id);
1432         if (!edje) {
1433                 return LB_STATUS_ERROR_NOT_EXIST;
1434         }
1435
1436         edje_object_part_drag_value_set(elm_layout_edje_get(edje), part, x, y);
1437         return LB_STATUS_SUCCESS;
1438 }
1439
1440 PUBLIC int script_update_size(void *han, const char *id, int w, int h)
1441 {
1442         struct info *handle = han;
1443         Evas_Object *edje;
1444
1445         edje = find_edje(handle, id);
1446         if (!edje) {
1447                 return LB_STATUS_ERROR_NOT_EXIST;
1448         }
1449
1450         if (!id) {
1451                 /*!
1452                  * \note
1453                  * Need to resize the canvas too
1454                  */
1455                 ecore_evas_resize(handle->ee, w, h);
1456         }
1457
1458         DbgPrint("Resize object to %dx%d\n", w, h);
1459         evas_object_resize(edje, w, h);
1460         return LB_STATUS_SUCCESS;
1461 }
1462
1463 PUBLIC int script_update_category(void *h, const char *id, const char *category)
1464 {
1465         struct info *handle = h;
1466
1467         if (handle->category) {
1468                 free(handle->category);
1469                 handle->category = NULL;
1470         }
1471
1472         if (!category) {
1473                 return LB_STATUS_SUCCESS;
1474         }
1475
1476         handle->category = strdup(category);
1477         if (!handle->category) {
1478                 ErrPrint("Error: %s\n", strerror(errno));
1479                 return LB_STATUS_ERROR_MEMORY;
1480         }
1481
1482         return LB_STATUS_SUCCESS;
1483 }
1484
1485 PUBLIC void *script_create(void *buffer_handle, const char *file, const char *group)
1486 {
1487         struct info *handle;
1488
1489         handle = calloc(1, sizeof(*handle));
1490         if (!handle) {
1491                 ErrPrint("Error: %s\n", strerror(errno));
1492                 return NULL;
1493         }
1494
1495         handle->file = strdup(file);
1496         if (!handle->file) {
1497                 ErrPrint("Error: %s\n", strerror(errno));
1498                 free(handle);
1499                 return NULL;
1500         }
1501
1502         handle->group = strdup(group);
1503         if (!handle->group) {
1504                 ErrPrint("Error: %s\n", strerror(errno));
1505                 free(handle->file);
1506                 free(handle);
1507                 return NULL;
1508         }
1509
1510         handle->buffer_handle = buffer_handle;
1511
1512         s_info.handle_list = eina_list_append(s_info.handle_list, handle);
1513
1514         return handle;
1515 }
1516
1517 PUBLIC int script_destroy(void *_handle)
1518 {
1519         struct info *handle;
1520         Evas_Object *edje;
1521
1522         handle = _handle;
1523
1524         if (!eina_list_data_find(s_info.handle_list, handle)) {
1525                 DbgPrint("Not found (already deleted?)\n");
1526                 return LB_STATUS_ERROR_NOT_EXIST;
1527         }
1528
1529         s_info.handle_list = eina_list_remove(s_info.handle_list, handle);
1530
1531         edje = eina_list_nth(handle->obj_list, 0);
1532         if (edje) {
1533                 evas_object_del(edje);
1534         }
1535
1536         DbgPrint("Release handle\n");
1537         free(handle->category);
1538         free(handle->file);
1539         free(handle->group);
1540         free(handle);
1541         return LB_STATUS_SUCCESS;
1542 }
1543
1544 static void sw_render_pre_cb(void *data, Evas *e, void *event_info)
1545 {
1546         struct info *handle = data;
1547
1548         if (handle->render_pre) {
1549                 handle->render_pre(handle->buffer_handle, handle->render_data);
1550         }
1551
1552         script_buffer_lock(handle->buffer_handle);
1553
1554         if (s_info.premultiplied) {
1555                 int w;
1556                 int h;
1557
1558                 script_buffer_get_size(handle->buffer_handle, &w, &h);
1559                 evas_damage_rectangle_add(handle->e, 0, 0, w, h);
1560         }
1561 }
1562
1563 static void sw_render_post_cb(void *data, Evas *e, void *event_info)
1564 {
1565         struct info *handle = data;
1566
1567         if (s_info.premultiplied) {
1568                 void *canvas;
1569                 int x, y, w, h;
1570
1571                 // Get a pointer of a buffer of the virtual canvas
1572                 canvas = (void *)ecore_evas_buffer_pixels_get(handle->ee);
1573                 if (!canvas) {
1574                         ErrPrint("Failed to get pixel canvas\n");
1575                         return;
1576                 }
1577
1578                 ecore_evas_geometry_get(handle->ee, &x, &y, &w, &h);
1579                 evas_data_argb_unpremul(canvas, w * h);
1580         }
1581
1582         script_buffer_unlock(handle->buffer_handle);
1583
1584         if (handle->render_post) {
1585                 handle->render_post(handle->buffer_handle, handle->render_data);
1586         }
1587 }
1588
1589 static void render_pre_cb(void *data, Evas *e, void *event_info)
1590 {
1591         struct info *handle = data;
1592         void *canvas;
1593
1594         canvas = script_buffer_pixmap_acquire_buffer(handle->buffer_handle);
1595         if (!canvas) {
1596                 ErrPrint("Acquired buffer is NULL\n");
1597         }
1598
1599         sw_render_pre_cb(data, handle->e, event_info);
1600 }
1601
1602 static void render_post_cb(void *data, Evas *e, void *event_info)
1603 {
1604         struct info *handle = data;
1605         void *canvas;
1606
1607         sw_render_post_cb(data, handle->e, event_info);
1608         canvas = script_buffer_pixmap_buffer(handle->buffer_handle);
1609         if (!canvas) {
1610                 ErrPrint("Acquired buffer is NULL\n");
1611         } else {
1612                 script_buffer_pixmap_release_buffer(canvas);
1613         }
1614 }
1615
1616 static void *alloc_fb(void *data, int size)
1617 {
1618         struct info *handle = data;
1619
1620         if (script_buffer_load(handle->buffer_handle) < 0) {
1621                 ErrPrint("Failed to load buffer handler\n");
1622                 return NULL;
1623         }
1624
1625         return script_buffer_fb(handle->buffer_handle);
1626 }
1627
1628 static void free_fb(void *data, void *ptr)
1629 {
1630         struct info *handle = data;
1631
1632         if (!handle->buffer_handle) {
1633                 ErrPrint("Buffer is not valid (maybe already released)\n");
1634                 return;
1635         }
1636
1637         if (script_buffer_fb(handle->buffer_handle) != ptr) {
1638                 ErrPrint("Buffer pointer is not matched\n");
1639         }
1640
1641         (void)script_buffer_unload(handle->buffer_handle);
1642 }
1643
1644 static int destroy_ecore_evas(struct info *handle)
1645 {
1646         if (!handle->ee) {
1647                 return LB_STATUS_SUCCESS;
1648         }
1649         ecore_evas_free(handle->ee);
1650         handle->ee = NULL;
1651         handle->e = NULL;
1652         return LB_STATUS_SUCCESS;
1653 }
1654
1655 static int create_ecore_evas(struct info *handle, int *w, int *h)
1656 {
1657         script_buffer_get_size(handle->buffer_handle, w, h);
1658         if (*w == 0 && *h == 0) {
1659                 ErrPrint("ZERO size FB accessed\n");
1660                 return LB_STATUS_ERROR_INVALID;
1661         }
1662
1663         if (handle->ee) {
1664                 int ow = 0;
1665                 int oh = 0;
1666
1667                 ecore_evas_geometry_get(handle->ee, NULL, NULL, &ow, &oh);
1668                 if (*w != ow || *h != oh) {
1669                         ErrPrint("EE exists, But different size - buffer_handle(%dx%d) -> ee(%dx%d)\n", ow, oh, *w, *h);
1670                         ecore_evas_resize(handle->ee, *w, *h);
1671                 }
1672
1673                 return LB_STATUS_SUCCESS;
1674         }
1675
1676         handle->ee = ecore_evas_buffer_allocfunc_new(*w, *h, alloc_fb, free_fb, handle);
1677         if (!handle->ee) {
1678                 ErrPrint("Failed to create a buffer\n");
1679                 return LB_STATUS_ERROR_FAULT;
1680         }
1681
1682         handle->e = ecore_evas_get(handle->ee);
1683         if (!handle->e) {
1684                 ErrPrint("Failed to get an Evas\n");
1685                 ecore_evas_free(handle->ee);
1686                 handle->ee = NULL;
1687                 return LB_STATUS_ERROR_FAULT;
1688         }
1689
1690         if (script_buffer_type(handle->buffer_handle) == BUFFER_TYPE_PIXMAP) {
1691                 void *canvas;
1692
1693                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb, handle);
1694                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_POST, render_post_cb, handle);
1695
1696                 /*
1697                  * \note
1698                  * ecore_evas_alpha_set tries to access the canvas buffer.
1699                  * Without any render_pre/render_post callback.
1700                  */
1701                 canvas = script_buffer_pixmap_acquire_buffer(handle->buffer_handle);
1702                 if (!canvas) {
1703                         ErrPrint("Acquired buffer is NULL\n");
1704                 } else {
1705                         ecore_evas_alpha_set(handle->ee, EINA_TRUE);
1706                         script_buffer_pixmap_release_buffer(canvas);
1707                 }
1708         } else {
1709                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_PRE, sw_render_pre_cb, handle);
1710                 evas_event_callback_add(handle->e, EVAS_CALLBACK_RENDER_POST, sw_render_post_cb, handle);
1711                 ecore_evas_alpha_set(handle->ee, EINA_TRUE);
1712         }
1713
1714         ecore_evas_manual_render_set(handle->ee, EINA_FALSE);
1715         ecore_evas_resize(handle->ee, *w, *h);
1716         ecore_evas_show(handle->ee);
1717         ecore_evas_activate(handle->ee);
1718
1719         return LB_STATUS_SUCCESS;
1720 }
1721
1722 PUBLIC int script_load(void *_handle, int (*render_pre)(void *buffer_handle, void *data), int (*render_post)(void *render_handle, void *data), void *data)
1723 {
1724         struct info *handle;
1725         Evas_Object *edje;
1726         struct obj_info *obj_info;
1727         int ret;
1728         int w;
1729         int h;
1730
1731         /*!
1732          * \TODO
1733          * Create "Ecore_Evas *"
1734          */
1735
1736         handle = _handle;
1737
1738         handle->render_pre = render_pre;
1739         handle->render_post = render_post;
1740         handle->render_data = data;
1741
1742         ret = create_ecore_evas(handle, &w, &h);
1743         if (ret < 0) {
1744                 return ret;
1745         }
1746
1747         obj_info = calloc(1, sizeof(*obj_info));
1748         if (!obj_info) {
1749                 ErrPrint("Heap: %s\n", strerror(errno));
1750                 destroy_ecore_evas(handle);
1751                 return LB_STATUS_ERROR_MEMORY;
1752         }
1753
1754         obj_info->parent = evas_object_rectangle_add(handle->e);
1755         if (!obj_info->parent) {
1756                 ErrPrint("Unable to create a parent box\n");
1757                 free(obj_info);
1758                 destroy_ecore_evas(handle);
1759                 return LB_STATUS_ERROR_FAULT;
1760         }
1761
1762         edje = elm_layout_add(obj_info->parent);
1763         if (!edje) {
1764                 ErrPrint("Failed to create an edje object\n");
1765                 evas_object_del(obj_info->parent);
1766                 free(obj_info);
1767                 destroy_ecore_evas(handle);
1768                 return LB_STATUS_ERROR_FAULT;
1769         }
1770
1771         edje_object_scale_set(elm_layout_edje_get(edje), elm_config_scale_get());
1772
1773         if (!elm_layout_file_set(edje, handle->file, handle->group)) {
1774                 int err;
1775
1776                 err = edje_object_load_error_get(elm_layout_edje_get(edje));
1777                 if (err != EDJE_LOAD_ERROR_NONE) {
1778                         ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, edje_load_error_str(err));
1779                 }
1780                 evas_object_del(edje);
1781                 evas_object_del(obj_info->parent);
1782                 free(obj_info);
1783                 destroy_ecore_evas(handle);
1784                 return LB_STATUS_ERROR_IO;
1785         }
1786
1787         handle->parent = edje;
1788
1789         elm_object_signal_callback_add(edje, "*", "*", script_signal_cb, handle);
1790         evas_object_event_callback_add(edje, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1791         evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1792         evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1793         evas_object_resize(edje, w, h);
1794         evas_object_show(edje);
1795         evas_object_data_set(edje, "obj_info", obj_info);
1796
1797         handle->obj_list = eina_list_append(handle->obj_list, edje);
1798         return LB_STATUS_SUCCESS;
1799 }
1800
1801 PUBLIC int script_unload(void *_handle)
1802 {
1803         struct info *handle;
1804
1805         /*!
1806          * \TODO
1807          * Destroy "Ecore_Evas *"
1808          */
1809
1810         handle = _handle;
1811
1812         if (handle->parent) {
1813                 DbgPrint("Delete parent box\n");
1814                 evas_object_del(handle->parent);
1815         }
1816
1817         (void)destroy_ecore_evas(handle);
1818         return LB_STATUS_SUCCESS;
1819 }
1820
1821 static void access_cb(keynode_t *node, void *user_data)
1822 {
1823         int state;
1824
1825         if (!node) {
1826                 if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &state) != 0) {
1827                         ErrPrint("Idle lock state is not valid\n");
1828                         state = 0; /* DISABLED */
1829                 }
1830         } else {
1831                 state = vconf_keynode_get_bool(node);
1832         }
1833
1834         DbgPrint("ELM CONFIG ACCESS: %d\n", state);
1835         elm_config_access_set(state);
1836         s_info.access_on = state;
1837 }
1838
1839 static void update_font_cb(void *data)
1840 {
1841         elm_config_font_overlay_set(TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
1842         DbgPrint("Update text class %s (%s, %d)\n", TEXT_CLASS, s_info.font_name, DEFAULT_FONT_SIZE);
1843 }
1844
1845 static void font_changed_cb(keynode_t *node, void *user_data)
1846 {
1847         char *font_name;
1848
1849         evas_font_reinit();
1850
1851         if (s_info.font_name) {
1852                 font_name = vconf_get_str("db/setting/accessibility/font_name");
1853                 if (!font_name) {
1854                         ErrPrint("Invalid font name (NULL)\n");
1855                         return;
1856                 }
1857
1858                 if (!strcmp(s_info.font_name, font_name)) {
1859                         DbgPrint("Font is not changed (Old: %s(%p) <> New: %s(%p))\n", s_info.font_name, s_info.font_name, font_name, font_name);
1860                         free(font_name);
1861                         return;
1862                 }
1863
1864                 DbgPrint("Release old font name: %s(%p)\n", s_info.font_name, s_info.font_name);
1865                 free(s_info.font_name);
1866         } else {
1867                 int ret;
1868
1869                 /*!
1870                  * Get the first font name using system_settings API.
1871                  */
1872                 font_name = NULL;
1873                 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &font_name);
1874                 if (ret != SYSTEM_SETTINGS_ERROR_NONE || !font_name) {
1875                         ErrPrint("System setting get: %d, font_name[%p]\n", ret, font_name);
1876                         return;
1877                 }
1878         }
1879
1880         s_info.font_name = font_name;
1881         DbgPrint("Font name is changed to %s(%p)\n", s_info.font_name, s_info.font_name);
1882
1883         /*!
1884          * \NOTE
1885          * Try to update all liveboxes
1886          */
1887         update_font_cb(NULL);
1888 }
1889
1890 static inline int convert_font_size(int size)
1891 {
1892         switch (size) {
1893         case SYSTEM_SETTINGS_FONT_SIZE_SMALL:
1894                 size = -80;
1895                 break;
1896         case SYSTEM_SETTINGS_FONT_SIZE_NORMAL:
1897                 size = -100;
1898                 break;
1899         case SYSTEM_SETTINGS_FONT_SIZE_LARGE:
1900                 size = -150;
1901                 break;
1902         case SYSTEM_SETTINGS_FONT_SIZE_HUGE:
1903                 size = -190;
1904                 break;
1905         case SYSTEM_SETTINGS_FONT_SIZE_GIANT:
1906                 size = -250;
1907                 break;
1908         default:
1909                 size = -100;
1910                 break;
1911         }
1912
1913         DbgPrint("Return size: %d\n", size);
1914         return size;
1915 }
1916
1917 static void font_size_cb(system_settings_key_e key, void *user_data)
1918 {
1919         int size;
1920
1921         if (system_settings_get_value_int(SYSTEM_SETTINGS_KEY_FONT_SIZE, &size) != SYSTEM_SETTINGS_ERROR_NONE) {
1922                 return;
1923         }
1924
1925         size = convert_font_size(size);
1926
1927         if (size == s_info.font_size) {
1928                 DbgPrint("Font size is not changed\n");
1929                 return;
1930         }
1931
1932         s_info.font_size = size;
1933         DbgPrint("Font size is changed to %d, but don't update the font info\n", size);
1934 }
1935
1936 PUBLIC int script_init(double scale, int premultiplied)
1937 {
1938         int ret;
1939         char *argv[] = {
1940                 "livebox.edje",
1941                 NULL,
1942         };
1943
1944         s_info.premultiplied = premultiplied;
1945
1946         /* ecore is already initialized */
1947         elm_init(1, argv);
1948         elm_config_scale_set(scale);
1949         DbgPrint("Scale is updated: %lf\n", scale);
1950
1951         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb, NULL);
1952         if (ret < 0) {
1953                 DbgPrint("TTS changed: %d\n", ret);
1954         }
1955
1956         ret = vconf_notify_key_changed("db/setting/accessibility/font_name", font_changed_cb, NULL);
1957         DbgPrint("System font is changed: %d\n", ret);
1958         
1959         ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, font_size_cb, NULL);
1960         DbgPrint("System font size is changed: %d\n", ret);
1961
1962         access_cb(NULL, NULL);
1963         font_changed_cb(NULL, NULL);
1964         font_size_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, NULL);
1965         return LB_STATUS_SUCCESS;
1966 }
1967
1968 PUBLIC int script_fini(void)
1969 {
1970         int ret;
1971         Eina_List *l;
1972         Eina_List *n;
1973         struct info *handle;
1974
1975         EINA_LIST_FOREACH_SAFE(s_info.handle_list, l, n, handle) {
1976                 script_destroy(handle);
1977         }
1978
1979         ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE);
1980         if (ret < 0) {
1981                 DbgPrint("Unset font size change event callback: %d\n", ret);
1982         }
1983
1984         ret = vconf_ignore_key_changed("db/setting/accessibility/font_name", font_changed_cb);
1985         if (ret < 0) {
1986                 DbgPrint("Unset font name change event callback: %d\n", ret);
1987         }
1988
1989         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb);
1990         if (ret < 0) {
1991                 DbgPrint("Unset tts: %d\n", ret);
1992         }
1993
1994         elm_shutdown();
1995
1996         free(s_info.font_name);
1997         s_info.font_name = NULL;
1998         return LB_STATUS_SUCCESS;
1999 }
2000
2001 /* End of a file */