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