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