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