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