forked from enlightenment/efl
90 lines
2.2 KiB
C
90 lines
2.2 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
#include <sys/types.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <sys/time.h>
|
|
|
|
#include "Ecore.h"
|
|
#include "ecore_private.h"
|
|
#include "ecore_main_common.h"
|
|
|
|
#ifdef HAVE_SYS_TIMERFD_H
|
|
|
|
static Eo *realtime_obj = NULL;
|
|
|
|
static void
|
|
_cb_read(void *data EINA_UNUSED, const Efl_Event *event)
|
|
{
|
|
Eo *loop = efl_provider_find(event->object, EFL_LOOP_CLASS);
|
|
int fd = efl_loop_handler_fd_get(event->object);
|
|
char buf[8];
|
|
|
|
if (read(fd, buf, sizeof(buf)) >= 0) return;
|
|
DBG("system clock changed");
|
|
// XXX: ecore event needs to be eo loop api's
|
|
ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL);
|
|
_ecore_main_timechanges_stop(loop);
|
|
_ecore_main_timechanges_start(loop);
|
|
}
|
|
|
|
static void
|
|
_cb_del(void *data EINA_UNUSED, const Efl_Event *event)
|
|
{
|
|
int fd = efl_loop_handler_fd_get(event->object);
|
|
if (event->object == realtime_obj) realtime_obj = NULL;
|
|
close(fd);
|
|
}
|
|
|
|
EFL_CALLBACKS_ARRAY_DEFINE(_event_watch,
|
|
{ EFL_LOOP_HANDLER_EVENT_READ, _cb_read },
|
|
{ EFL_EVENT_DEL, _cb_del });
|
|
#endif
|
|
|
|
void
|
|
_ecore_main_timechanges_start(Eo *obj)
|
|
{
|
|
#ifdef HAVE_SYS_TIMERFD_H
|
|
struct itimerspec its;
|
|
int fd;
|
|
|
|
if (realtime_obj) return;
|
|
|
|
fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
|
|
if (fd < 0) return;
|
|
|
|
memset(&its, 0, sizeof(its));
|
|
its.it_value.tv_sec = TIME_T_MAX; // end of time - 0xf
|
|
if (timerfd_settime(fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
|
|
&its, NULL) < 0)
|
|
{
|
|
WRN("Couldn't arm timerfd to detect clock changes: %s", strerror(errno));
|
|
close(fd);
|
|
return;
|
|
}
|
|
realtime_obj =
|
|
efl_add(EFL_LOOP_HANDLER_CLASS, obj,
|
|
efl_loop_handler_fd_set(efl_added, fd),
|
|
efl_loop_handler_active_set(efl_added, EFL_LOOP_HANDLER_FLAGS_READ),
|
|
efl_event_callback_array_add(efl_added, _event_watch(), NULL));
|
|
#endif
|
|
}
|
|
|
|
void
|
|
_ecore_main_timechanges_stop(Eo *obj EINA_UNUSED)
|
|
{
|
|
#ifdef HAVE_SYS_TIMERFD_H
|
|
Eo *o = realtime_obj;
|
|
if (!o) return;
|
|
realtime_obj = NULL;
|
|
efl_del(o);
|
|
#endif
|
|
}
|