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