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