Update License
[apps/livebox/livebox-edje.git] / src / script_port.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (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 BASE_WIDTH      720.0f
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 *win;
81         Eina_List *access_chain;
82 };
83
84 static struct {
85         char *font_name;
86         int font_size;
87 } s_info = {
88         .font_name = NULL,
89         .font_size = 1,
90 };
91
92 static inline double scale_get(void)
93 {
94         int width;
95         int height;
96         ecore_x_window_size_get(0, &width, &height);
97         return (double)width / BASE_WIDTH;
98 }
99
100 static inline Evas_Object *find_edje(struct info *handle, const char *id)
101 {
102         Eina_List *l;
103         Evas_Object *edje;
104         struct obj_info *obj_info;
105
106         EINA_LIST_FOREACH(handle->obj_list, l, edje) {
107                 obj_info = evas_object_data_get(edje, "obj_info");
108                 if (!obj_info) {
109                         ErrPrint("Object info is not valid\n");
110                         continue;
111                 }
112
113                 if (!id) {
114                         if (!obj_info->id)
115                                 return edje;
116
117                         continue;
118                 } else if (!obj_info->id) {
119                         continue;
120                 }
121
122                 if (!strcmp(obj_info->id, id))
123                         return edje;
124         }
125
126         DbgPrint("EDJE[%s] is not found\n", id);
127         return NULL;
128 }
129
130 static inline void rebuild_focus_chain(Evas_Object *obj)
131 {
132         struct obj_info *obj_info;
133         Evas_Object *ao;
134         Eina_List *l;
135
136         obj_info = evas_object_data_get(obj, "obj_info");
137         if (!obj_info) {
138                 ErrPrint("Object info is not available\n");
139                 return;
140         }
141
142         elm_object_focus_custom_chain_unset(obj);
143
144         DbgPrint("Rebuild focus chain begin\n");
145         EINA_LIST_FOREACH(obj_info->access_chain, l, ao) {
146                 DbgPrint("Append %p\n", ao);
147                 elm_object_focus_custom_chain_append(obj, ao, NULL);
148         }
149         DbgPrint("Rebuild focus chain done\n");
150 }
151
152 PUBLIC const char *script_magic_id(void)
153 {
154         return "edje";
155 }
156
157 PUBLIC int script_update_color(void *h, Evas *e, const char *id, const char *part, const char *rgba)
158 {
159         struct info *handle = h;
160         Evas_Object *edje;
161         int r[3], g[3], b[3], a[3];
162         int ret;
163
164         edje = find_edje(handle, id);
165         if (!edje)
166                 return LB_STATUS_ERROR_NOT_EXIST;
167
168         ret = sscanf(rgba, "%d %d %d %d %d %d %d %d %d %d %d %d",
169                                         r, g, b, a,                     /* OBJECT */
170                                         r + 1, g + 1, b + 1, a + 1,     /* OUTLINE */
171                                         r + 2, g + 2, b + 2, a + 2);    /* SHADOW */
172         if (ret != 12) {
173                 DbgPrint("id[%s] part[%s] rgba[%s]\n", id, part, rgba);
174                 return LB_STATUS_ERROR_INVALID;
175         }
176
177         ret = edje_object_color_class_set(elm_layout_edje_get(edje), part,
178                                 r[0], g[0], b[0], a[0], /* OBJECT */
179                                 r[1], g[1], b[1], a[1], /* OUTLINE */
180                                 r[2], g[2], b[2], a[2]); /* SHADOW */
181
182         DbgPrint("EDJE[%s] color class is %s changed", id, ret == EINA_TRUE ? "successfully" : "not");
183         return LB_STATUS_SUCCESS;
184 }
185
186 static void activate_cb(void *data, Evas_Object *part_obj, Elm_Object_Item *item)
187 {
188         Evas_Object *ao;
189         Evas_Object *edje;
190         Evas *e;
191         int x;
192         int y;
193         int w;
194         int h;
195         struct timeval tv;
196         double timestamp;
197
198         ao = evas_object_data_get(part_obj, "ao");
199         if (!ao)
200                 return;
201
202         edje = evas_object_data_get(ao, "edje");
203         if (!edje)
204                 return;
205
206         e = evas_object_evas_get(part_obj);
207         evas_object_geometry_get(part_obj, &x, &y, &w, &h);
208         x += w / 2;
209         y += h / 2;
210
211         if (gettimeofday(&tv, NULL) < 0) {
212                 ErrPrint("Failed to get time\n");
213                 timestamp = 0.0f;
214         } else {
215                 timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f);
216         }
217
218         DbgPrint("Cursor is on %dx%d\n", x, y);
219         evas_event_feed_mouse_move(e, x, y, timestamp, NULL);
220         evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, timestamp + 0.01f, NULL);
221         evas_event_feed_mouse_move(e, x, y, timestamp + 0.02f, NULL);
222         evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, timestamp + 0.03f, NULL);
223 }
224
225 PUBLIC int script_update_text(void *h, Evas *e, const char *id, const char *part, const char *text)
226 {
227         struct obj_info *obj_info;
228         struct info *handle = h;
229         Evas_Object *edje;
230         Evas_Object *to;
231
232         edje = find_edje(handle, id);
233         if (!edje) {
234                 ErrPrint("Failed to find EDJE\n");
235                 return LB_STATUS_ERROR_NOT_EXIST;
236         }
237
238         obj_info = evas_object_data_get(edje, "obj_info");
239         if (!obj_info) {
240                 ErrPrint("Object info is not available\n");
241                 return LB_STATUS_ERROR_FAULT;
242         }
243
244         elm_object_part_text_set(edje, part, text ? text : "");
245
246         to = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
247         if (to) {
248                 Evas_Object *ao;
249                 char *utf8;
250
251                 ao = evas_object_data_get(to, "ao");
252                 if (!ao) {
253                         ao = elm_access_object_register(to, edje);
254                         if (!ao) {
255                                 ErrPrint("Unable to add ao: %s\n", part);
256                                 goto out;
257                         }
258                         obj_info->access_chain = eina_list_append(obj_info->access_chain, ao);
259                         evas_object_data_set(to, "ao", ao);
260                         evas_object_data_set(ao, "edje", edje);
261                         elm_access_activate_cb_set(ao, activate_cb, NULL);
262                         elm_object_focus_custom_chain_append(edje, ao, NULL);
263                 }
264
265                 if (!text || !strlen(text)) {
266                         obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
267                         evas_object_data_del(to, "ao");
268                         evas_object_data_del(ao, "edje");
269                         elm_access_object_unregister(ao);
270                         DbgPrint("[%s] Remove access object\n", part);
271
272                         rebuild_focus_chain(edje);
273                         goto out;
274                 }
275
276                 utf8 = elm_entry_markup_to_utf8(text);
277                 if ((!utf8 || !strlen(utf8))) {
278                         free(utf8);
279
280                         obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
281                         evas_object_data_del(to, "ao");
282                         evas_object_data_del(ao, "edje");
283                         elm_access_object_unregister(ao);
284                         DbgPrint("[%s] Remove access object\n", part);
285
286                         rebuild_focus_chain(edje);
287                         goto out;
288                 }
289
290                 elm_access_info_set(ao, ELM_ACCESS_INFO, utf8);
291                 DbgPrint("[%s] Update access object (%s)\n", part, utf8);
292                 free(utf8);
293         } else {
294                 ErrPrint("Unable to get text part[%s]\n", part);
295         }
296
297 out:
298         return LB_STATUS_SUCCESS;
299 }
300
301 static void parse_aspect(struct image_option *img_opt, const char *value, int len)
302 {
303         while (len > 0 && *value == ' ') {
304                 value++;
305                 len--;
306         }
307
308         if (len < 4)
309                 return;
310
311         img_opt->aspect = !strncasecmp(value, "true", 4);
312         DbgPrint("Parsed ASPECT: %d (%s)\n", img_opt->aspect, value);
313 }
314
315 static void parse_orient(struct image_option *img_opt, const char *value, int len)
316 {
317         while (len > 0 && *value == ' ') {
318                 value++;
319                 len--;
320         }
321
322         if (len < 4)
323                 return;
324
325         img_opt->orient = !strncasecmp(value, "true", 4);
326         DbgPrint("Parsed ORIENT: %d (%s)\n", img_opt->orient, value);
327 }
328
329 static void parse_size(struct image_option *img_opt, const char *value, int len)
330 {
331         int width;
332         int height;
333         char *buf;
334
335         while (len > 0 && *value == ' ') {
336                 value++;
337                 len--;
338         }
339
340         buf = strndup(value, len);
341         if (!buf) {
342                 ErrPrint("Heap: %s\n", strerror(errno));
343                 return;
344         }
345
346         if (sscanf(buf, "%dx%d", &width, &height) == 2) {
347                 img_opt->width = width;
348                 img_opt->height = height;
349                 DbgPrint("Parsed size : %dx%d (%s)\n", width, height, buf);
350         } else {
351                 DbgPrint("Invalid size tag[%s]\n", buf);
352         }
353
354         free(buf);
355 }
356
357 static void parse_fill(struct image_option *img_opt, const char *value, int len)
358 {
359         while (len > 0 && *value == ' ') {
360                 value++;
361                 len--;
362         }
363
364         if (!strncasecmp(value, "in-size", len))
365                 img_opt->fill = FILL_IN_SIZE;
366         else if (!strncasecmp(value, "over-size", len))
367                 img_opt->fill = FILL_OVER_SIZE;
368         else
369                 img_opt->fill = FILL_DISABLE;
370
371         DbgPrint("Parsed FILL: %d (%s)\n", img_opt->fill, value);
372 }
373
374 static inline void parse_image_option(const char *option, struct image_option *img_opt)
375 {
376         const char *ptr;
377         const char *cmd;
378         const char *value;
379         struct {
380                 const char *cmd;
381                 void (*handler)(struct image_option *img_opt, const char *value, int len);
382         } cmd_list[] = {
383                 {
384                         .cmd = "aspect", /* Keep the aspect ratio */
385                         .handler = parse_aspect,
386                 },
387                 {
388                         .cmd = "orient", /* Keep the orientation value: for the rotated images */
389                         .handler = parse_orient,
390                 },
391                 {
392                         .cmd = "fill", /* Fill the image to its container */
393                         .handler = parse_fill, /* Value: in-size, over-size, disable(default) */
394                 },
395                 {
396                         .cmd = "size",
397                         .handler = parse_size,
398                 },
399         };
400         enum {
401                 STATE_START,
402                 STATE_TOKEN,
403                 STATE_DATA,
404                 STATE_IGNORE,
405                 STATE_ERROR,
406                 STATE_END,
407         } state;
408         int idx;
409         int tag;
410
411         if (!option || !*option)
412                 return;
413
414         state = STATE_START;
415         /*!
416          * \note
417          * GCC 4.7 warnings uninitialized idx and tag value.
418          * But it will be initialized by the state machine. :(
419          * Anyway, I just reset idx and tag for reducing the GCC4.7 complains.
420          */
421         idx = 0;
422         tag = 0;
423         cmd = NULL;
424         value = NULL;
425
426         for (ptr = option; state != STATE_END; ptr++) {
427                 switch (state) {
428                 case STATE_START:
429                         if (*ptr == '\0') {
430                                 state = STATE_END;
431                                 continue;
432                         }
433
434                         if (isalpha(*ptr)) {
435                                 state = STATE_TOKEN;
436                                 ptr--;
437                         }
438                         tag = 0;
439                         idx = 0;
440
441                         cmd = cmd_list[tag].cmd;
442                         break;
443                 case STATE_IGNORE:
444                         if (*ptr == '=') {
445                                 state = STATE_DATA;
446                                 value = ptr;
447                         } else if (*ptr == '\0') {
448                                 state = STATE_END;
449                         }
450                         break;
451                 case STATE_TOKEN:
452                         if (cmd[idx] == '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '=')) {
453                                 if (*ptr == '=') {
454                                         value = ptr;
455                                         state = STATE_DATA;
456                                 } else {
457                                         state = STATE_IGNORE;
458                                 }
459                                 idx = 0;
460                         } else if (*ptr == '\0') {
461                                 state = STATE_END;
462                         } else if (cmd[idx] == *ptr) {
463                                 idx++;
464                         } else {
465                                 ptr -= (idx + 1);
466
467                                 tag++;
468                                 if (tag == sizeof(cmd_list) / sizeof(cmd_list[0])) {
469                                         tag = 0;
470                                         state = STATE_ERROR;
471                                 } else {
472                                         cmd = cmd_list[tag].cmd;
473                                 }
474                                 idx = 0;
475                         }
476                         break;
477                 case STATE_DATA:
478                         if (*ptr == ';' || *ptr == '\0') {
479                                 cmd_list[tag].handler(img_opt, value + 1, idx);
480                                 state = *ptr ? STATE_START : STATE_END;
481                         } else {
482                                 idx++;
483                         }
484                         break;
485                 case STATE_ERROR:
486                         if (*ptr == ';')
487                                 state = STATE_START;
488                         else if (*ptr == '\0')
489                                 state = STATE_END;
490                         break;
491                 default:
492                         break;
493                 }
494         }
495 }
496
497 PUBLIC int script_update_access(void *_h, Evas *e, const char *id, const char *part, const char *text, const char *option)
498 {
499         struct info *handle = _h;
500         Evas_Object *edje;
501         struct obj_info *obj_info;
502         Evas_Object *to;
503
504         edje = find_edje(handle, id);
505         if (!edje) {
506                 ErrPrint("No such object: %s\n", id);
507                 return LB_STATUS_ERROR_NOT_EXIST;
508         }
509
510         obj_info = evas_object_data_get(edje, "obj_info");
511         if (!obj_info) {
512                 ErrPrint("Object info is not available\n");
513                 return LB_STATUS_ERROR_FAULT;
514         }
515
516         to = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(edje), part);
517         if (to) {
518                 Evas_Object *ao;
519
520                 ao = evas_object_data_get(to, "ao");
521                 if (ao) {
522                         DbgPrint("[%s] Update access object (%s)\n", part, text);
523                         if (text && strlen(text)) {
524                                 elm_access_info_set(ao, ELM_ACCESS_INFO, text);
525                         } else {
526                                 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
527                                 evas_object_data_del(to, "ao");
528                                 evas_object_data_del(ao, "edje");
529                                 elm_access_object_unregister(ao);
530                                 DbgPrint("Successfully unregistered\n");
531
532                                 rebuild_focus_chain(edje);
533                         }
534                 } else if (text && strlen(text)) {
535                         ao = elm_access_object_register(to, edje);
536                         if (!ao) {
537                                 ErrPrint("Unable to register access object\n");
538                         } else {
539                                 elm_access_info_set(ao, ELM_ACCESS_INFO, text);
540                                 obj_info->access_chain = eina_list_append(obj_info->access_chain, ao);
541                                 evas_object_data_set(to, "ao", ao);
542                                 elm_object_focus_custom_chain_append(edje, ao, NULL);
543                                 DbgPrint("[%s] Register access info: (%s)\n", part, text);
544                                 evas_object_data_set(ao, "edje", edje);
545                                 elm_access_activate_cb_set(ao, activate_cb, NULL);
546                         }
547                 }
548         } else {
549                 ErrPrint("[%s] is not exists\n", part);
550         }
551
552         return LB_STATUS_SUCCESS;
553 }
554
555 PUBLIC int script_update_image(void *_h, Evas *e, const char *id, const char *part, const char *path, const char *option)
556 {
557         struct info *handle = _h;
558         Evas_Load_Error err;
559         Evas_Object *edje;
560         Evas_Object *img;
561         Evas_Coord w, h;
562         struct obj_info *obj_info;
563         struct child *child;
564         struct image_option img_opt = {
565                 .aspect = 0,
566                 .orient = 0,
567                 .fill = FILL_DISABLE,
568                 .width = -1,
569                 .height = -1,
570         };
571
572         edje = find_edje(handle, id);
573         if (!edje) {
574                 ErrPrint("No such object: %s\n", id);
575                 return LB_STATUS_ERROR_NOT_EXIST;
576         }
577
578         obj_info = evas_object_data_get(edje, "obj_info");
579         if (!obj_info) {
580                 ErrPrint("Object info is not available\n");
581                 return LB_STATUS_ERROR_FAULT;
582         }
583
584         img = elm_object_part_content_unset(edje, part);
585         if (img) {
586                 Eina_List *l;
587                 Eina_List *n;
588                 Evas_Object *ao;
589
590                 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
591                         if (child->obj != img)
592                                 continue;
593
594                         obj_info->children = eina_list_remove(obj_info->children, child);
595                         free(child->part);
596                         free(child);
597                         break;
598                 }
599
600                 DbgPrint("delete object %s %p\n", part, img);
601                 ao = evas_object_data_del(img, "ao");
602                 if (ao) {
603                         obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
604                         evas_object_data_del(ao, "edje");
605                         elm_access_object_unregister(ao);
606                         DbgPrint("Successfully unregistered\n");
607                 }
608                 evas_object_del(img);
609
610                 rebuild_focus_chain(edje);
611         }
612
613         if (!path || !strlen(path) || access(path, R_OK) != 0) {
614                 DbgPrint("SKIP - Path: [%s]\n", path);
615                 return LB_STATUS_SUCCESS;
616         }
617
618         child = malloc(sizeof(*child));
619         if (!child) {
620                 ErrPrint("Heap: %s\n", strerror(errno));
621                 return LB_STATUS_ERROR_MEMORY;
622         }
623
624         child->part = strdup(part);
625         if (!child->part) {
626                 ErrPrint("Heap: %s\n", strerror(errno));
627                 free(child);
628                 return LB_STATUS_ERROR_MEMORY;
629         }
630
631         img = evas_object_image_add(e);
632         if (!img) {
633                 ErrPrint("Failed to add an image object\n");
634                 free(child->part);
635                 free(child);
636                 return LB_STATUS_ERROR_FAULT;
637         }
638
639         evas_object_image_preload(img, EINA_FALSE);
640         parse_image_option(option, &img_opt);
641         evas_object_image_load_orientation_set(img, img_opt.orient);
642
643         evas_object_image_file_set(img, path, NULL);
644         err = evas_object_image_load_error_get(img);
645         if (err != EVAS_LOAD_ERROR_NONE) {
646                 ErrPrint("Load error: %s\n", evas_load_error_str(err));
647                 evas_object_del(img);
648                 free(child->part);
649                 free(child);
650                 return LB_STATUS_ERROR_IO;
651         }
652
653         evas_object_image_size_get(img, &w, &h);
654         if (img_opt.aspect) {
655                 if (img_opt.fill == FILL_OVER_SIZE) {
656                         Evas_Coord part_w;
657                         Evas_Coord part_h;
658
659                         if (img_opt.width >= 0 && img_opt.height >= 0) {
660                                 part_w = img_opt.width * scale_get();
661                                 part_h = img_opt.height * scale_get();
662                         } else {
663                                 part_w = 0;
664                                 part_h = 0;
665                                 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
666                         }
667                         DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
668
669                         if (part_w > w || part_h > h) {
670                                 double fw;
671                                 double fh;
672
673                                 fw = (double)part_w / (double)w;
674                                 fh = (double)part_h / (double)h;
675
676                                 if (fw > fh) {
677                                         w = part_w;
678                                         h = (double)h * fw;
679                                 } else {
680                                         h = part_h;
681                                         w = (double)w * fh;
682                                 }
683                         }
684                         DbgPrint("Size: %dx%d\n", w, h);
685
686                         evas_object_image_load_size_set(img, w, h);
687                         evas_object_image_load_region_set(img, (w - part_w) / 2, (h - part_h) / 2, part_w, part_h);
688                         evas_object_image_fill_set(img, 0, 0, part_w, part_h);
689                         evas_object_image_reload(img);
690                 } else if (img_opt.fill == FILL_IN_SIZE) {
691                         Evas_Coord part_w;
692                         Evas_Coord part_h;
693
694                         if (img_opt.width >= 0 && img_opt.height >= 0) {
695                                 part_w = img_opt.width * scale_get();
696                                 part_h = img_opt.height * scale_get();
697                         } else {
698                                 part_w = 0;
699                                 part_h = 0;
700                                 edje_object_part_geometry_get(elm_layout_edje_get(edje), part, NULL, NULL, &part_w, &part_h);
701                         }
702                         DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h);
703
704                         if (part_w > w || part_h > h) {
705                                 double fw;
706                                 double fh;
707
708                                 fw = (double)part_w / (double)w;
709                                 fh = (double)part_h / (double)h;
710
711                                 if (fw > fh) {
712                                         w = part_w;
713                                         h = (double)h * fw;
714                                 } else {
715                                         h = part_h;
716                                         w = (double)w * fh;
717                                 }
718                         }
719                         DbgPrint("Size: %dx%d\n", w, h);
720                         evas_object_image_fill_set(img, 0, 0, part_w, part_h);
721                         evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
722                         evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
723                 } else {
724                         evas_object_image_fill_set(img, 0, 0, w, h);
725                         evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
726                         evas_object_size_hint_aspect_set(img, EVAS_ASPECT_CONTROL_BOTH, w, h);
727                 }
728         } else {
729                 if (img_opt.width >= 0 && img_opt.height >= 0) {
730                         w = img_opt.width;
731                         h = img_opt.height;
732                         DbgPrint("Using given image size: %dx%d\n", w, h);
733                 }
734
735                 evas_object_image_fill_set(img, 0, 0, w, h);
736                 evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
737                 evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
738         }
739
740         /*!
741          * \note
742          * object will be shown by below statement automatically
743          */
744         DbgPrint("%s part swallow image %p (%dx%d)\n", part, img, w, h);
745         child->obj = img;
746         elm_object_part_content_set(edje, part, img);
747         obj_info->children = eina_list_append(obj_info->children, child);
748
749         /*!
750          * \note
751          * This object is not registered as an access object.
752          * So the developer should add it to access list manually, using DESC_ACCESS block.
753          */
754         return LB_STATUS_SUCCESS;
755 }
756
757 static void script_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
758 {
759         struct info *handle = data;
760         Evas_Coord w;
761         Evas_Coord h;
762         Evas_Coord px = 0;
763         Evas_Coord py = 0;
764         Evas_Coord pw = 0;
765         Evas_Coord ph = 0;
766         double sx;
767         double sy;
768         double ex;
769         double ey;
770
771         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
772         edje_object_part_geometry_get(elm_layout_edje_get(obj), source, &px, &py, &pw, &ph);
773
774         sx = ex = 0.0f;
775         if (w) {
776                 sx = (double)px / (double)w;
777                 ex = (double)(px + pw) / (double)w;
778         }
779
780         sy = ey = 0.0f;
781         if (h) {
782                 sy = (double)py / (double)h;
783                 ey = (double)(py + ph) / (double)h;
784         }
785
786         DbgPrint("Signal emit: source[%s], emission[%s]\n", source, emission);
787         script_signal_emit(handle->e, source, emission, sx, sy, ex, ey);
788 }
789
790 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
791 {
792         struct info *handle = _info;
793         struct obj_info *obj_info;
794         struct child *child;
795         Evas_Object *ao;
796
797         handle->obj_list = eina_list_remove(handle->obj_list, obj);
798
799         obj_info = evas_object_data_del(obj, "obj_info");
800         if (!obj_info) {
801                 ErrPrint("Object info is not valid\n");
802                 return;
803         }
804
805         DbgPrint("delete object %s %p\n", obj_info->id, obj);
806
807         elm_object_signal_callback_del(obj, "*", "*", script_signal_cb);
808
809         elm_object_focus_custom_chain_unset(obj);
810
811         EINA_LIST_FREE(obj_info->children, child) {
812                 DbgPrint("delete object %s %p\n", child->part, child->obj);
813                 if (child->obj) {
814                         Evas_Object *ao;
815                         ao = evas_object_data_del(child->obj, "ao");
816                         if (ao) {
817                                 obj_info->access_chain = eina_list_remove(obj_info->access_chain, ao);
818                                 evas_object_data_del(ao, "edje");
819                                 elm_access_object_unregister(ao);
820                         }
821                         evas_object_del(child->obj);
822                 }
823                 free(child->part);
824                 free(child);
825         }
826
827         EINA_LIST_FREE(obj_info->access_chain, ao) {
828                 evas_object_data_del(ao, "edje");
829                 elm_access_object_unregister(ao);
830         }
831
832         free(obj_info->id);
833         free(obj_info);
834 }
835
836 /*!
837         LB_ACCESS_HIGHLIGHT             0
838         LB_ACCESS_HIGHLIGHT_NEXT        1
839         LB_ACCESS_HIGHLIGHT_PREV        2
840         LB_ACCESS_ACTIVATE              3
841         LB_ACCESS_VALUE_CHANGE          4
842         LB_ACCESS_SCROLL                5
843 */
844 PUBLIC int script_feed_event(void *h, Evas *e, int event_type, int x, int y, int down, double timestamp)
845 {
846         struct info *handle = h;
847         Evas_Object *edje;
848         struct obj_info *obj_info;
849         int ret = LB_STATUS_SUCCESS;
850
851         DbgPrint("event: %d, x: %d, y: %d\n", event_type, x, y);
852
853         edje = find_edje(handle, NULL); /*!< Get the base layout */
854         if (!edje) {
855                 ErrPrint("Base layout is not exist\n");
856                 return LB_STATUS_ERROR_NOT_EXIST;
857         }
858
859         obj_info = evas_object_data_get(edje, "obj_info");
860         if (!obj_info) {
861                 ErrPrint("Object info is not valid\n");
862                 return LB_STATUS_ERROR_INVALID;
863         }
864
865         if (event_type & LB_SCRIPT_ACCESS_EVENT) {
866                 Elm_Access_Action_Info *info;
867                 Elm_Access_Action_Type action;
868                 const Eina_List *chain;
869
870                 info = calloc(1, sizeof(*info));
871                 if (!info) {
872                         ErrPrint("Error: %s\n", strerror(errno));
873                         return LB_STATUS_ERROR_MEMORY;
874                 }
875
876                 chain = elm_object_focus_custom_chain_get(edje);
877                 DbgPrint("Focus chain : %d\n", eina_list_count(chain));
878
879                 if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT) == LB_SCRIPT_ACCESS_HIGHLIGHT) {
880                         action = ELM_ACCESS_ACTION_HIGHLIGHT;
881                         info->x = x;
882                         info->y = y;
883                         ret = elm_access_action(edje, action, info);
884                         DbgPrint("ACCESS_HIGHLIGHT: %dx%d returns %d\n", x, y, ret);
885                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
886                 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) == LB_SCRIPT_ACCESS_HIGHLIGHT_NEXT) {
887                         action = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
888                         info->highlight_cycle = EINA_FALSE;
889                         ret = elm_access_action(edje, action, info);
890                         DbgPrint("ACCESS_HIGHLIGHT_NEXT, returns %d\n", ret);
891                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
892                 } else if ((event_type & LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) == LB_SCRIPT_ACCESS_HIGHLIGHT_PREV) {
893                         action = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
894                         info->highlight_cycle = EINA_FALSE;
895                         ret = elm_access_action(edje, action, info);
896                         DbgPrint("ACCESS_HIGHLIGHT_PREV, returns %d\n", ret);
897                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
898                 } else if ((event_type & LB_SCRIPT_ACCESS_ACTIVATE) == LB_SCRIPT_ACCESS_ACTIVATE) {
899                         action = ELM_ACCESS_ACTION_ACTIVATE;
900                         ret = elm_access_action(edje, action, info);
901                         DbgPrint("ACCESS_HIGHLIGHT_ACTIVATE, returns %d\n", ret);
902                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
903                 } else if ((event_type & LB_SCRIPT_ACCESS_VALUE_CHANGE) == LB_SCRIPT_ACCESS_VALUE_CHANGE) {
904                         action = ELM_ACCESS_ACTION_VALUE_CHANGE;
905                         ret = elm_access_action(edje, action, info);
906                         DbgPrint("ACCESS_HIGHLIGHT_VALUE_CHANGE, returns %d\n", ret);
907                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
908                 } else if ((event_type & LB_SCRIPT_ACCESS_SCROLL) == LB_SCRIPT_ACCESS_SCROLL) {
909                         action = ELM_ACCESS_ACTION_SCROLL;
910                         info->x = x;
911                         info->y = y;
912                         switch (down) {
913                         case 0: info->mouse_type = 0; break;
914                         case -1: info->mouse_type = 1; break;
915                         case 1: info->mouse_type = 2; break;
916                         default:
917                                 break;
918                         }
919                         ret = elm_access_action(edje, action, info);
920                         DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
921                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
922                 } else if ((event_type & LB_SCRIPT_ACCESS_UNHIGHLIGHT) == LB_SCRIPT_ACCESS_UNHIGHLIGHT) {
923                         action = ELM_ACCESS_ACTION_UNHIGHLIGHT;
924                         ret = elm_access_action(edje, action, info);
925                         DbgPrint("ACCESS_UNHIGHLIGHT, returns %d\n", ret);
926                         ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
927                 } else {
928                         DbgPrint("Invalid event\n");
929                         ret = LB_ACCESS_STATUS_ERROR;
930                 }
931
932                 free(info);
933         } else if (event_type & LB_SCRIPT_MOUSE_EVENT) {
934                 switch (event_type) {
935                 case LB_SCRIPT_MOUSE_DOWN:
936                         evas_event_feed_mouse_move(e, x, y, timestamp, NULL);
937                         evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, timestamp + 0.01f, NULL);
938                         break;
939                 case LB_SCRIPT_MOUSE_MOVE:
940                         evas_event_feed_mouse_move(e, x, y, timestamp, NULL);
941                         break;
942                 case LB_SCRIPT_MOUSE_UP:
943                         evas_event_feed_mouse_move(e, x, y, timestamp, NULL);
944                         evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, timestamp + 0.1f, NULL);
945                         break;
946                 case LB_SCRIPT_MOUSE_IN:
947                         evas_event_feed_mouse_in(e, timestamp, NULL);
948                         break;
949                 case LB_SCRIPT_MOUSE_OUT:
950                         evas_event_feed_mouse_out(e, timestamp, NULL);
951                         break;
952                 default:
953                         return LB_STATUS_ERROR_INVALID;
954                 }
955         } else if (event_type & LB_SCRIPT_KEY_EVENT) {
956                 DbgPrint("Key event is not implemented\n");
957                 return LB_STATUS_ERROR_NOT_IMPLEMENTED;
958         }
959
960         return ret;
961 }
962
963 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)
964 {
965         struct info *handle = h;
966         Evas_Object *edje;
967         Evas_Object *obj;
968         struct obj_info *obj_info;
969         struct child *child;
970
971         DbgPrint("src_id[%s] target_id[%s] part[%s] path[%s] group[%s]\n", src_id, target_id, part, path, group);
972
973         edje = find_edje(handle, src_id);
974         if (!edje) {
975                 ErrPrint("Edje is not exists\n");
976                 return LB_STATUS_ERROR_NOT_EXIST;
977         }
978
979         obj_info = evas_object_data_get(edje, "obj_info");
980         if (!obj_info) {
981                 ErrPrint("Object info is not valid\n");
982                 return LB_STATUS_ERROR_INVALID;
983         }
984
985         obj = elm_object_part_content_unset(edje, part);
986         if (obj) {
987                 Eina_List *l;
988                 Eina_List *n;
989
990                 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
991                         if (child->obj != obj)
992                                 continue;
993
994                         obj_info->children = eina_list_remove(obj_info->children, child);
995
996                         free(child->part);
997                         free(child);
998                         break;
999                 }
1000
1001                 DbgPrint("delete object %s %p\n", part, obj);
1002                 /*!
1003                  * \note
1004                  * This will call the edje_del_cb.
1005                  * It will delete all access objects
1006                  */
1007                 evas_object_del(obj);
1008         }
1009
1010         if (!path || !strlen(path) || access(path, R_OK) != 0) {
1011                 DbgPrint("SKIP - Path: [%s]\n", path);
1012                 return LB_STATUS_SUCCESS;
1013         }
1014
1015         obj = elm_layout_add(edje);
1016         if (!obj) {
1017                 ErrPrint("Failed to add a new edje object\n");
1018                 return LB_STATUS_ERROR_FAULT;
1019         }
1020
1021         if (!elm_layout_file_set(obj, path, group)) {
1022                 int err;
1023                 const char *errmsg;
1024
1025                 err = edje_object_load_error_get(elm_layout_edje_get(obj));
1026                 errmsg = edje_load_error_str(err);
1027                 ErrPrint("Could not load %s from %s: %s\n", group, path, errmsg);
1028                 evas_object_del(obj);
1029                 return LB_STATUS_ERROR_IO;
1030         }
1031
1032         evas_object_show(obj);
1033
1034         obj_info = calloc(1, sizeof(*obj_info));
1035         if (!obj_info) {
1036                 ErrPrint("Failed to add a obj_info\n");
1037                 evas_object_del(obj);
1038                 return LB_STATUS_ERROR_MEMORY;
1039         }
1040
1041         obj_info->id = strdup(target_id);
1042         if (!obj_info->id) {
1043                 ErrPrint("Failed to add a obj_info\n");
1044                 free(obj_info);
1045                 evas_object_del(obj);
1046                 return LB_STATUS_ERROR_MEMORY;
1047         }
1048
1049         child = malloc(sizeof(*child));
1050         if (!child) {
1051                 ErrPrint("Error: %s\n", strerror(errno));
1052                 free(obj_info->id);
1053                 free(obj_info);
1054                 evas_object_del(obj);
1055                 return LB_STATUS_ERROR_MEMORY;
1056         }
1057
1058         child->part = strdup(part);
1059         if (!child->part) {
1060                 ErrPrint("Error: %s\n", strerror(errno));
1061                 free(child);
1062                 free(obj_info->id);
1063                 free(obj_info);
1064                 evas_object_del(obj);
1065                 return LB_STATUS_ERROR_MEMORY;
1066         }
1067
1068         child->obj = obj;
1069
1070         evas_object_data_set(obj, "obj_info", obj_info);
1071         evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1072         elm_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
1073         handle->obj_list = eina_list_append(handle->obj_list, obj);
1074
1075         DbgPrint("%s part swallow edje %p\n", part, obj);
1076         elm_object_part_content_set(edje, part, obj);
1077         obj_info = evas_object_data_get(edje, "obj_info");
1078         obj_info->children = eina_list_append(obj_info->children, child);
1079         return LB_STATUS_SUCCESS;
1080 }
1081
1082 PUBLIC int script_update_signal(void *h, Evas *e, const char *id, const char *part, const char *signal)
1083 {
1084         struct info *handle = h;
1085         Evas_Object *edje;
1086
1087         DbgPrint("id[%s], part[%s], signal[%s]\n", id, part, signal);
1088
1089         edje = find_edje(handle, id);
1090         if (!edje)
1091                 return LB_STATUS_ERROR_NOT_EXIST;
1092
1093         elm_object_signal_emit(edje, signal, part);
1094         return LB_STATUS_SUCCESS;
1095 }
1096
1097 PUBLIC int script_update_drag(void *h, Evas *e, const char *id, const char *part, double x, double y)
1098 {
1099         struct info *handle = h;
1100         Evas_Object *edje;
1101
1102         DbgPrint("id[%s], part[%s], %lfx%lf\n", id, part, x, y);
1103
1104         edje = find_edje(handle, id);
1105         if (!edje)
1106                 return LB_STATUS_ERROR_NOT_EXIST;
1107
1108         edje_object_part_drag_value_set(elm_layout_edje_get(edje), part, x, y);
1109         return LB_STATUS_SUCCESS;
1110 }
1111
1112 PUBLIC int script_update_size(void *han, Evas *e, const char *id, int w, int h)
1113 {
1114         struct info *handle = han;
1115         Evas_Object *edje;
1116
1117         edje = find_edje(handle, id);
1118         if (!edje)
1119                 return LB_STATUS_ERROR_NOT_EXIST;
1120
1121         if (!id) {
1122                 handle->w = w;
1123                 handle->h = h;
1124         }
1125
1126         DbgPrint("Resize object to %dx%d\n", w, h);
1127         evas_object_resize(edje, w, h);
1128         return LB_STATUS_SUCCESS;
1129 }
1130
1131 PUBLIC int script_update_category(void *h, Evas *e, const char *id, const char *category)
1132 {
1133         struct info *handle = h;
1134
1135         DbgPrint("id[%s], category[%s]\n", id, category);
1136
1137         if (handle->category) {
1138                 free(handle->category);
1139                 handle->category = NULL;
1140         }
1141
1142         if (!category)
1143                 return LB_STATUS_SUCCESS;
1144
1145         handle->category = strdup(category);
1146         if (!handle->category) {
1147                 ErrPrint("Error: %s\n", strerror(errno));
1148                 return LB_STATUS_ERROR_MEMORY;
1149         }
1150
1151         return LB_STATUS_SUCCESS;
1152 }
1153
1154 PUBLIC void *script_create(const char *file, const char *group)
1155 {
1156         struct info *handle;
1157
1158         DbgPrint("file[%s], group[%s]\n", file, group);
1159
1160         handle = calloc(1, sizeof(*handle));
1161         if (!handle) {
1162                 ErrPrint("Error: %s\n", strerror(errno));
1163                 return NULL;
1164         }
1165
1166         handle->file = strdup(file);
1167         if (!handle->file) {
1168                 ErrPrint("Error: %s\n", strerror(errno));
1169                 free(handle);
1170                 return NULL;
1171         }
1172
1173         handle->group = strdup(group);
1174         if (!handle->group) {
1175                 ErrPrint("Error: %s\n", strerror(errno));
1176                 free(handle->file);
1177                 free(handle);
1178                 return NULL;
1179         }
1180
1181         return handle;
1182 }
1183
1184 PUBLIC int script_destroy(void *_handle)
1185 {
1186         struct info *handle;
1187         Evas_Object *edje;
1188
1189         handle = _handle;
1190
1191         edje = eina_list_nth(handle->obj_list, 0);
1192         if (edje)
1193                 evas_object_del(edje);
1194
1195         free(handle->category);
1196         free(handle->file);
1197         free(handle->group);
1198         free(handle);
1199         return LB_STATUS_SUCCESS;
1200 }
1201
1202 PUBLIC int script_load(void *_handle, Evas *e, int w, int h)
1203 {
1204         struct info *handle;
1205         Evas_Object *edje;
1206         struct obj_info *obj_info;
1207
1208         handle = _handle;
1209
1210         obj_info = calloc(1, sizeof(*obj_info));
1211         if (!obj_info) {
1212                 ErrPrint("Heap: %s\n", strerror(errno));
1213                 return LB_STATUS_ERROR_MEMORY;
1214         }
1215
1216         obj_info->win = evas_object_rectangle_add(e);
1217         if (!obj_info->win) {
1218                 free(obj_info);
1219                 return LB_STATUS_ERROR_FAULT;
1220         }
1221
1222         edje = elm_layout_add(obj_info->win);
1223         if (!edje) {
1224                 ErrPrint("Failed to create an edje object\n");
1225                 evas_object_del(obj_info->win);
1226                 free(obj_info);
1227                 return LB_STATUS_ERROR_FAULT;
1228         }
1229
1230         DbgPrint("Load edje: %s - %s\n", handle->file, handle->group);
1231         if (!elm_layout_file_set(edje, handle->file, handle->group)) {
1232                 int err;
1233                 const char *errmsg;
1234
1235                 err = edje_object_load_error_get(elm_layout_edje_get(edje));
1236                 errmsg = edje_load_error_str(err);
1237                 ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, errmsg);
1238                 evas_object_del(edje);
1239                 evas_object_del(obj_info->win);
1240                 free(obj_info);
1241                 return LB_STATUS_ERROR_IO;
1242         }
1243
1244         handle->e = e;
1245         handle->w = w;
1246         handle->h = h;
1247
1248         elm_object_signal_callback_add(edje, "*", "*", script_signal_cb, handle);
1249         evas_object_event_callback_add(edje, EVAS_CALLBACK_DEL, edje_del_cb, handle);
1250         evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1251         evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1252         evas_object_resize(edje, handle->w, handle->h);
1253         evas_object_show(edje);
1254         evas_object_data_set(edje, "obj_info", obj_info);
1255
1256         handle->obj_list = eina_list_append(handle->obj_list, edje);
1257         return LB_STATUS_SUCCESS;
1258 }
1259
1260 PUBLIC int script_unload(void *_handle, Evas *e)
1261 {
1262         struct info *handle;
1263         Evas_Object *edje;
1264
1265         handle = _handle;
1266
1267         DbgPrint("Unload edje: %s - %s\n", handle->file, handle->group);
1268         edje = eina_list_nth(handle->obj_list, 0);
1269         if (edje)
1270                 evas_object_del(edje);
1271         handle->e = NULL;
1272         return LB_STATUS_SUCCESS;
1273 }
1274
1275 static void access_cb(keynode_t *node, void *user_data)
1276 {
1277         int state;
1278
1279         if (!node) {
1280                 if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &state) != 0) {
1281                         ErrPrint("Idle lock state is not valid\n");
1282                         state = 0; /* DISABLED */
1283                 }
1284         } else {
1285                 state = vconf_keynode_get_bool(node);
1286         }
1287
1288         DbgPrint("ELM CONFIG ACCESS: %d\n", state);
1289         elm_config_access_set(state);
1290 }
1291
1292 static void update_font_cb(void *data)
1293 {
1294         elm_config_font_overlay_set(TEXT_CLASS, s_info.font_name, s_info.font_size);
1295         DbgPrint("Update text class %s (%s, %d)\n", TEXT_CLASS, s_info.font_name, s_info.font_size);
1296 }
1297
1298 static void font_changed_cb(system_settings_key_e key, void *user_data)
1299 {
1300         int ret;
1301         char *font_name;
1302
1303         ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &font_name);
1304         if (ret != SYSTEM_SETTINGS_ERROR_NONE || !font_name)
1305                 return;
1306
1307         if (s_info.font_name && !strcmp(s_info.font_name, font_name)) {
1308                 DbgPrint("Font is not changed\n");
1309                 free(font_name);
1310                 return;
1311         }
1312
1313         if (s_info.font_name) {
1314                 free(s_info.font_name);
1315                 s_info.font_name = NULL;
1316         }
1317
1318         s_info.font_name = font_name;
1319         DbgPrint("Font name is changed to %s\n", s_info.font_name);
1320
1321         /*!
1322          * \NOTE
1323          * Try to update all liveboxes
1324          */
1325         update_font_cb(NULL);
1326 }
1327
1328 static void font_size_cb(system_settings_key_e key, void *user_data)
1329 {
1330         int size;
1331
1332         if (system_settings_get_value_int(SYSTEM_SETTINGS_KEY_FONT_SIZE, &size) != SYSTEM_SETTINGS_ERROR_NONE)
1333                 return;
1334
1335         if (size == s_info.font_size) {
1336                 DbgPrint("Font size is not changed\n");
1337                 return;
1338         }
1339
1340         s_info.font_size = size;
1341         DbgPrint("Font size is changed to %d\n", size);
1342
1343         update_font_cb(NULL);
1344 }
1345
1346 PUBLIC int script_init(void)
1347 {
1348         int ret;
1349         char *argv[] = {
1350                 "livebox.edje",
1351                 NULL,
1352         };
1353         /* ecore is already initialized */
1354         elm_init(1, argv);
1355         elm_config_scale_set(scale_get());
1356
1357         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb, NULL);
1358         if (ret < 0)
1359                 ErrPrint("Failed to access cb\n");
1360
1361         access_cb(NULL, NULL);
1362
1363         ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE, font_changed_cb, NULL);
1364         DbgPrint("System font is changed: %d\n", ret);
1365         
1366         ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE, font_size_cb, NULL);
1367         DbgPrint("System font size is changed: %d\n", ret);
1368
1369         ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_FONT_TYPE, &s_info.font_name);
1370         if (ret == SYSTEM_SETTINGS_ERROR_NONE)
1371                 DbgPrint("Current font: %s\n", s_info.font_name);
1372
1373         ret = system_settings_get_value_int(SYSTEM_SETTINGS_KEY_FONT_SIZE, &s_info.font_size);
1374         if (ret == SYSTEM_SETTINGS_ERROR_NONE)
1375                 DbgPrint("Current size: %d\n", s_info.font_size);
1376
1377         return LB_STATUS_SUCCESS;
1378 }
1379
1380 PUBLIC int script_fini(void)
1381 {
1382         int ret;
1383         ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_SIZE);
1384         ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE);
1385         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, access_cb);
1386         elm_shutdown();
1387         return LB_STATUS_SUCCESS;
1388 }
1389
1390 /* End of a file */