diff options
author | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
commit | 3ad3455551be0d7859ecb02290376206d5e66498 (patch) | |
tree | 497917e12b4d7f458dff9765d9b53f64c4e03fc3 /libraries/elementary/src/lib/elm_module.c | |
parent | Update EFL to latest beta. (diff) | |
download | SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.zip SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.gz SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.bz2 SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.xz |
And actually include new files, plus elementary libraries.
Diffstat (limited to '')
-rw-r--r-- | libraries/elementary/src/lib/elm_module.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elm_module.c b/libraries/elementary/src/lib/elm_module.c new file mode 100644 index 0000000..396e9de --- /dev/null +++ b/libraries/elementary/src/lib/elm_module.c | |||
@@ -0,0 +1,251 @@ | |||
1 | #include <Elementary.h> | ||
2 | #include "elm_priv.h" | ||
3 | |||
4 | /* what are moodules in elementary for? for modularising behavior and features | ||
5 | * so they can be plugged in and out where you dont want the core source to | ||
6 | * always behave like that or do it that way. plug it at runtime! | ||
7 | * | ||
8 | * they have module names (in config) and "slots" to plug that module into | ||
9 | * to server a purpose. eg you plug plugin "xx" into the "entry-copy-paste" | ||
10 | * slot so it would provide replacement copy & paste ui functionality and | ||
11 | * specific symbols | ||
12 | * | ||
13 | * config is something like: | ||
14 | * | ||
15 | * export ELM_MODULES="xx>slot1:yy>slot2" | ||
16 | * | ||
17 | * where a module named xx is plugged into slot1 & yy is plugged into slot2 | ||
18 | * | ||
19 | * real examples: | ||
20 | * | ||
21 | * export ELM_MODULES="my_module>entry/api" | ||
22 | * | ||
23 | * this loads the module called "my_module" into the slot "entry/api" which | ||
24 | * is an api slot for entry modules to modify behavior and hook to | ||
25 | * creation/deletion of the entry as well as replace the longpress behavior. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | # include "elementary_config.h" | ||
30 | #endif | ||
31 | |||
32 | static Eina_Hash *modules = NULL; | ||
33 | static Eina_Hash *modules_as = NULL; | ||
34 | |||
35 | void | ||
36 | _elm_module_init(void) | ||
37 | { | ||
38 | modules = eina_hash_string_small_new(NULL); | ||
39 | modules_as = eina_hash_string_small_new(NULL); | ||
40 | } | ||
41 | |||
42 | void | ||
43 | _elm_module_shutdown(void) | ||
44 | { | ||
45 | // FIXME: unload all modules | ||
46 | if (modules) eina_hash_free(modules); | ||
47 | modules = NULL; | ||
48 | if (modules_as) eina_hash_free(modules_as); | ||
49 | modules_as = NULL; | ||
50 | } | ||
51 | |||
52 | void | ||
53 | _elm_module_parse(const char *s) | ||
54 | { | ||
55 | const char *p, *pe; | ||
56 | |||
57 | p = s; | ||
58 | pe = p; | ||
59 | for (;;) | ||
60 | { | ||
61 | if ((*pe == ':') || (!*pe)) | ||
62 | { // p -> pe == 'name:' | ||
63 | if (pe > p) | ||
64 | { | ||
65 | char *n = malloc(pe - p + 1); | ||
66 | if (n) | ||
67 | { | ||
68 | char *nn; | ||
69 | |||
70 | strncpy(n, p, pe - p); | ||
71 | n[pe - p] = 0; | ||
72 | nn = strchr(n, '>'); | ||
73 | if (nn) | ||
74 | { | ||
75 | *nn = 0; | ||
76 | nn++; | ||
77 | _elm_module_add(n, nn); | ||
78 | } | ||
79 | free(n); | ||
80 | } | ||
81 | } | ||
82 | if (!*pe) break; | ||
83 | p = pe + 1; | ||
84 | pe = p; | ||
85 | } | ||
86 | else | ||
87 | pe++; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | Elm_Module * | ||
92 | _elm_module_find_as(const char *as) | ||
93 | { | ||
94 | Elm_Module *m; | ||
95 | |||
96 | m = eina_hash_find(modules_as, as); | ||
97 | if (!m) return NULL; | ||
98 | |||
99 | if (!_elm_module_load(m)) | ||
100 | { | ||
101 | _elm_module_del(m); | ||
102 | return NULL; | ||
103 | } | ||
104 | return m; | ||
105 | } | ||
106 | |||
107 | Eina_Bool | ||
108 | _elm_module_load(Elm_Module *m) | ||
109 | { | ||
110 | const char *home; | ||
111 | char buf[PATH_MAX]; | ||
112 | |||
113 | if (m->module) return EINA_TRUE; | ||
114 | |||
115 | home = getenv("HOME"); | ||
116 | if (home) | ||
117 | { | ||
118 | snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/modules/%s/%s/module" EFL_SHARED_EXTENSION, home, m->name, MODULE_ARCH); | ||
119 | m->module = eina_module_new(buf); | ||
120 | if (m->module && eina_module_load (m->module) == EINA_TRUE) | ||
121 | { | ||
122 | m->init_func = eina_module_symbol_get(m->module, "elm_modapi_init"); | ||
123 | if (m->init_func) | ||
124 | { | ||
125 | m->shutdown_func = eina_module_symbol_get(m->module, "elm_modapi_shutdown"); | ||
126 | m->so_path = eina_stringshare_add(buf); | ||
127 | snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/modules/%s/%s", home, m->name, MODULE_ARCH); | ||
128 | m->bin_dir = eina_stringshare_add(buf); | ||
129 | snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/modules/%s", home, m->name); | ||
130 | m->data_dir = eina_stringshare_add(buf); | ||
131 | } | ||
132 | else | ||
133 | { | ||
134 | if (m->module) | ||
135 | { | ||
136 | eina_module_unload(m->module); | ||
137 | eina_module_free(m->module); | ||
138 | m->module = NULL; | ||
139 | } | ||
140 | return EINA_FALSE; | ||
141 | } | ||
142 | } | ||
143 | else if (m->module) | ||
144 | { | ||
145 | eina_module_free(m->module); | ||
146 | m->module = NULL; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | if (!m->module) | ||
151 | { | ||
152 | snprintf(buf, sizeof(buf), "%s/elementary/modules/%s/%s/module" EFL_SHARED_EXTENSION, _elm_lib_dir, m->name, MODULE_ARCH); | ||
153 | m->module = eina_module_new(buf); | ||
154 | if (m->module && eina_module_load (m->module) == EINA_TRUE) | ||
155 | { | ||
156 | m->init_func = eina_module_symbol_get(m->module, "elm_modapi_init"); | ||
157 | if (m->init_func) | ||
158 | { | ||
159 | m->shutdown_func = eina_module_symbol_get(m->module, "elm_modapi_shutdown"); | ||
160 | m->so_path = eina_stringshare_add(buf); | ||
161 | snprintf(buf, sizeof(buf), "%s/elementary/modules/%s/%s", _elm_lib_dir, m->name, MODULE_ARCH); | ||
162 | m->bin_dir = eina_stringshare_add(buf); | ||
163 | snprintf(buf, sizeof(buf), "%s/elementary/modules/%s", _elm_lib_dir, m->name); | ||
164 | m->data_dir = eina_stringshare_add(buf); | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | if (m->module) | ||
169 | { | ||
170 | eina_module_unload(m->module); | ||
171 | eina_module_free(m->module); | ||
172 | m->module = NULL; | ||
173 | } | ||
174 | return EINA_FALSE; | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | else if (m->module) | ||
179 | { | ||
180 | eina_module_free(m->module); | ||
181 | m->module = NULL; | ||
182 | } | ||
183 | |||
184 | if (!m->module) return EINA_FALSE; | ||
185 | return EINA_TRUE; | ||
186 | } | ||
187 | |||
188 | void | ||
189 | _elm_module_unload(Elm_Module *m) | ||
190 | { | ||
191 | eina_stringshare_del(m->so_path); | ||
192 | eina_stringshare_del(m->data_dir); | ||
193 | eina_stringshare_del(m->bin_dir); | ||
194 | if (m->api) | ||
195 | { | ||
196 | free(m->api); | ||
197 | m->api = NULL; | ||
198 | } | ||
199 | if (m->module) | ||
200 | { | ||
201 | if (m->shutdown_func) m->shutdown_func(m); | ||
202 | eina_module_unload(m->module); | ||
203 | eina_module_free(m->module); | ||
204 | m->module = NULL; | ||
205 | } | ||
206 | m->shutdown_func = NULL; | ||
207 | m->init_func = NULL; | ||
208 | } | ||
209 | |||
210 | Elm_Module * | ||
211 | _elm_module_add(const char *name, const char *as) | ||
212 | { | ||
213 | Elm_Module *m; | ||
214 | |||
215 | if (name[0] == '/') return NULL; | ||
216 | |||
217 | m = eina_hash_find(modules, name); | ||
218 | if (m) | ||
219 | { | ||
220 | m->references++; | ||
221 | return m; | ||
222 | } | ||
223 | m = calloc(1, sizeof(Elm_Module)); | ||
224 | if (!m) return NULL; | ||
225 | m->version = 1; | ||
226 | m->name = eina_stringshare_add(name); | ||
227 | m->references = 1; | ||
228 | eina_hash_direct_add(modules, m->name, m); | ||
229 | m->as = eina_stringshare_add(as); | ||
230 | eina_hash_direct_add(modules_as, m->as, m); | ||
231 | return m; | ||
232 | } | ||
233 | |||
234 | void | ||
235 | _elm_module_del(Elm_Module *m) | ||
236 | { | ||
237 | m->references--; | ||
238 | if (m->references > 0) return; | ||
239 | _elm_module_unload(m); | ||
240 | eina_hash_del(modules, m->name, m); | ||
241 | eina_hash_del(modules_as, m->as, m); | ||
242 | eina_stringshare_del(m->name); | ||
243 | eina_stringshare_del(m->as); | ||
244 | free(m); | ||
245 | } | ||
246 | |||
247 | const void * | ||
248 | _elm_module_symbol_get(Elm_Module *m, const char *name) | ||
249 | { | ||
250 | return eina_module_symbol_get(m->module, name); | ||
251 | } | ||