Fix:Core:Renamed src to navit for cleanup of includes
[navit-package] / navit / plugin.c
1 #include <glib.h>
2 #include <gmodule.h>
3 #include "config.h"
4 #include "plugin.h"
5 #include "file.h"
6 #define PLUGIN_C
7 #include "plugin.h"
8
9 struct plugin {
10         int active;
11         int lazy;
12         char *name;
13         GModule *mod;
14         void (*init)(void);
15 };
16
17 struct plugins {
18         GHashTable *hash;
19         GList *list;
20 };
21
22 struct plugin *
23 plugin_new(char *plugin)
24 {
25         struct plugin *ret;
26         if (! g_module_supported()) {
27                 return NULL;
28         }
29         ret=g_new0(struct plugin, 1);
30         ret->name=g_strdup(plugin);
31         return ret;
32         
33 }
34
35 int
36 plugin_load(struct plugin *pl)
37 {
38         gpointer init;
39
40         GModule *mod;
41
42         if (pl->mod) {
43                 g_warning("can't load '%s', already loaded\n", pl->name);
44                 return 0;
45         }
46         mod=g_module_open(pl->name, G_MODULE_BIND_LOCAL | (pl->lazy ? G_MODULE_BIND_LAZY : 0));
47         if (! mod) {
48                 g_warning("can't load '%s', Error '%s'\n", pl->name, g_module_error());
49                 return 0;
50         }
51         if (!g_module_symbol(mod, "plugin_init", &init)) {
52                 g_warning("can't load '%s', plugin_init not found\n", pl->name);
53                 g_module_close(mod);
54                 return 0;
55         } else {
56                 pl->mod=mod;
57                 pl->init=init;
58         }
59         return 1;
60 }
61
62 char *
63 plugin_get_name(struct plugin *pl)
64 {
65         return pl->name;
66 }
67
68 int
69 plugin_get_active(struct plugin *pl)
70 {
71         return pl->active;
72 }
73
74 void
75 plugin_set_active(struct plugin *pl, int active)
76 {
77         pl->active=active;
78 }
79
80 void
81 plugin_set_lazy(struct plugin *pl, int lazy)
82 {
83         pl->lazy=lazy;
84 }
85
86 void
87 plugin_call_init(struct plugin *pl)
88 {
89         pl->init();
90 }
91
92 void
93 plugin_unload(struct plugin *pl)
94 {
95         g_module_close(pl->mod);
96         pl->mod=NULL;
97 }
98
99 void
100 plugin_destroy(struct plugin *pl)
101 {
102         g_free(pl);
103 }
104
105 struct plugins *
106 plugins_new(void)
107 {
108         struct plugins *ret=g_new0(struct plugins, 1);
109         ret->hash=g_hash_table_new(g_str_hash, g_str_equal);
110         return ret;
111 }
112
113 void
114 plugins_add_path(struct plugins *pls, const char *path, int active, int lazy)
115 {
116         struct file_wordexp *we;
117         int i, count;
118         char **array;
119         char *name;
120         struct plugin *pl;
121
122         we=file_wordexp_new(path);
123         count=file_wordexp_get_count(we);
124         array=file_wordexp_get_array(we);       
125         for (i = 0 ; i < count ; i++) {
126                 name=array[i];
127                 if (! (pl=g_hash_table_lookup(pls->hash, name))) {
128                         pl=plugin_new(name);
129                         if (! pl) {
130                                 g_warning("failed to create plugin '%s'\n", name);
131                                 continue;
132                         }
133                         g_hash_table_insert(pls->hash, plugin_get_name(pl), pl);
134                         pls->list=g_list_append(pls->list, pl);
135                 } else {
136                         pls->list=g_list_remove(pls->list, pl);
137                         pls->list=g_list_append(pls->list, pl);
138                 }
139                 plugin_set_active(pl, active);
140                 plugin_set_lazy(pl, lazy);
141         }
142         file_wordexp_destroy(we);
143 }
144
145 void
146 plugins_init(struct plugins *pls)
147 {
148 #ifdef USE_PLUGINS
149         struct plugin *pl;
150         GList *l;
151
152         l=pls->list;
153         while (l) {
154                 pl=l->data;
155                 if (plugin_get_active(pl)) 
156                         if (!plugin_load(pl)) 
157                                 plugin_set_active(pl, 0);
158                 l=g_list_next(l);
159         }
160         l=pls->list;
161         while (l) {
162                 pl=l->data;
163                 if (plugin_get_active(pl)) 
164                         plugin_call_init(pl);
165                 l=g_list_next(l);
166         }
167 #endif
168 }
169
170 void
171 plugins_destroy(struct plugins *pls)
172 {
173         GList *l;
174         struct plugin *pl;
175
176         l=pls->list;
177         while (l) {
178                 pl=l->data;
179                 plugin_unload(pl);
180                 plugin_destroy(pl);
181         }
182         g_list_free(pls->list);
183         g_hash_table_destroy(pls->hash);
184         g_free(pls);
185 }
186
187 void *
188 plugin_get_type(enum plugin_type type, const char *name)
189 {
190         GList *l;
191         struct name_val *nv;
192         l=plugin_types[type];
193         while (l) {
194                 nv=l->data;
195                 if (!g_ascii_strcasecmp(nv->name, name))
196                         return nv->val;
197                 l=g_list_next(l);
198         }
199         return NULL;
200 }