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.
This commit is contained in:
parent
ca39ff976e
commit
c0c5736a4e
|
@ -549,6 +549,8 @@ AC_ARG_ENABLE([systemd],
|
|||
fi
|
||||
],
|
||||
[want_systemd="no"])
|
||||
AM_CONDITIONAL([WANT_SYSTEMD], [test "${want_systemd}" = "yes"])
|
||||
|
||||
|
||||
#### Platform-dependent
|
||||
DL_LIBS=""
|
||||
|
|
|
@ -21,6 +21,12 @@ eezefilesdir = $(datadir)/eeze
|
|||
eezefiles_DATA = eeze/checkme
|
||||
EXTRA_DIST += $(eezefiles_DATA)
|
||||
|
||||
########################################################################
|
||||
# Ecore
|
||||
ecorefilesdir = $(datadir)/ecore
|
||||
ecorefiles_DATA = ecore/checkme
|
||||
EXTRA_DIST += $(ecorefiles_DATA)
|
||||
|
||||
########################################################################
|
||||
# Ecore_Imf
|
||||
ecoreimffilesdir = $(datadir)/ecore_imf
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
This is just a test file used to help ecore determine its prefix location.
|
|
@ -2,6 +2,8 @@ prefix=@prefix@
|
|||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
modules=@libdir@/ecore
|
||||
module_arch=@MODULE_ARCH@
|
||||
|
||||
Name: ecore
|
||||
Description: Ecore event abstraction library
|
||||
|
|
|
@ -52,11 +52,41 @@ lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_signal.c lib/ecore/ecore_exe.c
|
|||
endif
|
||||
endif
|
||||
|
||||
lib_ecore_libecore_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_CFLAGS@
|
||||
lib_ecore_libecore_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
|
||||
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
|
||||
-DPACKAGE_DATA_DIR=\"$(datadir)/ecore\" \
|
||||
-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" \
|
||||
@ECORE_CFLAGS@
|
||||
lib_ecore_libecore_la_LIBADD = @ECORE_LIBS@
|
||||
lib_ecore_libecore_la_DEPENDENCIES = @ECORE_INTERNAL_LIBS@
|
||||
lib_ecore_libecore_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
|
||||
|
||||
|
||||
### Modules
|
||||
|
||||
# systemd
|
||||
|
||||
if WANT_SYSTEMD
|
||||
ecoresystemdpkgdir = $(libdir)/ecore/system/systemd/$(MODULE_ARCH)
|
||||
ecoresystemdpkg_LTLIBRARIES = modules/ecore/system/systemd/module.la
|
||||
modules_ecore_system_systemd_module_la_SOURCES = \
|
||||
modules/ecore/system/systemd/ecore_system_systemd.c
|
||||
modules_ecore_system_systemd_module_la_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
@ECORE_CFLAGS@ \
|
||||
@ELDBUS_CFLAGS@
|
||||
modules_ecore_system_systemd_module_la_LIBADD = \
|
||||
@USE_ECORE_LIBS@ \
|
||||
@USE_ELDBUS_LIBS@
|
||||
modules_ecore_system_systemd_module_la_DEPENDENCIES = \
|
||||
@USE_ECORE_INTERNAL_LIBS@ \
|
||||
@USE_ELDBUS_INTERNAL_LIBS@
|
||||
modules_ecore_system_systemd_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
modules_ecore_system_systemd_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
|
||||
### Unit tests
|
||||
|
||||
if EFL_ENABLE_TESTS
|
||||
|
|
|
@ -116,6 +116,77 @@ int _ecore_main_lock_count;
|
|||
# define CODESET "INVALID"
|
||||
#endif
|
||||
|
||||
static Eina_Prefix *_ecore_pfx = NULL;
|
||||
static Eina_Array *module_list = NULL;
|
||||
|
||||
static void
|
||||
ecore_system_modules_load(void)
|
||||
{
|
||||
char buf[PATH_MAX] = "";
|
||||
char *path;
|
||||
|
||||
if (getenv("EFL_RUN_IN_TREE"))
|
||||
{
|
||||
struct stat st;
|
||||
snprintf(buf, sizeof(buf), "%s/src/modules/ecore/system",
|
||||
PACKAGE_BUILD_DIR);
|
||||
if (stat(buf, &st) == 0)
|
||||
{
|
||||
const char *built_modules[] = {
|
||||
#ifdef HAVE_SYSTEMD
|
||||
"systemd",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
const char **itr;
|
||||
for (itr = built_modules; *itr != NULL; itr++)
|
||||
{
|
||||
snprintf(buf, sizeof(buf),
|
||||
"%s/src/modules/ecore/system/%s/.libs",
|
||||
PACKAGE_BUILD_DIR, *itr);
|
||||
module_list = eina_module_list_get(module_list, buf,
|
||||
EINA_FALSE, NULL, NULL);
|
||||
}
|
||||
|
||||
if (module_list)
|
||||
eina_module_list_load(module_list);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
path = eina_module_environment_path_get("ECORE_MODULES_DIR",
|
||||
"/ecore/system");
|
||||
if (path)
|
||||
{
|
||||
module_list = eina_module_arch_list_get(module_list, path, MODULE_ARCH);
|
||||
free(path);
|
||||
}
|
||||
|
||||
path = eina_module_environment_path_get("HOME", "/.ecore/system");
|
||||
if (path)
|
||||
{
|
||||
module_list = eina_module_arch_list_get(module_list, path, MODULE_ARCH);
|
||||
free(path);
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/ecore/system",
|
||||
eina_prefix_lib_get(_ecore_pfx));
|
||||
module_list = eina_module_arch_list_get(module_list, buf, MODULE_ARCH);
|
||||
|
||||
eina_module_list_load(module_list);
|
||||
}
|
||||
|
||||
static void
|
||||
ecore_system_modules_unload(void)
|
||||
{
|
||||
if (module_list)
|
||||
{
|
||||
eina_module_list_free(module_list);
|
||||
eina_array_free(module_list);
|
||||
module_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup Ecore_Init_Group
|
||||
*
|
||||
|
@ -170,6 +241,16 @@ ecore_init(void)
|
|||
goto shutdown_log_dom;
|
||||
}
|
||||
|
||||
_ecore_pfx = eina_prefix_new(NULL, ecore_init,
|
||||
"ECORE", "ecore", "checkme",
|
||||
PACKAGE_BIN_DIR, PACKAGE_LIB_DIR,
|
||||
PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
|
||||
if (!_ecore_pfx)
|
||||
{
|
||||
ERR("Could not get ecore installation prefix");
|
||||
goto shutdown_log_dom;
|
||||
}
|
||||
|
||||
eo_init();
|
||||
|
||||
if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
|
||||
|
@ -230,6 +311,9 @@ ecore_init(void)
|
|||
EINA_LOG_STATE_STOP,
|
||||
EINA_LOG_STATE_INIT);
|
||||
|
||||
|
||||
ecore_system_modules_load();
|
||||
|
||||
return _ecore_init_count;
|
||||
|
||||
shutdown_mempool:
|
||||
|
@ -273,6 +357,8 @@ ecore_shutdown(void)
|
|||
if (--_ecore_init_count != 0)
|
||||
goto unlock;
|
||||
|
||||
ecore_system_modules_unload();
|
||||
|
||||
eina_log_timing(_ecore_log_dom,
|
||||
EINA_LOG_STATE_START,
|
||||
EINA_LOG_STATE_SHUTDOWN);
|
||||
|
@ -345,6 +431,10 @@ ecore_shutdown(void)
|
|||
ecore_mempool_shutdown();
|
||||
eina_log_domain_unregister(_ecore_log_dom);
|
||||
_ecore_log_dom = -1;
|
||||
|
||||
eina_prefix_free(_ecore_pfx);
|
||||
_ecore_pfx = NULL;
|
||||
|
||||
eina_shutdown();
|
||||
#ifdef HAVE_EVIL
|
||||
evil_shutdown();
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eldbus.h>
|
||||
#include <Ecore.h>
|
||||
#include <locale.h>
|
||||
|
||||
static int _log_dom = -1;
|
||||
static Eldbus_Connection *_conn = NULL;
|
||||
|
||||
static Eina_List *_objs = NULL;
|
||||
static Eina_List *_proxies = NULL;
|
||||
|
||||
#ifdef CRITICAL
|
||||
#undef CRITICAL
|
||||
#endif
|
||||
#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifdef ERR
|
||||
#undef ERR
|
||||
#endif
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifdef WRN
|
||||
#undef WRN
|
||||
#endif
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#endif
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
|
||||
|
||||
|
||||
static void
|
||||
_props_changed_hostname(void *data EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
Eldbus_Message_Iter *changed, *entry, *invalidated;
|
||||
const char *iface, *prop;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sa{sv}as",
|
||||
&iface, &changed, &invalidated))
|
||||
{
|
||||
ERR("Error getting data from properties changed signal.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(changed, 'e', &entry))
|
||||
{
|
||||
const void *key;
|
||||
Eldbus_Message_Iter *var;
|
||||
if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var))
|
||||
continue;
|
||||
if (strcmp(key, "Hostname") == 0)
|
||||
goto changed_hostname;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(invalidated, 's', &prop))
|
||||
{
|
||||
if (strcmp(prop, "Hostname") == 0)
|
||||
goto changed_hostname;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
changed_hostname:
|
||||
ecore_event_add(ECORE_EVENT_HOSTNAME_CHANGED, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_props_changed_timedate(void *data EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
Eldbus_Message_Iter *changed, *entry, *invalidated;
|
||||
const char *iface, *prop;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sa{sv}as",
|
||||
&iface, &changed, &invalidated))
|
||||
{
|
||||
ERR("Error getting data from properties changed signal.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(changed, 'e', &entry))
|
||||
{
|
||||
const void *key;
|
||||
Eldbus_Message_Iter *var;
|
||||
if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var))
|
||||
continue;
|
||||
if (strcmp(key, "Timezone") == 0)
|
||||
goto changed_timedate;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(invalidated, 's', &prop))
|
||||
{
|
||||
if (strcmp(prop, "Timezone") == 0)
|
||||
goto changed_timedate;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
changed_timedate:
|
||||
ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
struct locale_cat_desc {
|
||||
int cat;
|
||||
int namelen;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct locale_cat_desc locale_cat_desc[] = {
|
||||
#define CAT(name) {name, sizeof(#name) - 1, #name}
|
||||
CAT(LC_CTYPE),
|
||||
CAT(LC_NUMERIC),
|
||||
CAT(LC_TIME),
|
||||
CAT(LC_COLLATE),
|
||||
CAT(LC_MONETARY),
|
||||
CAT(LC_MESSAGES),
|
||||
CAT(LC_ALL),
|
||||
CAT(LC_PAPER),
|
||||
CAT(LC_NAME),
|
||||
CAT(LC_ADDRESS),
|
||||
CAT(LC_TELEPHONE),
|
||||
CAT(LC_MEASUREMENT),
|
||||
CAT(LC_IDENTIFICATION),
|
||||
#undef CAT
|
||||
{-1, -1, NULL}
|
||||
};
|
||||
|
||||
static int _locale_parse(const char *str, int *cat, const char **value)
|
||||
{
|
||||
const struct locale_cat_desc *itr;
|
||||
const char *p = strchr(str, '=');
|
||||
int klen;
|
||||
|
||||
if (!p) goto end;
|
||||
|
||||
klen = p - str;
|
||||
for (itr = locale_cat_desc; itr->name != NULL; itr++)
|
||||
{
|
||||
if ((klen == itr->namelen) && (memcmp(str, itr->name, klen) == 0))
|
||||
{
|
||||
*cat = itr->cat;
|
||||
*value = str + itr->namelen + 1;
|
||||
return itr - locale_cat_desc;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
*cat = -1;
|
||||
*value = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _locale_get(void *data EINA_UNUSED, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *variant, *array;
|
||||
const char *errname, *errmsg, *val;
|
||||
Eina_Bool setlocs[EINA_C_ARRAY_LENGTH(locale_cat_desc)];
|
||||
unsigned int i;
|
||||
|
||||
if (eldbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
ERR("Message error %s - %s", errname, errmsg);
|
||||
goto end;
|
||||
}
|
||||
if (!eldbus_message_arguments_get(msg, "v", &variant))
|
||||
{
|
||||
ERR("Error getting arguments.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!eldbus_message_iter_get_and_next(variant, 'a', &array))
|
||||
{
|
||||
ERR("Error getting array.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
memset(setlocs, 0, sizeof(setlocs));
|
||||
while (eldbus_message_iter_get_and_next(array, 's', &val))
|
||||
{
|
||||
int cat, idx;
|
||||
const char *value;
|
||||
idx = _locale_parse(val, &cat, &value);
|
||||
if (idx >= 0)
|
||||
setlocs[idx] = EINA_TRUE;
|
||||
setlocale(cat, value);
|
||||
}
|
||||
|
||||
for (i = 0; i < EINA_C_ARRAY_LENGTH(locale_cat_desc); i++)
|
||||
{
|
||||
if ((!setlocs[i]) && (locale_cat_desc[i].cat != LC_ALL))
|
||||
setlocale(locale_cat_desc[i].cat, "C");
|
||||
}
|
||||
|
||||
end:
|
||||
ecore_event_add(ECORE_EVENT_LOCALE_CHANGED, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_props_changed_locale(void *data, const Eldbus_Message *msg)
|
||||
{
|
||||
Eldbus_Proxy *proxy = data;
|
||||
Eldbus_Message_Iter *changed, *entry, *invalidated;
|
||||
const char *iface, *prop;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sa{sv}as",
|
||||
&iface, &changed, &invalidated))
|
||||
{
|
||||
ERR("Error getting data from properties changed signal.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(changed, 'e', &entry))
|
||||
{
|
||||
const void *key;
|
||||
Eldbus_Message_Iter *var;
|
||||
if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var))
|
||||
continue;
|
||||
if (strcmp(key, "Locale") == 0)
|
||||
goto changed_locale;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(invalidated, 's', &prop))
|
||||
{
|
||||
if (strcmp(prop, "Locale") == 0)
|
||||
goto changed_locale;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
changed_locale:
|
||||
eldbus_proxy_property_get(proxy, "Locale", _locale_get, NULL);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_property_change_monitor(const char *name,
|
||||
const char *path,
|
||||
const char *iface,
|
||||
Eldbus_Signal_Cb cb)
|
||||
{
|
||||
Eldbus_Object *o;
|
||||
Eldbus_Proxy *p;
|
||||
Eldbus_Signal_Handler *s;
|
||||
|
||||
o = eldbus_object_get(_conn, name, path);
|
||||
if (!o)
|
||||
{
|
||||
ERR("could not get object name=%s, path=%s", name, path);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
p = eldbus_proxy_get(o, iface);
|
||||
if (!p)
|
||||
{
|
||||
ERR("could not get proxy interface=%s, name=%s, path=%s",
|
||||
iface, name, path);
|
||||
eldbus_object_unref(o);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
s = eldbus_proxy_properties_changed_callback_add(p, cb, p);
|
||||
if (!s)
|
||||
{
|
||||
ERR("could not add signal handler for properties changed for proxy "
|
||||
"interface=%s, name=%s, path=%s", iface, name, path);
|
||||
eldbus_proxy_unref(p);
|
||||
eldbus_object_unref(o);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
_objs = eina_list_append(_objs, o);
|
||||
_proxies = eina_list_append(_proxies, p);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void _ecore_system_systemd_shutdown(void);
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_system_systemd_init(void)
|
||||
{
|
||||
eldbus_init();
|
||||
|
||||
_log_dom = eina_log_domain_register("ecore_system_systemd", NULL);
|
||||
if (_log_dom < 0)
|
||||
{
|
||||
EINA_LOG_ERR("Could not register log domain: ecore_system_systemd");
|
||||
goto error;
|
||||
}
|
||||
|
||||
_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
|
||||
|
||||
if (!_property_change_monitor("org.freedesktop.hostname1",
|
||||
"/org/freedesktop/hostname1",
|
||||
"org.freedesktop.hostname1",
|
||||
_props_changed_hostname))
|
||||
goto error;
|
||||
|
||||
if (!_property_change_monitor("org.freedesktop.timedate1",
|
||||
"/org/freedesktop/timedate1",
|
||||
"org.freedesktop.timedate1",
|
||||
_props_changed_timedate))
|
||||
goto error;
|
||||
|
||||
if (!_property_change_monitor("org.freedesktop.locale1",
|
||||
"/org/freedesktop/locale1",
|
||||
"org.freedesktop.locale1",
|
||||
_props_changed_locale))
|
||||
goto error;
|
||||
|
||||
DBG("ecore system 'systemd' loaded");
|
||||
return EINA_TRUE;
|
||||
|
||||
error:
|
||||
_ecore_system_systemd_shutdown();
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_system_systemd_shutdown(void)
|
||||
{
|
||||
DBG("ecore system 'systemd' unloaded");
|
||||
|
||||
while (_proxies)
|
||||
{
|
||||
eldbus_proxy_unref(_proxies->data);
|
||||
_proxies = eina_list_remove_list(_proxies, _proxies);
|
||||
}
|
||||
|
||||
while (_objs)
|
||||
{
|
||||
eldbus_object_unref(_objs->data);
|
||||
_objs = eina_list_remove_list(_objs, _objs);
|
||||
}
|
||||
|
||||
if (_conn)
|
||||
{
|
||||
eldbus_connection_unref(_conn);
|
||||
_conn = NULL;
|
||||
}
|
||||
|
||||
if (_log_dom > 0)
|
||||
{
|
||||
eina_log_domain_unregister(_log_dom);
|
||||
_log_dom = -1;
|
||||
}
|
||||
|
||||
eldbus_shutdown();
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(_ecore_system_systemd_init);
|
||||
EINA_MODULE_SHUTDOWN(_ecore_system_systemd_shutdown);
|
Loading…
Reference in New Issue