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