summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-08-08 20:32:53 -0300
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-08-09 14:28:02 -0300
commitc0c5736a4e0d41adc9c97577006c289718c926de (patch)
tree50bc5feedd13d4c4fca49aeb55842008fd3100b7
parentca39ff976e576dd917becf989f28fdf149c9f1d0 (diff)
ecore: add system modules, implement 'systemd'.
Ecore will now load "system modules" on ecore_init(). The "systemd" module will use DBus to monitor localed, hostnamed and timedated and add system events related to those changes.
-rw-r--r--configure.ac2
-rw-r--r--data/Makefile.am6
-rw-r--r--data/ecore/checkme1
-rw-r--r--pc/ecore.pc.in2
-rw-r--r--src/Makefile_Ecore.am32
-rw-r--r--src/lib/ecore/ecore.c90
-rw-r--r--src/modules/ecore/system/systemd/ecore_system_systemd.c354
7 files changed, 486 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 0d4f96bbf7..1a01978bb8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -549,6 +549,8 @@ AC_ARG_ENABLE([systemd],
549 fi 549 fi
550 ], 550 ],
551 [want_systemd="no"]) 551 [want_systemd="no"])
552AM_CONDITIONAL([WANT_SYSTEMD], [test "${want_systemd}" = "yes"])
553
552 554
553#### Platform-dependent 555#### Platform-dependent
554DL_LIBS="" 556DL_LIBS=""
diff --git a/data/Makefile.am b/data/Makefile.am
index e6926e5a8b..5cd88de865 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -22,6 +22,12 @@ eezefiles_DATA = eeze/checkme
22EXTRA_DIST += $(eezefiles_DATA) 22EXTRA_DIST += $(eezefiles_DATA)
23 23
24######################################################################## 24########################################################################
25# Ecore
26ecorefilesdir = $(datadir)/ecore
27ecorefiles_DATA = ecore/checkme
28EXTRA_DIST += $(ecorefiles_DATA)
29
30########################################################################
25# Ecore_Imf 31# Ecore_Imf
26ecoreimffilesdir = $(datadir)/ecore_imf 32ecoreimffilesdir = $(datadir)/ecore_imf
27ecoreimffiles_DATA = ecore_imf/checkme 33ecoreimffiles_DATA = ecore_imf/checkme
diff --git a/data/ecore/checkme b/data/ecore/checkme
new file mode 100644
index 0000000000..1688a66696
--- /dev/null
+++ b/data/ecore/checkme
@@ -0,0 +1 @@
This is just a test file used to help ecore determine its prefix location.
diff --git a/pc/ecore.pc.in b/pc/ecore.pc.in
index 2f0de2a907..ab7004a420 100644
--- a/pc/ecore.pc.in
+++ b/pc/ecore.pc.in
@@ -2,6 +2,8 @@ prefix=@prefix@
2exec_prefix=@exec_prefix@ 2exec_prefix=@exec_prefix@
3libdir=@libdir@ 3libdir=@libdir@
4includedir=@includedir@ 4includedir=@includedir@
5modules=@libdir@/ecore
6module_arch=@MODULE_ARCH@
5 7
6Name: ecore 8Name: ecore
7Description: Ecore event abstraction library 9Description: Ecore event abstraction library
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index 40329a06c3..5e6515ba56 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -52,11 +52,41 @@ lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_signal.c lib/ecore/ecore_exe.c
52endif 52endif
53endif 53endif
54 54
55lib_ecore_libecore_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_CFLAGS@ 55lib_ecore_libecore_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
56-DPACKAGE_BIN_DIR=\"$(bindir)\" \
57-DPACKAGE_LIB_DIR=\"$(libdir)\" \
58-DPACKAGE_DATA_DIR=\"$(datadir)/ecore\" \
59-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" \
60@ECORE_CFLAGS@
56lib_ecore_libecore_la_LIBADD = @ECORE_LIBS@ 61lib_ecore_libecore_la_LIBADD = @ECORE_LIBS@
57lib_ecore_libecore_la_DEPENDENCIES = @ECORE_INTERNAL_LIBS@ 62lib_ecore_libecore_la_DEPENDENCIES = @ECORE_INTERNAL_LIBS@
58lib_ecore_libecore_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ 63lib_ecore_libecore_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
59 64
65
66### Modules
67
68# systemd
69
70if WANT_SYSTEMD
71ecoresystemdpkgdir = $(libdir)/ecore/system/systemd/$(MODULE_ARCH)
72ecoresystemdpkg_LTLIBRARIES = modules/ecore/system/systemd/module.la
73modules_ecore_system_systemd_module_la_SOURCES = \
74modules/ecore/system/systemd/ecore_system_systemd.c
75modules_ecore_system_systemd_module_la_CPPFLAGS = \
76-I$(top_builddir)/src/lib/efl \
77@ECORE_CFLAGS@ \
78@ELDBUS_CFLAGS@
79modules_ecore_system_systemd_module_la_LIBADD = \
80@USE_ECORE_LIBS@ \
81@USE_ELDBUS_LIBS@
82modules_ecore_system_systemd_module_la_DEPENDENCIES = \
83@USE_ECORE_INTERNAL_LIBS@ \
84@USE_ELDBUS_INTERNAL_LIBS@
85modules_ecore_system_systemd_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
86modules_ecore_system_systemd_module_la_LIBTOOLFLAGS = --tag=disable-static
87endif
88
89
60### Unit tests 90### Unit tests
61 91
62if EFL_ENABLE_TESTS 92if EFL_ENABLE_TESTS
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c
index 28726a2229..489dc6074d 100644
--- a/src/lib/ecore/ecore.c
+++ b/src/lib/ecore/ecore.c
@@ -116,6 +116,77 @@ int _ecore_main_lock_count;
116# define CODESET "INVALID" 116# define CODESET "INVALID"
117#endif 117#endif
118 118
119static Eina_Prefix *_ecore_pfx = NULL;
120static Eina_Array *module_list = NULL;
121
122static void
123ecore_system_modules_load(void)
124{
125 char buf[PATH_MAX] = "";
126 char *path;
127
128 if (getenv("EFL_RUN_IN_TREE"))
129 {
130 struct stat st;
131 snprintf(buf, sizeof(buf), "%s/src/modules/ecore/system",
132 PACKAGE_BUILD_DIR);
133 if (stat(buf, &st) == 0)
134 {
135 const char *built_modules[] = {
136#ifdef HAVE_SYSTEMD
137 "systemd",
138#endif
139 NULL
140 };
141 const char **itr;
142 for (itr = built_modules; *itr != NULL; itr++)
143 {
144 snprintf(buf, sizeof(buf),
145 "%s/src/modules/ecore/system/%s/.libs",
146 PACKAGE_BUILD_DIR, *itr);
147 module_list = eina_module_list_get(module_list, buf,
148 EINA_FALSE, NULL, NULL);
149 }
150
151 if (module_list)
152 eina_module_list_load(module_list);
153 return;
154 }
155 }
156
157 path = eina_module_environment_path_get("ECORE_MODULES_DIR",
158 "/ecore/system");
159 if (path)
160 {
161 module_list = eina_module_arch_list_get(module_list, path, MODULE_ARCH);
162 free(path);
163 }
164
165 path = eina_module_environment_path_get("HOME", "/.ecore/system");
166 if (path)
167 {
168 module_list = eina_module_arch_list_get(module_list, path, MODULE_ARCH);
169 free(path);
170 }
171
172 snprintf(buf, sizeof(buf), "%s/ecore/system",
173 eina_prefix_lib_get(_ecore_pfx));
174 module_list = eina_module_arch_list_get(module_list, buf, MODULE_ARCH);
175
176 eina_module_list_load(module_list);
177}
178
179static void
180ecore_system_modules_unload(void)
181{
182 if (module_list)
183 {
184 eina_module_list_free(module_list);
185 eina_array_free(module_list);
186 module_list = NULL;
187 }
188}
189
119/** 190/**
120 * @addtogroup Ecore_Init_Group 191 * @addtogroup Ecore_Init_Group
121 * 192 *
@@ -170,6 +241,16 @@ ecore_init(void)
170 goto shutdown_log_dom; 241 goto shutdown_log_dom;
171 } 242 }
172 243
244 _ecore_pfx = eina_prefix_new(NULL, ecore_init,
245 "ECORE", "ecore", "checkme",
246 PACKAGE_BIN_DIR, PACKAGE_LIB_DIR,
247 PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
248 if (!_ecore_pfx)
249 {
250 ERR("Could not get ecore installation prefix");
251 goto shutdown_log_dom;
252 }
253
173 eo_init(); 254 eo_init();
174 255
175 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1; 256 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
@@ -230,6 +311,9 @@ ecore_init(void)
230 EINA_LOG_STATE_STOP, 311 EINA_LOG_STATE_STOP,
231 EINA_LOG_STATE_INIT); 312 EINA_LOG_STATE_INIT);
232 313
314
315 ecore_system_modules_load();
316
233 return _ecore_init_count; 317 return _ecore_init_count;
234 318
235shutdown_mempool: 319shutdown_mempool:
@@ -273,6 +357,8 @@ ecore_shutdown(void)
273 if (--_ecore_init_count != 0) 357 if (--_ecore_init_count != 0)
274 goto unlock; 358 goto unlock;
275 359
360 ecore_system_modules_unload();
361
276 eina_log_timing(_ecore_log_dom, 362 eina_log_timing(_ecore_log_dom,
277 EINA_LOG_STATE_START, 363 EINA_LOG_STATE_START,
278 EINA_LOG_STATE_SHUTDOWN); 364 EINA_LOG_STATE_SHUTDOWN);
@@ -345,6 +431,10 @@ ecore_shutdown(void)
345 ecore_mempool_shutdown(); 431 ecore_mempool_shutdown();
346 eina_log_domain_unregister(_ecore_log_dom); 432 eina_log_domain_unregister(_ecore_log_dom);
347 _ecore_log_dom = -1; 433 _ecore_log_dom = -1;
434
435 eina_prefix_free(_ecore_pfx);
436 _ecore_pfx = NULL;
437
348 eina_shutdown(); 438 eina_shutdown();
349#ifdef HAVE_EVIL 439#ifdef HAVE_EVIL
350 evil_shutdown(); 440 evil_shutdown();
diff --git a/src/modules/ecore/system/systemd/ecore_system_systemd.c b/src/modules/ecore/system/systemd/ecore_system_systemd.c
new file mode 100644
index 0000000000..0943775ead
--- /dev/null
+++ b/src/modules/ecore/system/systemd/ecore_system_systemd.c
@@ -0,0 +1,354 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eldbus.h>
6#include <Ecore.h>
7#include <locale.h>
8
9static int _log_dom = -1;
10static Eldbus_Connection *_conn = NULL;
11
12static Eina_List *_objs = NULL;
13static Eina_List *_proxies = NULL;
14
15#ifdef CRITICAL
16#undef CRITICAL
17#endif
18#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
19
20#ifdef ERR
21#undef ERR
22#endif
23#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
24
25#ifdef WRN
26#undef WRN
27#endif
28#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
29
30#ifdef DBG
31#undef DBG
32#endif
33#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
34
35
36static void
37_props_changed_hostname(void *data EINA_UNUSED, const Eldbus_Message *msg)
38{
39 Eldbus_Message_Iter *changed, *entry, *invalidated;
40 const char *iface, *prop;
41
42 if (!eldbus_message_arguments_get(msg, "sa{sv}as",
43 &iface, &changed, &invalidated))
44 {
45 ERR("Error getting data from properties changed signal.");
46 return;
47 }
48
49 while (eldbus_message_iter_get_and_next(changed, 'e', &entry))
50 {
51 const void *key;
52 Eldbus_Message_Iter *var;
53 if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var))
54 continue;
55 if (strcmp(key, "Hostname") == 0)
56 goto changed_hostname;
57 }
58
59 while (eldbus_message_iter_get_and_next(invalidated, 's', &prop))
60 {
61 if (strcmp(prop, "Hostname") == 0)
62 goto changed_hostname;
63 }
64
65 return;
66
67 changed_hostname:
68 ecore_event_add(ECORE_EVENT_HOSTNAME_CHANGED, NULL, NULL, NULL);
69}
70
71static void
72_props_changed_timedate(void *data EINA_UNUSED, const Eldbus_Message *msg)
73{
74 Eldbus_Message_Iter *changed, *entry, *invalidated;
75 const char *iface, *prop;
76
77 if (!eldbus_message_arguments_get(msg, "sa{sv}as",
78 &iface, &changed, &invalidated))
79 {
80 ERR("Error getting data from properties changed signal.");
81 return;
82 }
83
84 while (eldbus_message_iter_get_and_next(changed, 'e', &entry))
85 {
86 const void *key;
87 Eldbus_Message_Iter *var;
88 if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var))
89 continue;
90 if (strcmp(key, "Timezone") == 0)
91 goto changed_timedate;
92 }
93
94 while (eldbus_message_iter_get_and_next(invalidated, 's', &prop))
95 {
96 if (strcmp(prop, "Timezone") == 0)
97 goto changed_timedate;
98 }
99
100 return;
101
102 changed_timedate:
103 ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL);
104}
105
106struct locale_cat_desc {
107 int cat;
108 int namelen;
109 const char *name;
110};
111
112static const struct locale_cat_desc locale_cat_desc[] = {
113#define CAT(name) {name, sizeof(#name) - 1, #name}
114 CAT(LC_CTYPE),
115 CAT(LC_NUMERIC),
116 CAT(LC_TIME),
117 CAT(LC_COLLATE),
118 CAT(LC_MONETARY),
119 CAT(LC_MESSAGES),
120 CAT(LC_ALL),
121 CAT(LC_PAPER),
122 CAT(LC_NAME),
123 CAT(LC_ADDRESS),
124 CAT(LC_TELEPHONE),
125 CAT(LC_MEASUREMENT),
126 CAT(LC_IDENTIFICATION),
127#undef CAT
128 {-1, -1, NULL}
129};
130
131static int _locale_parse(const char *str, int *cat, const char **value)
132{
133 const struct locale_cat_desc *itr;
134 const char *p = strchr(str, '=');
135 int klen;
136
137 if (!p) goto end;
138
139 klen = p - str;
140 for (itr = locale_cat_desc; itr->name != NULL; itr++)
141 {
142 if ((klen == itr->namelen) && (memcmp(str, itr->name, klen) == 0))
143 {
144 *cat = itr->cat;
145 *value = str + itr->namelen + 1;
146 return itr - locale_cat_desc;
147 }
148 }
149
150 end:
151 *cat = -1;
152 *value = NULL;
153 return -1;
154}
155
156static void _locale_get(void *data EINA_UNUSED, const Eldbus_Message *msg,
157 Eldbus_Pending *pending EINA_UNUSED)
158{
159 Eldbus_Message_Iter *variant, *array;
160 const char *errname, *errmsg, *val;
161 Eina_Bool setlocs[EINA_C_ARRAY_LENGTH(locale_cat_desc)];
162 unsigned int i;
163
164 if (eldbus_message_error_get(msg, &errname, &errmsg))
165 {
166 ERR("Message error %s - %s", errname, errmsg);
167 goto end;
168 }
169 if (!eldbus_message_arguments_get(msg, "v", &variant))
170 {
171 ERR("Error getting arguments.");
172 goto end;
173 }
174
175 if (!eldbus_message_iter_get_and_next(variant, 'a', &array))
176 {
177 ERR("Error getting array.");
178 goto end;
179 }
180
181 memset(setlocs, 0, sizeof(setlocs));
182 while (eldbus_message_iter_get_and_next(array, 's', &val))
183 {
184 int cat, idx;
185 const char *value;
186 idx = _locale_parse(val, &cat, &value);
187 if (idx >= 0)
188 setlocs[idx] = EINA_TRUE;
189 setlocale(cat, value);
190 }
191
192 for (i = 0; i < EINA_C_ARRAY_LENGTH(locale_cat_desc); i++)
193 {
194 if ((!setlocs[i]) && (locale_cat_desc[i].cat != LC_ALL))
195 setlocale(locale_cat_desc[i].cat, "C");
196 }
197
198 end:
199 ecore_event_add(ECORE_EVENT_LOCALE_CHANGED, NULL, NULL, NULL);
200}
201
202static void
203_props_changed_locale(void *data, const Eldbus_Message *msg)
204{
205 Eldbus_Proxy *proxy = data;
206 Eldbus_Message_Iter *changed, *entry, *invalidated;
207 const char *iface, *prop;
208
209 if (!eldbus_message_arguments_get(msg, "sa{sv}as",
210 &iface, &changed, &invalidated))
211 {
212 ERR("Error getting data from properties changed signal.");
213 return;
214 }
215
216 while (eldbus_message_iter_get_and_next(changed, 'e', &entry))
217 {
218 const void *key;
219 Eldbus_Message_Iter *var;
220 if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var))
221 continue;
222 if (strcmp(key, "Locale") == 0)
223 goto changed_locale;
224 }
225
226 while (eldbus_message_iter_get_and_next(invalidated, 's', &prop))
227 {
228 if (strcmp(prop, "Locale") == 0)
229 goto changed_locale;
230 }
231
232 return;
233
234 changed_locale:
235 eldbus_proxy_property_get(proxy, "Locale", _locale_get, NULL);
236}
237
238static Eina_Bool
239_property_change_monitor(const char *name,
240 const char *path,
241 const char *iface,
242 Eldbus_Signal_Cb cb)
243{
244 Eldbus_Object *o;
245 Eldbus_Proxy *p;
246 Eldbus_Signal_Handler *s;
247
248 o = eldbus_object_get(_conn, name, path);
249 if (!o)
250 {
251 ERR("could not get object name=%s, path=%s", name, path);
252 return EINA_FALSE;
253 }
254
255 p = eldbus_proxy_get(o, iface);
256 if (!p)
257 {
258 ERR("could not get proxy interface=%s, name=%s, path=%s",
259 iface, name, path);
260 eldbus_object_unref(o);
261 return EINA_FALSE;
262 }
263
264 s = eldbus_proxy_properties_changed_callback_add(p, cb, p);
265 if (!s)
266 {
267 ERR("could not add signal handler for properties changed for proxy "
268 "interface=%s, name=%s, path=%s", iface, name, path);
269 eldbus_proxy_unref(p);
270 eldbus_object_unref(o);
271 return EINA_FALSE;
272 }
273
274 _objs = eina_list_append(_objs, o);
275 _proxies = eina_list_append(_proxies, p);
276 return EINA_TRUE;
277}
278
279static void _ecore_system_systemd_shutdown(void);
280
281static Eina_Bool
282_ecore_system_systemd_init(void)
283{
284 eldbus_init();
285
286 _log_dom = eina_log_domain_register("ecore_system_systemd", NULL);
287 if (_log_dom < 0)
288 {
289 EINA_LOG_ERR("Could not register log domain: ecore_system_systemd");
290 goto error;
291 }
292
293 _conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
294
295 if (!_property_change_monitor("org.freedesktop.hostname1",
296 "/org/freedesktop/hostname1",
297 "org.freedesktop.hostname1",
298 _props_changed_hostname))
299 goto error;
300
301 if (!_property_change_monitor("org.freedesktop.timedate1",
302 "/org/freedesktop/timedate1",
303 "org.freedesktop.timedate1",
304 _props_changed_timedate))
305 goto error;
306
307 if (!_property_change_monitor("org.freedesktop.locale1",
308 "/org/freedesktop/locale1",
309 "org.freedesktop.locale1",
310 _props_changed_locale))
311 goto error;
312
313 DBG("ecore system 'systemd' loaded");
314 return EINA_TRUE;
315
316 error:
317 _ecore_system_systemd_shutdown();
318 return EINA_FALSE;
319}
320
321static void
322_ecore_system_systemd_shutdown(void)
323{
324 DBG("ecore system 'systemd' unloaded");
325
326 while (_proxies)
327 {
328 eldbus_proxy_unref(_proxies->data);
329 _proxies = eina_list_remove_list(_proxies, _proxies);
330 }
331
332 while (_objs)
333 {
334 eldbus_object_unref(_objs->data);
335 _objs = eina_list_remove_list(_objs, _objs);
336 }
337
338 if (_conn)
339 {
340 eldbus_connection_unref(_conn);
341 _conn = NULL;
342 }
343
344 if (_log_dom > 0)
345 {
346 eina_log_domain_unregister(_log_dom);
347 _log_dom = -1;
348 }
349
350 eldbus_shutdown();
351}
352
353EINA_MODULE_INIT(_ecore_system_systemd_init);
354EINA_MODULE_SHUTDOWN(_ecore_system_systemd_shutdown);