Update the livebox-edje.
[apps/livebox/livebox-edje.git] / src / script_port.c
1 /*
2  * Copyright 2012  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://www.tizenopensource.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 <Evas.h>
24 #include <Edje.h>
25 #include <Eina.h>
26 #include <Ecore.h>
27 #include <Ecore_Evas.h>
28 #include <Eet.h>
29 #include <Ecore_X.h>
30
31 #include <dlog.h>
32 #include <debug.h>
33 #include <vconf.h>
34
35 #include "script_port.h"
36
37 #define TEXT_CLASS      "tizen"
38
39 extern void evas_common_font_flush(void);
40 extern int evas_common_font_cache_get(void);
41 extern void evas_common_font_cache_set(int size);
42
43 struct image_option {
44         int orient;
45         int aspect;
46 };
47
48 struct info {
49         char *file;
50         char *group;
51         char *category;
52         int w;
53         int h;
54
55         Evas *e;
56
57         Eina_List *obj_list;
58 };
59
60 struct child {
61         Evas_Object *obj;
62         char *part;
63 };
64
65 struct obj_info {
66         char *id;
67         Eina_List *children;
68 };
69
70 struct {
71         Ecore_Event_Handler *property_handler;
72         char *font;
73         int size;
74 } s_info = {
75         .property_handler = NULL,
76         .font = NULL,
77         .size = -100,
78 };
79
80 /*!
81  * \NOTE
82  * Reservce this for future use
83 static inline void common_cache_flush(void *evas)
84 {
85         int file_cache;
86         int collection_cache;
87         int image_cache;
88         int font_cache;
89
90         file_cache = edje_file_cache_get();
91         collection_cache = edje_collection_cache_get();
92         image_cache = evas_image_cache_get(evas);
93         font_cache = evas_font_cache_get(evas);
94
95         edje_file_cache_set(file_cache);
96         edje_collection_cache_set(collection_cache);
97         evas_image_cache_set(evas, 0);
98         evas_font_cache_set(evas, 0);
99
100         evas_image_cache_flush(evas);
101         evas_render_idle_flush(evas);
102         evas_font_cache_flush(evas);
103
104         edje_file_cache_flush();
105         edje_collection_cache_flush();
106
107         edje_file_cache_set(file_cache);
108         edje_collection_cache_set(collection_cache);
109         evas_image_cache_set(evas, image_cache);
110         evas_font_cache_set(evas, font_cache);
111
112         eet_clearcache();
113 }
114  */
115
116 static inline Evas_Object *find_edje(struct info *handle, const char *id)
117 {
118         Eina_List *l;
119         Evas_Object *edje;
120         struct obj_info *obj_info;
121
122         EINA_LIST_FOREACH(handle->obj_list, l, edje) {
123                 obj_info = evas_object_data_get(edje, "obj_info");
124                 if (!obj_info) {
125                         ErrPrint("Object info is not valid\n");
126                         continue;
127                 }
128
129                 if (!id) {
130                         if (!obj_info->id)
131                                 return edje;
132
133                         continue;
134                 } else if (!obj_info->id) {
135                         continue;
136                 }
137
138                 if (!strcmp(obj_info->id, id))
139                         return edje;
140         }
141
142         DbgPrint("EDJE[%s] is not found\n", id);
143         return NULL;
144 }
145
146 const char *script_magic_id(void)
147 {
148         return "edje";
149 }
150
151 int script_update_color(void *h, Evas *e, const char *id, const char *part, const char *rgba)
152 {
153         struct info *handle = h;
154         Evas_Object *edje;
155         int r[3], g[3], b[3], a[3];
156         int ret;
157
158         edje = find_edje(handle, id);
159         if (!edje)
160                 return -ENOENT;
161
162         ret = sscanf(rgba, "%d %d %d %d %d %d %d %d %d %d %d %d",
163                                         r, g, b, a,                     /* OBJECT */
164                                         r + 1, g + 1, b + 1, a + 1,     /* OUTLINE */
165                                         r + 2, g + 2, b + 2, a + 2);    /* SHADOW */
166         if (ret != 12) {
167                 DbgPrint("id[%s] part[%s] rgba[%s]\n", id, part, rgba);
168                 return -EINVAL;
169         }
170
171         ret = edje_object_color_class_set(edje, part,
172                                 r[0], g[0], b[0], a[0], /* OBJECT */
173                                 r[1], g[1], b[1], a[1], /* OUTLINE */
174                                 r[2], g[2], b[2], a[2]); /* SHADOW */
175
176         DbgPrint("EDJE[%s] color class is %s changed", id, ret == EINA_TRUE ? "successfully" : "not");
177         return 0;
178 }
179
180 int script_update_text(void *h, Evas *e, const char *id, const char *part, const char *text)
181 {
182         struct info *handle = h;
183         Evas_Object *edje;
184
185         edje = find_edje(handle, id);
186         if (!edje)
187                 return -ENOENT;
188
189         edje_object_part_text_set(edje, part, text);
190         return 0;
191 }
192
193 static void parse_aspect(struct image_option *img_opt, const char *value, int len)
194 {
195         while (len > 0 && *value == ' ') {
196                 value++;
197                 len--;
198         }
199
200         if (len < 4)
201                 return;
202
203         img_opt->aspect = !strncasecmp(value, "true", 4);
204         DbgPrint("Parsed ASPECT: %d\n", img_opt->aspect);
205 }
206
207 static void parse_orient(struct image_option *img_opt, const char *value, int len)
208 {
209         while (len > 0 && *value == ' ') {
210                 value++;
211                 len--;
212         }
213
214         if (len < 4)
215                 return;
216
217         img_opt->orient = !strncasecmp(value, "true", 4);
218         DbgPrint("Parsed ORIENT: %d\n", img_opt->aspect);
219 }
220
221 static inline void parse_image_option(const char *option, struct image_option *img_opt)
222 {
223         const char *ptr;
224         const char *cmd;
225         const char *value;
226         struct {
227                 const char *cmd;
228                 void (*handler)(struct image_option *img_opt, const char *value, int len);
229         } cmd_list[] = {
230                 {
231                         .cmd = "aspect",
232                         .handler = parse_aspect,
233                 },
234                 {
235                         .cmd = "orient",
236                         .handler = parse_orient,
237                 },
238         };
239         enum {
240                 STATE_START,
241                 STATE_TOKEN,
242                 STATE_DATA,
243                 STATE_IGNORE,
244                 STATE_ERROR,
245                 STATE_END,
246         } state;
247         int idx;
248         int tag;
249
250         if (!option || !*option)
251                 return;
252
253         state = STATE_START;
254
255         for (ptr = option; state != STATE_END; ptr++) {
256                 switch (state) {
257                 case STATE_START:
258                         if (*ptr == '\0') {
259                                 state = STATE_END;
260                                 continue;
261                         }
262
263                         if (isalpha(*ptr)) {
264                                 state = STATE_TOKEN;
265                                 ptr--;
266                         }
267                         tag = 0;
268                         idx = 0;
269
270                         cmd = cmd_list[tag].cmd;
271                         break;
272                 case STATE_IGNORE:
273                         if (*ptr == '=') {
274                                 state = STATE_DATA;
275                                 value = ptr;
276                         } else if (*ptr == '\0') {
277                                 state = STATE_END;
278                         }
279                         break;
280                 case STATE_TOKEN:
281                         if (cmd[idx] == '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '=')) {
282                                 if (*ptr == '=') {
283                                         value = ptr;
284                                         state = STATE_DATA;
285                                 } else {
286                                         state = STATE_IGNORE;
287                                 }
288                                 idx = 0;
289                         } else if (*ptr == '\0') {
290                                 state = STATE_END;
291                         } else if (cmd[idx] == *ptr) {
292                                 idx++;
293                         } else {
294                                 ptr -= (idx + 1);
295
296                                 tag++;
297                                 if (tag == sizeof(cmd_list) / sizeof(cmd_list[0])) {
298                                         tag = 0;
299                                         state = STATE_ERROR;
300                                 } else {
301                                         cmd = cmd_list[tag].cmd;
302                                 }
303                                 idx = 0;
304                         }
305                         break;
306                 case STATE_DATA:
307                         if (*ptr == ';' || *ptr == '\0') {
308                                 cmd_list[tag].handler(img_opt, value + 1, idx);
309                                 state = *ptr ? STATE_START : STATE_END;
310                         } else {
311                                 idx++;
312                         }
313                         break;
314                 case STATE_ERROR:
315                         if (*ptr == ';')
316                                 state = STATE_START;
317                         else if (*ptr == '\0')
318                                 state = STATE_END;
319                         break;
320                 default:
321                         break;
322                 }
323         }
324 }
325
326 int script_update_image(void *_h, Evas *e, const char *id, const char *part, const char *path, const char *option)
327 {
328         struct info *handle = _h;
329         Evas_Load_Error err;
330         Evas_Object *edje;
331         Evas_Object *img;
332         Evas_Coord w, h;
333         struct obj_info *obj_info;
334         struct child *child;
335         struct image_option img_opt = {
336                 .aspect = 0,
337                 .orient = 0,
338         };
339
340         edje = find_edje(handle, id);
341         if (!edje) {
342                 ErrPrint("No such object: %s\n", id);
343                 return -ENOENT;
344         }
345
346         obj_info = evas_object_data_get(edje, "obj_info");
347         if (!obj_info) {
348                 ErrPrint("Object info is not available\n");
349                 return -EFAULT;
350         }
351
352         img = edje_object_part_swallow_get(edje, part);
353         if (img) {
354                 Eina_List *l;
355                 Eina_List *n;
356
357                 edje_object_part_unswallow(edje, img);
358
359                 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
360                         if (child->obj != img)
361                                 continue;
362
363                         obj_info->children = eina_list_remove(obj_info->children, child);
364                         free(child->part);
365                         free(child);
366                         break;
367                 }
368
369                 DbgPrint("delete object %s %p\n", part, img);
370                 evas_object_del(img);
371         }
372
373         if (!path || !strlen(path) || access(path, R_OK) != 0) {
374                 DbgPrint("SKIP - Path: [%s]\n", path);
375                 return 0;
376         }
377
378         child = malloc(sizeof(*child));
379         if (!child) {
380                 ErrPrint("Heap: %s\n", strerror(errno));
381                 return -ENOMEM;
382         }
383
384         child->part = strdup(part);
385         if (!child->part) {
386                 ErrPrint("Heap: %s\n", strerror(errno));
387                 free(child);
388                 return -ENOMEM;
389         }
390
391         img = evas_object_image_filled_add(e);
392         if (!img) {
393                 ErrPrint("Failed to add an image object\n");
394                 free(child->part);
395                 free(child);
396                 return -EFAULT;
397         }
398
399         parse_image_option(option, &img_opt);
400         evas_object_image_load_orientation_set(img, img_opt.orient);
401
402         child->obj = img;
403
404         evas_object_image_file_set(img, path, NULL);
405
406         err = evas_object_image_load_error_get(img);
407         if (err != EVAS_LOAD_ERROR_NONE) {
408                 ErrPrint("Load error: %s\n", evas_load_error_str(err));
409                 evas_object_del(img);
410                 free(child->part);
411                 free(child);
412                 return -EIO;
413         }
414
415         evas_object_image_size_get(img, &w, &h);
416         evas_object_image_fill_set(img, 0, 0, w, h);
417         evas_object_size_hint_fill_set(img, EVAS_HINT_FILL, EVAS_HINT_FILL);
418         if (img_opt.aspect)
419                 evas_object_size_hint_aspect_set(img, EVAS_ASPECT_CONTROL_BOTH, w, h);
420         else
421                 evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
422         evas_object_resize(img, w, h);
423
424         /*!
425          * \note
426          * object will be shown by below statement automatically
427          */
428         DbgPrint("%s part swallow image %p\n", part, img);
429         edje_object_part_swallow(edje, part, img);
430         obj_info->children = eina_list_append(obj_info->children, child);
431
432         return 0;
433 }
434
435 static void script_signal_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
436 {
437         struct info *handle = data;
438         Evas_Coord w;
439         Evas_Coord h;
440         Evas_Coord px = 0;
441         Evas_Coord py = 0;
442         Evas_Coord pw = 0;
443         Evas_Coord ph = 0;
444         double sx;
445         double sy;
446         double ex;
447         double ey;
448
449         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
450         edje_object_part_geometry_get(obj, source, &px, &py, &pw, &ph);
451
452         sx = ex = 0.0f;
453         if (w) {
454                 sx = (double)px / (double)w;
455                 ex = (double)(px + pw) / (double)w;
456         }
457
458         sy = ey = 0.0f;
459         if (h) {
460                 sy = (double)py / (double)h;
461                 ey = (double)(py + ph) / (double)h;
462         }
463
464         DbgPrint("Signal emit: source[%s], emission[%s]\n", source, emission);
465         script_signal_emit(handle->e, source, emission, sx, sy, ex, ey);
466 }
467
468 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
469 {
470         struct info *handle = _info;
471         struct obj_info *obj_info;
472         struct child *child;
473
474         handle->obj_list = eina_list_remove(handle->obj_list, obj);
475
476         obj_info = evas_object_data_del(obj, "obj_info");
477         if (!obj_info) {
478                 ErrPrint("Object info is not valid\n");
479                 return;
480         }
481
482         DbgPrint("delete object %s %p\n", obj_info->id, obj);
483
484         edje_object_signal_callback_del_full(obj, "*", "*", script_signal_cb, handle);
485
486         EINA_LIST_FREE(obj_info->children, child) {
487                 DbgPrint("delete object %s %p\n", child->part, child->obj);
488                 if (child->obj)
489                         evas_object_del(child->obj);
490                 free(child->part);
491                 free(child);
492         }
493
494         free(obj_info->id);
495         free(obj_info);
496 }
497
498 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)
499 {
500         struct info *handle = h;
501         Evas_Object *edje;
502         Evas_Object *obj;
503         struct obj_info *obj_info;
504         struct child *child;
505
506         DbgPrint("src_id[%s] target_id[%s] part[%s] path[%s] group[%s]\n", src_id, target_id, part, path, group);
507
508         edje = find_edje(handle, src_id);
509         if (!edje) {
510                 ErrPrint("Edje is not exists\n");
511                 return -ENOENT;
512         }
513
514         obj_info = evas_object_data_get(edje, "obj_info");
515         if (!obj_info) {
516                 ErrPrint("Object info is not valid\n");
517                 return -EINVAL;
518         }
519
520         obj = edje_object_part_swallow_get(edje, part);
521         if (obj) {
522                 Eina_List *l;
523                 Eina_List *n;
524
525                 edje_object_part_unswallow(edje, obj);
526
527                 EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
528                         if (child->obj != obj)
529                                 continue;
530
531                         obj_info->children = eina_list_remove(obj_info->children, child);
532                         free(child->part);
533                         free(child);
534                         break;
535                 }
536
537                 DbgPrint("delete object %s %p\n", part, obj);
538                 evas_object_del(obj);
539         }
540
541         if (!path || !strlen(path) || access(path, R_OK) != 0) {
542                 DbgPrint("SKIP - Path: [%s]\n", path);
543                 return 0;
544         }
545
546         obj = edje_object_add(e);
547         if (!obj) {
548                 ErrPrint("Failed to add a new edje object\n");
549                 return -EFAULT;
550         }
551
552         //edje_object_text_class_set(obj, TEXT_CLASS, s_info.font, s_info.size);
553         if (!edje_object_file_set(obj, path, group)) {
554                 int err;
555                 const char *errmsg;
556
557                 err = edje_object_load_error_get(obj);
558                 errmsg = edje_load_error_str(err);
559                 ErrPrint("Could not load %s from %s: %s\n", group, path, errmsg);
560                 evas_object_del(obj);
561                 return -EIO;
562         }
563
564         evas_object_show(obj);
565
566         obj_info = calloc(1, sizeof(*obj_info));
567         if (!obj_info) {
568                 ErrPrint("Failed to add a obj_info\n");
569                 evas_object_del(obj);
570                 return -ENOMEM;
571         }
572
573         obj_info->id = strdup(target_id);
574         if (!obj_info->id) {
575                 ErrPrint("Failed to add a obj_info\n");
576                 free(obj_info);
577                 evas_object_del(obj);
578                 return -ENOMEM;
579         }
580
581         child = malloc(sizeof(*child));
582         if (!child) {
583                 ErrPrint("Error: %s\n", strerror(errno));
584                 free(obj_info->id);
585                 free(obj_info);
586                 evas_object_del(obj);
587                 return -ENOMEM;
588         }
589
590         child->part = strdup(part);
591         if (!child->part) {
592                 ErrPrint("Error: %s\n", strerror(errno));
593                 free(child);
594                 free(obj_info->id);
595                 free(obj_info);
596                 evas_object_del(obj);
597                 return -ENOMEM;
598         }
599
600         child->obj = obj;
601
602         evas_object_data_set(obj, "obj_info", obj_info);
603         evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
604         edje_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
605         handle->obj_list = eina_list_append(handle->obj_list, obj);
606
607         DbgPrint("%s part swallow edje %p\n", part, obj);
608         edje_object_part_swallow(edje, part, obj);
609         obj_info = evas_object_data_get(edje, "obj_info");
610         obj_info->children = eina_list_append(obj_info->children, child);
611         return 0;
612 }
613
614 int script_update_signal(void *h, Evas *e, const char *id, const char *part, const char *signal)
615 {
616         struct info *handle = h;
617         Evas_Object *edje;
618
619         DbgPrint("id[%s], part[%s], signal[%s]\n", id, part, signal);
620
621         edje = find_edje(handle, id);
622         if (!edje)
623                 return -ENOENT;
624
625         edje_object_signal_emit(edje, signal, part);
626         return 0;
627 }
628
629 int script_update_drag(void *h, Evas *e, const char *id, const char *part, double x, double y)
630 {
631         struct info *handle = h;
632         Evas_Object *edje;
633
634         DbgPrint("id[%s], part[%s], %lfx%lf\n", id, part, x, y);
635
636         edje = find_edje(handle, id);
637         if (!edje)
638                 return -ENOENT;
639
640         edje_object_part_drag_value_set(edje, part, x, y);
641         return 0;
642 }
643
644 int script_update_size(void *han, Evas *e, const char *id, int w, int h)
645 {
646         struct info *handle = han;
647         Evas_Object *edje;
648
649         edje = find_edje(handle, id);
650         if (!edje)
651                 return -ENOENT;
652
653         if (!id) {
654                 handle->w = w;
655                 handle->h = h;
656         }
657
658         DbgPrint("Resize object to %dx%d\n", w, h);
659         evas_object_resize(edje, w, h);
660         return 0;
661 }
662
663 int script_update_category(void *h, Evas *e, const char *id, const char *category)
664 {
665         struct info *handle = h;
666
667         DbgPrint("id[%s], category[%s]\n", id, category);
668
669         if (handle->category) {
670                 free(handle->category);
671                 handle->category = NULL;
672         }
673
674         if (!category)
675                 return 0;
676
677         handle->category = strdup(category);
678         if (!handle->category) {
679                 ErrPrint("Error: %s\n", strerror(errno));
680                 return -ENOMEM;
681         }
682
683         return 0;
684 }
685
686 void *script_create(const char *file, const char *group)
687 {
688         struct info *handle;
689
690         DbgPrint("file[%s], group[%s]\n", file, group);
691
692         handle = calloc(1, sizeof(*handle));
693         if (!handle) {
694                 ErrPrint("Error: %s\n", strerror(errno));
695                 return NULL;
696         }
697
698         handle->file = strdup(file);
699         if (!handle->file) {
700                 ErrPrint("Error: %s\n", strerror(errno));
701                 free(handle);
702                 return NULL;
703         }
704
705         handle->group = strdup(group);
706         if (!handle->group) {
707                 ErrPrint("Error: %s\n", strerror(errno));
708                 free(handle->file);
709                 free(handle);
710                 return NULL;
711         }
712
713         return handle;
714 }
715
716 int script_destroy(void *_handle)
717 {
718         struct info *handle;
719         Evas_Object *edje;
720
721         handle = _handle;
722
723         edje = eina_list_nth(handle->obj_list, 0);
724         if (edje)
725                 evas_object_del(edje);
726
727         free(handle->category);
728         free(handle->file);
729         free(handle->group);
730         free(handle);
731         return 0;
732 }
733
734 int script_load(void *_handle, Evas *e, int w, int h)
735 {
736         struct info *handle;
737         Evas_Object *edje;
738         struct obj_info *obj_info;
739
740         handle = _handle;
741
742         obj_info = calloc(1, sizeof(*obj_info));
743         if (!obj_info) {
744                 ErrPrint("Heap: %s\n", strerror(errno));
745                 return -ENOMEM;
746         }
747
748         edje = edje_object_add(e);
749         if (!edje) {
750                 ErrPrint("Failed to create an edje object\n");
751                 free(obj_info);
752                 return -EFAULT;
753         }
754
755         //edje_object_text_class_set(edje, TEXT_CLASS, s_info.font, s_info.size);
756         DbgPrint("Load edje: %s - %s\n", handle->file, handle->group);
757         if (!edje_object_file_set(edje, handle->file, handle->group)) {
758                 int err;
759                 const char *errmsg;
760
761                 err = edje_object_load_error_get(edje);
762                 errmsg = edje_load_error_str(err);
763                 ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, errmsg);
764                 evas_object_del(edje);
765                 free(obj_info);
766                 return -EIO;
767         }
768
769         handle->e = e;
770         handle->w = w;
771         handle->h = h;
772
773         edje_object_signal_callback_add(edje, "*", "*", script_signal_cb, handle);
774         evas_object_event_callback_add(edje, EVAS_CALLBACK_DEL, edje_del_cb, handle);
775         evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
776         evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
777         evas_object_resize(edje, handle->w, handle->h);
778         evas_object_show(edje);
779         evas_object_data_set(edje, "obj_info", obj_info);
780
781         handle->obj_list = eina_list_append(handle->obj_list, edje);
782         return 0;
783 }
784
785 int script_unload(void *_handle, Evas *e)
786 {
787         struct info *handle;
788         Evas_Object *edje;
789
790         handle = _handle;
791
792         DbgPrint("Unload edje: %s - %s\n", handle->file, handle->group);
793         edje = eina_list_nth(handle->obj_list, 0);
794         if (edje)
795                 evas_object_del(edje);
796         handle->e = NULL;
797         return 0;
798 }
799
800 static Eina_Bool property_cb(void *data, int type, void *event)
801 {
802         Ecore_X_Event_Window_Property *info = (Ecore_X_Event_Window_Property *)event;
803
804         if (info->atom == ecore_x_atom_get("FONT_TYPE_change") || info->atom == ecore_x_atom_get("BADA_FONT_change")) {
805                 Eina_List *list;
806                 char *text;
807                 char *font;
808                 int cache;
809
810                 font = vconf_get_str("db/setting/accessibility/font_name");
811                 if (!font)
812                         return ECORE_CALLBACK_PASS_ON;
813
814                 if (s_info.font)
815                         free(s_info.font);
816
817                 s_info.font = font;
818
819                 cache = evas_common_font_cache_get();
820                 evas_common_font_cache_set(0);
821                 evas_common_font_flush();
822
823                 list = edje_text_class_list();
824                 EINA_LIST_FREE(list, text) {
825                         if (!strncasecmp(text, TEXT_CLASS, strlen(TEXT_CLASS))) {
826                                 edje_text_class_del(text);
827                                 edje_text_class_set(text, s_info.font, s_info.size);
828                                 DbgPrint("Update text class %s (%s, %d)\n", text, s_info.font, s_info.size);
829                         } else {
830                                 DbgPrint("Skip text class %s\n", text);
831                         }
832                 }
833
834                 evas_common_font_cache_set(cache);
835         }
836
837         return ECORE_CALLBACK_PASS_ON;
838 }
839
840 static void font_name_cb(keynode_t *node, void *user_data)
841 {
842         const char *font;
843
844         if (!node)
845                 return;
846
847         font = vconf_keynode_get_str(node);
848         if (!font)
849                 return;
850
851         DbgPrint("Font changed to %s\n", font);
852 }
853
854 static void font_size_cb(keynode_t *node, void *user_data)
855 {
856         if (!node)
857                 return;
858         /*!
859          * \TODO
860          * Implementing me.
861          */
862         DbgPrint("Size type: %d\n", vconf_keynode_get_int(node));
863 }
864
865 int script_init(void)
866 {
867         int ret;
868         /* ecore is already initialized */
869         edje_init();
870
871         s_info.property_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, property_cb, NULL);
872         if (!s_info.property_handler)
873                 ErrPrint("Failed to add a property change event handler\n");
874
875         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, font_size_cb, NULL);
876         if (ret < 0)
877                 ErrPrint("Failed to add vconf for font size change\n");
878
879         ret = vconf_notify_key_changed("db/setting/accessibility/font_name", font_name_cb, NULL);
880         if (ret < 0)
881                 ErrPrint("Failed to add vconf for font name change\n");
882
883         return 0;
884 }
885
886 int script_fini(void)
887 {
888
889         vconf_ignore_key_changed("db/setting/accessibility/font_name", font_name_cb);
890         vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, font_size_cb);
891         ecore_event_handler_del(s_info.property_handler);
892         s_info.property_handler = NULL;
893         edje_shutdown();
894         return 0;
895 }
896
897 /* End of a file */