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