efl - efreetd service move from dbus session bus to ecore ipc

this fixes warnings about no efreet dbus session bus in non session
environments as brought up on the mailing lists with:

Subject: Re: [E-devel] [EGIT] [core/efl] master 01/01: edje: unset
efreet cache update flag to prevent dbus connections

this moves all of efreetd client and server to ecore ipc, with client
auto-launching efreetd if not found as a service and trying for up to
500ms to connect. efreetd times out on last connection or no
connections after 10sec so it wont hang around forever if not in use.
it seems to work in my testing, so let me know if there is an issue.

@fix
This commit is contained in:
Carsten Haitzler 2015-06-24 19:24:21 +09:00
parent c6011926ba
commit 5abfefe99e
11 changed files with 456 additions and 485 deletions

View File

@ -383,13 +383,11 @@ cmakeconfig/EmileConfigVersion.cmake
servicedir = @dbusservicedir@
service_DATA = \
dbus-services/org.enlightenment.Efreet.service \
dbus-services/org.enlightenment.Ethumb.service
if HAVE_SYSTEMD_USER_SESSION
systemdunitsdir = @USER_SESSION_DIR@
systemdunits_DATA = \
systemd-services/efreet.service \
systemd-services/ethumb.service
endif
EXTRA_DIST += $(systemdunits_DATA)

View File

@ -4121,10 +4121,10 @@ EFL_PLATFORM_DEPEND([EFREET], [evil])
EFL_INTERNAL_DEPEND_PKG([EFREET], [eet])
EFL_INTERNAL_DEPEND_PKG([EFREET], [ecore])
EFL_INTERNAL_DEPEND_PKG([EFREET], [ecore-file])
EFL_INTERNAL_DEPEND_PKG([EFREET], [eldbus])
EFL_INTERNAL_DEPEND_PKG([EFREET], [eo])
EFL_INTERNAL_DEPEND_PKG([EFREET], [eina])
EFL_INTERNAL_DEPEND_PKG([EFREET], [emile])
EFL_INTERNAL_DEPEND_PKG([EFREET], [ecore-ipc])
### Checks for header files
@ -4755,9 +4755,7 @@ pc/ethumb.pc
pc/ethumb_client.pc
pc/elocation.pc
pc/elua.pc
dbus-services/org.enlightenment.Efreet.service
dbus-services/org.enlightenment.Ethumb.service
systemd-services/efreet.service
systemd-services/ethumb.service
$po_makefile_in
cmakeconfig/EflConfig.cmake
@ -5261,25 +5259,21 @@ if test "x$prefix" != "x/usr"; then
echo ""
echo "System-wide installation:"
echo " ln -s ${resolved_dbusservicedir}/org.enlightenment.Ethumb.service /usr/share/dbus-1/services/org.enlightenment.Ethumb.service"
echo " ln -s ${resolved_dbusservicedir}/org.enlightenment.Efreet.service /usr/share/dbus-1/services/org.enlightenment.Efreet.service"
echo ""
echo " or add \"${resolved_datadir}\" to \$XDG_DATA_DIRS"
echo ""
echo "User installation:"
echo " ln -s ${resolved_dbusservicedir}/org.enlightenment.Ethumb.service ~/.local/share/dbus-1/services/org.enlightenment.Ethumb.service"
echo " ln -s ${resolved_dbusservicedir}/org.enlightenment.Efreet.service ~/.local/share/dbus-1/services/org.enlightenment.Efreet.service"
fi
if test $needs_alert_systemd -eq 1; then
echo ""
echo "System-wide installation:"
echo " ln -s ${resolved_USER_SESSION_DIR}/ethumb.service /usr/lib/systemd/user/ethumb.service"
echo " ln -s ${resolved_USER_SESSION_DIR}/efreet.service /usr/lib/systemd/user/efreet.service"
echo ""
echo " or add \"${base_USER_SESSION_DIR}\" to \$XDG_DATA_DIRS or \$XDG_CONFIG_DIRS"
echo ""
echo "User installation:"
echo " ln -s ${resolved_USER_SESSION_DIR}/ethumb.service ~/.config/systemd/user/ethumb.service"
echo " ln -s ${resolved_USER_SESSION_DIR}/efreet.service ~/.config/systemd/user/efreet.service"
fi
echo ""
echo "#-------------------------------------------------------------------#"

View File

@ -1,4 +0,0 @@
[D-BUS Service]
Name=org.enlightenment.Efreet
Exec=@prefix@/bin/efreetd
@systemd_dbus_prefix@SystemdService=efreet.service

View File

@ -78,8 +78,8 @@ bin_PROGRAMS += bin/efreet/efreetd
bin_efreet_efreetd_SOURCES = \
bin/efreet/efreetd.c \
bin/efreet/efreetd.h \
bin/efreet/efreetd_dbus.h \
bin/efreet/efreetd_dbus.c \
bin/efreet/efreetd_ipc.h \
bin/efreet/efreetd_ipc.c \
bin/efreet/efreetd_cache.h \
bin/efreet/efreetd_cache.c
@ -206,8 +206,7 @@ efreettestsub_DATA = \
tests/efreet/data/sub/test.desktop
check_PROGRAMS += tests/efreet/efreet_suite
# Need to run with dbus-launch - disable for now
#TESTS += tests/efreet/efreet_suite
TESTS += tests/efreet/efreet_suite
tests_efreet_efreet_suite_SOURCES = \
tests/efreet/efreet_suite.c \

View File

@ -12,8 +12,8 @@
#include <Ecore_File.h>
#include "efreetd.h"
#include "efreetd_dbus.h"
#include "efreetd_cache.h"
#include "efreetd_ipc.h"
int efreetd_log_dom = -1;
@ -61,13 +61,13 @@ main(int argc, char *argv[])
if (!ecore_init()) goto ecore_error;
ecore_app_args_set(argc, (const char **)argv);
if (!ecore_file_init()) goto ecore_file_error;
if (!dbus_init()) goto dbus_error;
if (!ipc_init()) goto ipc_error;
if (!cache_init()) goto cache_error;
ecore_main_loop_begin();
cache_shutdown();
dbus_shutdown();
ipc_shutdown();
ecore_file_shutdown();
ecore_shutdown();
eina_log_domain_unregister(efreetd_log_dom);
@ -76,8 +76,8 @@ main(int argc, char *argv[])
return 0;
cache_error:
dbus_shutdown();
dbus_error:
ipc_shutdown();
ipc_error:
ecore_file_shutdown();
ecore_file_error:
ecore_shutdown();

View File

@ -7,7 +7,7 @@
#include <Ecore_File.h>
#include <Eet.h>
#include "efreetd.h"
#include "efreetd_dbus.h"
#include "efreetd_ipc.h"
#include "Efreet.h"
#define EFREET_MODULE_LOG_DOM efreetd_log_dom

View File

@ -1,262 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Ecore.h>
#include <Eldbus.h>
#include "efreetd.h"
#include "efreetd_cache.h"
#define BUS "org.enlightenment.Efreet"
#define PATH "/org/enlightenment/Efreet"
#define INTERFACE "org.enlightenment.Efreet"
/* internal */
enum
{
EFREET_SIGNAL_ICON_CACHE_UPDATE = 0,
EFREET_SIGNAL_DESKTOP_CACHE_UPDATE
};
static Eldbus_Connection *conn;
static Eldbus_Service_Interface *iface;
static Ecore_Timer *_shutdown = NULL;
static int clients = 0;
static Eina_Bool
do_shutdown(void *data EINA_UNUSED)
{
quit();
return ECORE_CALLBACK_CANCEL;
}
static void
disconnected(void *context EINA_UNUSED, Eldbus_Connection *connection EINA_UNUSED, void *event_info EINA_UNUSED)
{
INF("disconnected");
quit();
}
static void
client_name_owner_changed_cb(void *data EINA_UNUSED, const char *bus, const char *old_id EINA_UNUSED, const char *new_id)
{
if (new_id[0])
return;
eldbus_name_owner_changed_callback_del(conn, bus,
client_name_owner_changed_cb, NULL);
clients--;
if (clients <= 0)
{
clients = 0;
if (_shutdown) ecore_timer_del(_shutdown);
_shutdown = ecore_timer_add(10.0, do_shutdown, NULL);
}
}
static Eldbus_Message *
do_register(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
{
Eldbus_Message *reply;
const char *lang;
if (!eldbus_message_arguments_get(message, "s", &lang))
{
ERR("Error getting arguments.");
return NULL;
}
setenv("LANG", lang, 1);
clients++;
if (_shutdown) ecore_timer_del(_shutdown);
_shutdown = NULL;
eldbus_name_owner_changed_callback_add(conn,
eldbus_message_sender_get(message),
client_name_owner_changed_cb, NULL,
EINA_FALSE);
reply = eldbus_message_method_return_new(message);
eldbus_message_arguments_append(reply, "b", cache_desktop_exists());
return reply;
}
static Eldbus_Message *
add_desktop_dirs(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
{
Eldbus_Message_Iter *array = NULL;
const char *dir;
if (!eldbus_message_arguments_get(message, "as", &array))
{
ERR("Error getting arguments.");
return NULL;
}
while (eldbus_message_iter_get_and_next(array, 's', &dir))
{
cache_desktop_dir_add(dir);
}
return NULL;
}
static Eldbus_Message *
add_icon_dirs(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
{
Eldbus_Message_Iter *array = NULL;
const char *dir;
if (!eldbus_message_arguments_get(message, "as", &array))
{
ERR("Error getting arguments.");
return NULL;
}
while (eldbus_message_iter_get_and_next(array, 's', &dir))
{
cache_icon_dir_add(dir);
}
return NULL;
}
static Eldbus_Message *
build_desktop_cache(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message EINA_UNUSED)
{
const char *lang;
if (!eldbus_message_arguments_get(message, "s", &lang))
{
ERR("Error getting arguments.");
return NULL;
}
setenv("LANG", lang, 1);
cache_desktop_update();
return NULL;
}
static Eldbus_Message *
add_icon_exts(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
{
Eldbus_Message_Iter *array = NULL;
const char *ext;
if (!eldbus_message_arguments_get(message, "as", &array))
{
ERR("Error getting arguments.");
return NULL;
}
while (eldbus_message_iter_get_and_next(array, 's', &ext))
{
cache_icon_ext_add(ext);
}
return NULL;
}
static const Eldbus_Signal signals[] = {
[EFREET_SIGNAL_ICON_CACHE_UPDATE] = {"IconCacheUpdate", ELDBUS_ARGS({ "b", "update" }), 0},
[EFREET_SIGNAL_DESKTOP_CACHE_UPDATE] = {"DesktopCacheUpdate", ELDBUS_ARGS({ "b", "update" }), 0},
{ NULL, NULL, 0 }
};
static const Eldbus_Method methods[] = {
{
"Register", ELDBUS_ARGS({"s", "lang info"}), ELDBUS_ARGS({"b", "cache exists"}),
do_register, 0
},
{
"AddDesktopDirs", ELDBUS_ARGS({"as", "dirs"}), NULL,
add_desktop_dirs, ELDBUS_METHOD_FLAG_NOREPLY
},
{
"BuildDesktopCache", ELDBUS_ARGS({"s", "lang info"}), NULL,
build_desktop_cache, ELDBUS_METHOD_FLAG_NOREPLY
},
{
"AddIconDirs", ELDBUS_ARGS({"as", "dirs"}), NULL,
add_icon_dirs, ELDBUS_METHOD_FLAG_NOREPLY
},
{
"AddIconExts", ELDBUS_ARGS({"as", "exts"}), NULL,
add_icon_exts, ELDBUS_METHOD_FLAG_NOREPLY
},
{ NULL, NULL, NULL, NULL, 0 }
};
static const Eldbus_Service_Interface_Desc desc = {
INTERFACE, methods, signals, NULL, NULL, NULL
};
static void
on_name_request(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
unsigned int reply;
if (eldbus_message_error_get(msg, NULL, NULL))
{
ERR("error on on_name_request");
quit();
return;
}
if (!eldbus_message_arguments_get(msg, "u", &reply))
{
ERR("error getting arguments on on_name_request");
quit();
return;
}
if (reply != ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)
{
ERR("error name already in use");
quit();
return;
}
INF("name requested");
}
/* external */
void
send_signal_icon_cache_update(Eina_Bool update)
{
eldbus_service_signal_emit(iface, EFREET_SIGNAL_ICON_CACHE_UPDATE, update);
}
void
send_signal_desktop_cache_update(Eina_Bool update)
{
eldbus_service_signal_emit(iface, EFREET_SIGNAL_DESKTOP_CACHE_UPDATE, update);
}
Eina_Bool
dbus_init(void)
{
if (!eldbus_init()) return EINA_FALSE;
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
if (!conn) goto conn_error;
eldbus_connection_event_callback_add(conn,
ELDBUS_CONNECTION_EVENT_DISCONNECTED, disconnected, NULL);
iface = eldbus_service_interface_register(conn, PATH, &desc);
eldbus_name_request(conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
on_name_request, NULL);
return EINA_TRUE;
conn_error:
eldbus_shutdown();
return EINA_FALSE;
}
Eina_Bool
dbus_shutdown(void)
{
eldbus_connection_unref(conn);
eldbus_shutdown();
return EINA_TRUE;
}

View File

@ -0,0 +1,226 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Ecore.h>
#include <Ecore_Ipc.h>
#include "efreetd.h"
#include "efreetd_cache.h"
static int init = 0;
static Ecore_Ipc_Server *ipc = NULL;
static Ecore_Event_Handler *hnd_add = NULL;
static Ecore_Event_Handler *hnd_del = NULL;
static Ecore_Event_Handler *hnd_data = NULL;
static int clients = 0;
static Ecore_Timer *quit_timer = NULL;
static Eina_Bool
_cb_quit_timer(void *data EINA_UNUSED)
{
quit_timer = NULL;
quit();
return EINA_FALSE;
}
static void
_broadcast(Ecore_Ipc_Server *svr, int major, int minor, void *data, int size)
{
Eina_List *clients = ecore_ipc_server_clients_get(svr);
Eina_List *l;
Ecore_Ipc_Client *cl;
EINA_LIST_FOREACH(clients, l, cl)
{
ecore_ipc_client_send(cl, major, minor, 0, 0, 0, data, size);
}
}
static char *
_parse_str(void *data, int size)
{
char *str = malloc(size + 1);
if (!str) return NULL;
memcpy(str, data, size);
str[size] = 0;
return str;
}
static Eina_List *
_parse_strs(void *data, int size)
{
Eina_List *list = NULL;
char *p, *p0 = NULL, *p1 = NULL, *e = (char *)data + size;
for (p = data; p < e; p++)
{
if (!p0)
{
if (*p)
{
p0 = p;
p1 = e;
}
}
if (!*p)
{
p1 = strdup(p0);
if (p1) list = eina_list_append(list, p1);
p0 = NULL;
}
}
if (p0)
{
p = malloc(p1 - p0 + 1);
if (p)
{
memcpy(p, p0, p1 - p0);
p[p1 - p0] = 0;
list = eina_list_append(list, p);
}
}
return list;
}
#define IPC_HEAD(_type) \
Ecore_Ipc_Event_Client_##_type *e = event; \
if (ecore_ipc_client_server_get(e->client) != ipc) \
return ECORE_CALLBACK_PASS_ON
static Eina_Bool
_cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
IPC_HEAD(Add);
if (quit_timer)
{
ecore_timer_del(quit_timer);
quit_timer = NULL;
}
clients++;
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
IPC_HEAD(Del);
clients--;
if (clients == 0)
{
if (quit_timer) ecore_timer_del(quit_timer);
quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL);
}
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Eina_List *strs;
char *s;
IPC_HEAD(Data);
if (e->major == 1) // register lang
{ // input: str -> lang
if ((s = _parse_str(e->data, e->size)))
{
setenv("LANG", s, 1);
free(s);
}
// return if desktop cache exists (bool as minor)
ecore_ipc_client_send(e->client, 1 /* register reply */,
cache_desktop_exists(), 0, 0, 0, NULL, 0);
}
else if (e->major == 2) // add desktop dirs
{ // input: array of str -> dirs
strs = _parse_strs(e->data, e->size);
EINA_LIST_FREE(strs, s)
{
cache_desktop_dir_add(s);
free(s);
}
}
else if (e->major == 3) // build desktop cache
{ // input: str -> lang
if ((s = _parse_str(e->data, e->size)))
{
setenv("LANG", s, 1);
free(s);
}
cache_desktop_update();
}
else if (e->major == 4) // add icon dirs
{ // input: array of str -> dirs
strs = _parse_strs(e->data, e->size);
EINA_LIST_FREE(strs, s)
{
cache_icon_dir_add(s);
free(s);
}
}
else if (e->major == 5) // add icon exts
{ // input: array of str -> exts
strs = _parse_strs(e->data, e->size);
EINA_LIST_FREE(strs, s)
{
cache_icon_ext_add(s);
free(s);
}
}
return ECORE_CALLBACK_DONE;
}
///////////////////////////////////////////////////////////////////////////
void
send_signal_icon_cache_update(Eina_Bool update)
{
_broadcast(ipc, 2 /* icon cache update */, update, NULL, 0);
}
void
send_signal_desktop_cache_update(Eina_Bool update)
{
_broadcast(ipc, 3 /* desktop cache update */, update, NULL, 0);
}
Eina_Bool
ipc_init(void)
{
if (init > 0) return EINA_TRUE;
if (!ecore_ipc_init()) return EINA_FALSE;
ipc = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
if (!ipc)
{
ecore_ipc_shutdown();
return EINA_FALSE;
}
quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL);
hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
_cb_client_add, NULL);
hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
_cb_client_del, NULL);
hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
_cb_client_data, NULL);
init++;
return EINA_TRUE;
}
Eina_Bool
ipc_shutdown(void)
{
if (init <= 0) return EINA_TRUE;
init--;
if (init > 0) return EINA_TRUE;
ecore_ipc_server_del(ipc);
ecore_event_handler_del(hnd_add);
ecore_event_handler_del(hnd_del);
ecore_event_handler_del(hnd_data);
ipc = NULL;
hnd_add = NULL;
hnd_del = NULL;
hnd_data = NULL;
ecore_ipc_shutdown();
return EINA_TRUE;
}

View File

@ -1,10 +1,10 @@
#ifndef __EFREETD_DBUS_H
#define __EFREETD_DBUS_H
#ifndef __EFREETD_IPC_H
#define __EFREETD_IPC_H
void send_signal_icon_cache_update(Eina_Bool update);
void send_signal_desktop_cache_update(Eina_Bool update);
Eina_Bool dbus_init(void);
Eina_Bool dbus_shutdown(void);
Eina_Bool ipc_init(void);
Eina_Bool ipc_shutdown(void);
#endif

View File

@ -15,7 +15,7 @@
#include <Eet.h>
#include <Ecore.h>
#include <Ecore_File.h>
#include <Eldbus.h>
#include <Ecore_Ipc.h>
/* define macros and variable for using the eina logging system */
#define EFREET_MODULE_LOG_DOM _efreet_cache_log_dom
@ -35,13 +35,11 @@ struct _Efreet_Old_Cache
Eet_File *ef;
};
/* TODO: Common define location with daemon */
#define BUS "org.enlightenment.Efreet"
#define PATH "/org/enlightenment/Efreet"
#define INTERFACE "org.enlightenment.Efreet"
static Eldbus_Connection *conn = NULL;
static Eldbus_Proxy *proxy = NULL;
static Ecore_Ipc_Server *ipc = NULL;
static Eina_Prefix *pfx = NULL;
static Ecore_Event_Handler *hnd_add = NULL;
static Ecore_Event_Handler *hnd_del = NULL;
static Ecore_Event_Handler *hnd_data = NULL;
static Eina_Lock _lock;
@ -97,10 +95,6 @@ static void efreet_cache_icon_theme_free(Efreet_Icon_Theme *theme);
static Eina_Bool efreet_cache_check(Eet_File **ef, const char *path, int major);
static void *efreet_cache_close(Eet_File *ef);
static void on_send_register(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending);
static void desktop_cache_update(void *context, const Eldbus_Message *msg);
static void icon_cache_update(void *context, const Eldbus_Message *msg);
static void icon_cache_update_free(void *data, void *ev);
static void *hash_array_string_add(void *hash, const char *key, void *data);
@ -109,6 +103,122 @@ EAPI int EFREET_EVENT_ICON_CACHE_UPDATE = 0;
EAPI int EFREET_EVENT_DESKTOP_CACHE_UPDATE = 0;
EAPI int EFREET_EVENT_DESKTOP_CACHE_BUILD = 0;
#define IPC_HEAD(_type) \
Ecore_Ipc_Event_Server_##_type *e = event; \
if (e->server != ipc) \
return ECORE_CALLBACK_PASS_ON
static void
_ipc_launch(void)
{
char buf[PATH_MAX];
int num = 0;
if (!pfx) snprintf(buf, sizeof(buf), "efreetd");
else snprintf(buf, sizeof(buf), "%s/efreetd", eina_prefix_bin_get(pfx));
ecore_exe_run(buf, NULL);
while ((!ipc) && (num < 500))
{
num++;
usleep(1000);
ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
}
}
static Eina_Bool
_cb_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
IPC_HEAD(Add);
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_cb_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
IPC_HEAD(Del);
ipc = NULL;
_ipc_launch();
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
IPC_HEAD(Data);
if (e->major == 1) // registration
{
if (e->minor == 1)
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, NULL, NULL, NULL);
}
else if (e->major == 2) // icon cache update
{
if (e->minor == 1)
{
Efreet_Event_Cache_Update *ev;
efreet_cache_desktop_close();
ev = NEW(Efreet_Event_Cache_Update, 1);
if (ev)
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, NULL, NULL);
}
else
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, NULL, NULL, NULL);
}
else if (e->major == 3) // desktop cache update
{
Efreet_Event_Cache_Update *ev = NULL;
Efreet_Old_Cache *d = NULL;
Eina_List *l = NULL;
if (e->minor == 1)
{
ev = NEW(Efreet_Event_Cache_Update, 1);
if (!ev) goto error;
IF_RELEASE(theme_name);
// Save all old caches
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
d->hash = themes;
d->ef = icon_theme_cache;
l = eina_list_append(l, d);
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
d->hash = icons;
d->ef = icon_cache;
l = eina_list_append(l, d);
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
d->hash = fallbacks;
d->ef = fallback_cache;
l = eina_list_append(l, d);
// Create new empty caches
themes = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_theme_free));
icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
icon_theme_cache = NULL;
icon_cache = NULL;
fallback_cache = NULL;
// Send event
ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, icon_cache_update_free, l);
goto done;
}
error:
IF_FREE(ev);
EINA_LIST_FREE(l, d)
free(d);
}
done:
return ECORE_CALLBACK_DONE;
}
int
efreet_cache_init(void)
{
@ -139,31 +249,43 @@ efreet_cache_init(void)
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
desktops = eina_hash_string_superfast_new(NULL);
eldbus_init();
ecore_ipc_init();
// XXX: connect to efreetd
if (efreet_cache_update)
{
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
if (conn)
{
Eldbus_Object *obj;
pfx = eina_prefix_new
(NULL, efreet_icon_cache_file, "EFREET", "efreet", "checkme",
PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
if (!ipc) _ipc_launch();
if (ipc)
{
const char *s;
int len = 0;
obj = eldbus_object_get(conn, BUS, PATH);
proxy = eldbus_proxy_get(obj, INTERFACE);
eldbus_proxy_signal_handler_add(proxy, "IconCacheUpdate", icon_cache_update, NULL);
eldbus_proxy_signal_handler_add(proxy, "DesktopCacheUpdate", desktop_cache_update, NULL);
hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
_cb_server_add, NULL);
hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
_cb_server_del, NULL);
hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
_cb_server_data, NULL);
s = efreet_language_get();
if (s) len = strlen(s);
ecore_ipc_server_send(ipc, 1, 0, 0, 0, 0, s, len);
}
else
{
Efreet_Event_Cache_Update *ev;
eldbus_proxy_call(proxy, "Register", on_send_register, NULL, -1, "s", efreet_language_get());
/*
* TODO: Needed?
eldbus_name_owner_changed_callback_add(conn, BUS, on_name_owner_changed,
conn, EINA_TRUE);
*/
}
else
{
/* TODO: Run cache process directly */
}
WRN("Can't contact efreetd daemon for desktop/icon etc. changes");
ev = NEW(Efreet_Event_Cache_Update, 1);
if (ev)
{
ev->error = 1;
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, ev, NULL, NULL);
}
}
}
return 1;
@ -226,19 +348,16 @@ efreet_cache_shutdown(void)
util_cache = efreet_cache_close(util_cache);
IF_RELEASE(util_cache_file);
/*
* TODO: Needed??
eldbus_name_owner_changed_callback_del(conn, BUS, on_name_owner_changed, conn);
*/
if (conn)
{
Eldbus_Object *obj = eldbus_proxy_object_get(proxy);
eldbus_proxy_unref(proxy);
eldbus_object_unref(obj);
eldbus_connection_unref(conn);
}
eldbus_shutdown();
if (ipc) ecore_ipc_server_del(ipc);
if (pfx) eina_prefix_free(pfx);
if (hnd_add) ecore_event_handler_del(hnd_add);
if (hnd_del) ecore_event_handler_del(hnd_del);
if (hnd_data) ecore_event_handler_del(hnd_data);
ipc = NULL;
pfx = NULL;
hnd_add = NULL;
hnd_del = NULL;
hnd_data = NULL;
eina_lock_free(&_lock);
@ -924,65 +1043,67 @@ efreet_cache_desktop_free(Efreet_Desktop *desktop)
void
efreet_cache_desktop_add(Efreet_Desktop *desktop)
{
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *array_of_string;
char *path;
char *path;
if ((!efreet_cache_update) || (!proxy))
return;
/* TODO: Chunk updates */
if (!eina_main_loop_is()) return;
if ((!efreet_cache_update) || (!ipc)) return;
if (!eina_main_loop_is()) return;
/*
* TODO: Call in thread with:
ecore_thread_main_loop_begin();
ecore_thread_main_loop_end();
* ecore_thread_main_loop_begin();
* ecore_thread_main_loop_end();
*/
path = ecore_file_dir_get(desktop->orig_path);
msg = eldbus_proxy_method_call_new(proxy, "AddDesktopDirs");
iter = eldbus_message_iter_get(msg);
array_of_string = eldbus_message_iter_container_new(iter, 'a',"s");
eldbus_message_iter_basic_append(array_of_string, 's', path);
eldbus_message_iter_container_close(iter, array_of_string);
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
free(path);
path = ecore_file_dir_get(desktop->orig_path);
if (!path) return;
ecore_ipc_server_send(ipc, 2, 0, 0, 0, 0, path, strlen(path));
free(path);
}
void
efreet_cache_icon_exts_add(Eina_List *exts)
{
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *array_of_string;
Eina_List *l;
const char *ext;
Eina_List *l;
const char *s;
Eina_Binbuf *buf;
int num = 0;
unsigned char nil[1] = { 0 };
if ((!efreet_cache_update) || (!proxy))
return;
msg = eldbus_proxy_method_call_new(proxy, "AddIconExts");
iter = eldbus_message_iter_get(msg);
array_of_string = eldbus_message_iter_container_new(iter, 'a',"s");
EINA_LIST_FOREACH(exts, l, ext)
eldbus_message_iter_basic_append(array_of_string, 's', ext);
eldbus_message_iter_container_close(iter, array_of_string);
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
if ((!efreet_cache_update) || (!ipc)) return;
buf = eina_binbuf_new();
if (!buf) return;
EINA_LIST_FOREACH(exts, l, s)
{
if (num > 0) eina_binbuf_append_length(buf, nil, 1);
eina_binbuf_append_length(buf, (unsigned char *)s, strlen(s));
num++;
}
ecore_ipc_server_send(ipc, 5 /* add icon exts */, 0, 0, 0, 0,
eina_binbuf_string_get(buf),
eina_binbuf_length_get(buf));
eina_binbuf_free(buf);
}
void
efreet_cache_icon_dirs_add(Eina_List *dirs)
{
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *array_of_string;
Eina_List *l;
const char *dir;
Eina_List *l;
const char *s;
Eina_Binbuf *buf;
int num = 0;
unsigned char nil[1] = { 0 };
if ((!efreet_cache_update) || (!proxy))
return;
msg = eldbus_proxy_method_call_new(proxy, "AddIconDirs");
iter = eldbus_message_iter_get(msg);
array_of_string = eldbus_message_iter_container_new(iter, 'a',"s");
EINA_LIST_FOREACH(dirs, l, dir)
eldbus_message_iter_basic_append(array_of_string, 's', dir);
eldbus_message_iter_container_close(iter, array_of_string);
eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
if ((!efreet_cache_update) || (!ipc)) return;
buf = eina_binbuf_new();
if (!buf) return;
EINA_LIST_FOREACH(dirs, l, s)
{
if (num > 0) eina_binbuf_append_length(buf, nil, 1);
eina_binbuf_append_length(buf, (unsigned char *)s, strlen(s));
num++;
}
ecore_ipc_server_send(ipc, 4 /* add icon dirs */, 0, 0, 0, 0,
eina_binbuf_string_get(buf),
eina_binbuf_length_get(buf));
eina_binbuf_free(buf);
}
void
@ -1025,9 +1146,12 @@ efreet_cache_desktop_close(void)
void
efreet_cache_desktop_build(void)
{
if ((!efreet_cache_update) || (!proxy))
return;
eldbus_proxy_call(proxy, "BuildDesktopCache", NULL, NULL, -1, "s", efreet_language_get());
const char *s;
int len = 0;
if ((!efreet_cache_update) || (!ipc)) return;
s = efreet_language_get();
if (s) len = strlen(s);
ecore_ipc_server_send(ipc, 3 /* build desktop cache */, 0, 0, 0, 0, s, len);
}
static Eina_Bool
@ -1121,103 +1245,6 @@ efreet_cache_util_names(const char *key)
return util_cache_names;
}
static void
on_send_register(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
const char *errname, *errmsg;
Eina_Bool exists;
if (eldbus_message_error_get(msg, &errname, &errmsg))
{
Efreet_Event_Cache_Update *ev = NULL;
WRN("%s %s", errname, errmsg);
ev = NEW(Efreet_Event_Cache_Update, 1);
if (ev)
{
ev->error = 1;
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, ev, NULL, NULL);
}
}
else if (eldbus_message_arguments_get(msg, "b", &exists) && exists)
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, NULL, NULL, NULL);
}
static void
desktop_cache_update(void *context EINA_UNUSED, const Eldbus_Message *msg)
{
Eina_Bool update;
if (eldbus_message_arguments_get(msg, "b", &update))
{
if (update)
{
Efreet_Event_Cache_Update *ev = NULL;
efreet_cache_desktop_close();
ev = NEW(Efreet_Event_Cache_Update, 1);
if (ev)
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, NULL, NULL);
}
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, NULL, NULL, NULL);
}
}
static void
icon_cache_update(void *context EINA_UNUSED, const Eldbus_Message *msg)
{
Efreet_Event_Cache_Update *ev = NULL;
Efreet_Old_Cache *d = NULL;
Eina_List *l = NULL;
Eina_Bool update;
if (eldbus_message_arguments_get(msg, "b", &update) && update)
{
ev = NEW(Efreet_Event_Cache_Update, 1);
if (!ev) goto error;
IF_RELEASE(theme_name);
/* Save all old caches */
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
d->hash = themes;
d->ef = icon_theme_cache;
l = eina_list_append(l, d);
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
d->hash = icons;
d->ef = icon_cache;
l = eina_list_append(l, d);
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
d->hash = fallbacks;
d->ef = fallback_cache;
l = eina_list_append(l, d);
/* Create new empty caches */
themes = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_theme_free));
icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
icon_theme_cache = NULL;
icon_cache = NULL;
fallback_cache = NULL;
/* Send event */
ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, icon_cache_update_free, l);
}
return;
error:
IF_FREE(ev);
EINA_LIST_FREE(l, d)
free(d);
}
static void
icon_cache_update_free(void *data, void *ev)
{

View File

@ -1,7 +0,0 @@
[Unit]
Description=Efreet Enlightenment FreeDesktop.Org Daemon
[Service]
Type=dbus
BusName=org.enlightenment.Efreet
ExecStart=@prefix@/bin/efreetd