From 2a123c0d6a69831ff921ad9cedd40dc8bfacf25c Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 30 Apr 2008 12:21:31 +0000 Subject: [PATCH] Add support for evas asynchronous events. SVN revision: 34410 --- legacy/evas/configure.in | 28 ++- legacy/evas/src/lib/Evas.h | 4 + legacy/evas/src/lib/canvas/Makefile.am | 3 +- .../evas/src/lib/canvas/evas_async_events.c | 170 ++++++++++++++++++ legacy/evas/src/lib/include/evas_private.h | 3 + 5 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 legacy/evas/src/lib/canvas/evas_async_events.c diff --git a/legacy/evas/configure.in b/legacy/evas/configure.in index 2ac288a337..b1ff11ee67 100644 --- a/legacy/evas/configure.in +++ b/legacy/evas/configure.in @@ -1130,13 +1130,17 @@ AM_CONDITIONAL(BUILD_LOADER_PMAPS, test x$have_pmaps = xyes) pthread_cflags="" pthread_libs="" build_pthreads="no" +has_pthreads="no" # sched_getaffinity pthread_attr_setaffinity_np AC_CHECK_HEADERS(pthread.h sched.h, [ AC_CHECK_LIB(pthread, pthread_attr_setaffinity_np, [ AC_CHECK_LIB(pthread, pthread_barrier_wait, - [ build_pthreads="yes" ], + [ + build_pthreads="yes" + has_pthreads="yes" + ], [ build_pthreads="no" ] ) ], @@ -1173,6 +1177,26 @@ AC_ARG_ENABLE(pthreads, ] ) +####################################### +## Async events +build_async_events="auto" +AC_MSG_CHECKING(whether to build Async Events support) +AC_ARG_ENABLE(async-events, + AC_HELP_STRING([--enable-async-events], [enable async events support]), + [ build_async_events=$enableval ] +) +AC_MSG_RESULT($build_async_events) + +AC_MSG_CHECKING(whether we can build Async Events support) +if test \( "x$build_async_events" = "xyes" -o "x$build_async_events" = "xauto" \) -a "x$has_pthreads" = "xyes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(BUILD_ASYNC_EVENTS, 1, [Build async events support]) + build_async_events="yes" +else + AC_MSG_RESULT(no) + build_async_events="no" +fi + ####################################### ## MMX build_cpu_mmx="no" @@ -1761,6 +1785,8 @@ echo " SSE.....................: $build_cpu_sse" echo " ALTIVEC.................: $build_cpu_altivec" echo " Thread Support..........: $build_pthreads" echo +echo "Async Events..............: $build_async_events" +echo echo "ARGB Software Engine Options:" echo " Sampling Scaler.........: $scaler_sample" echo " Smooth Scaler...........: $scaler_smooth" diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index 22fb29fd92..18ba377e55 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -823,6 +823,10 @@ extern "C" { EAPI void evas_object_event_callback_add (Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data); EAPI void *evas_object_event_callback_del (Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info)); + EAPI int evas_async_events_fd_get (void); + EAPI int evas_async_events_process (void); + EAPI Evas_Bool evas_async_events_put (void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info)); + EAPI void evas_object_intercept_show_callback_add (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), const void *data); EAPI void *evas_object_intercept_show_callback_del (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj)); EAPI void evas_object_intercept_hide_callback_add (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), const void *data); diff --git a/legacy/evas/src/lib/canvas/Makefile.am b/legacy/evas/src/lib/canvas/Makefile.am index 9dda0e17e3..db66ba6d17 100644 --- a/legacy/evas/src/lib/canvas/Makefile.am +++ b/legacy/evas/src/lib/canvas/Makefile.am @@ -37,6 +37,7 @@ evas_font_dir.c \ evas_rectangle.c \ evas_render.c \ evas_smart.c \ -evas_stack.c +evas_stack.c \ +evas_async_events.c libevas_canvas_la_DEPENDENCIES = $(top_builddir)/config.h diff --git a/legacy/evas/src/lib/canvas/evas_async_events.c b/legacy/evas/src/lib/canvas/evas_async_events.c new file mode 100644 index 0000000000..069a158a86 --- /dev/null +++ b/legacy/evas/src/lib/canvas/evas_async_events.c @@ -0,0 +1,170 @@ +#include "config.h" +#include "evas_common.h" +#include "evas_private.h" + +#ifdef BUILD_ASYNC_EVENTS + +#include +#include +#include +#include + +static int _fd_write = -1; +static int _fd_read = -1; + +static int _init_evas_event = 0; +static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; + +typedef struct _Evas_Event_Async Evas_Event_Async; +struct _Evas_Event_Async +{ + void (*func)(void *target, Evas_Callback_Type type, void *event_info); + void *target; + Evas_Callback_Type type; + void *event_info; +}; + +#endif + +int +evas_async_events_init(void) +{ +#ifdef BUILD_ASYNC_EVENTS + int filedes[2]; + + _init_evas_event++; + if (_init_evas_event > 1) return _init_evas_event; + + if (pipe(filedes) == -1) + { + _init_evas_event = 0; + return 0; + } + + _fd_read = filedes[0]; + _fd_write = filedes[1]; + + fcntl(_fd_read, F_SETFL, O_NONBLOCK); + + return _init_evas_event; +#else + return 0; +#endif +} + +int +evas_async_events_shutdown(void) +{ +#ifdef BUILD_ASYNC_EVENTS + _init_evas_event--; + if (_init_evas_event > 0) return _init_evas_event; + + close(_fd_read); + close(_fd_write); + _fd_read = -1; + _fd_write = -1; + + return _init_evas_event; +#else + return 0; +#endif +} + +EAPI int +evas_async_events_fd_get(void) +{ +#ifdef BUILD_ASYNC_EVENTS + return _fd_read; +#else + return -1; +#endif +} + +EAPI int +evas_async_events_process(void) +{ +#ifdef BUILD_ASYNC_EVENTS + static Evas_Event_Async current; + static int size = 0; + int check; + int count = 0; + + if (_fd_read == -1) return 0; + + do + { + check = read(_fd_read, ((char*) ¤t) + size, sizeof(current) - size); + + if (check > 0) + { + size += check; + if (size == sizeof(current)) + { + if (current.func) current.func(current.target, current.type, current.event_info); + size = 0; + count++; + } + } + } + while (check > 0); + + if (check < 0) + switch (errno) + { + case EBADF: + case EINVAL: + case EIO: + case EISDIR: + _fd_read = -1; + } + + return count; +#else + return 0; +#endif +} + +EAPI Evas_Bool +evas_async_events_put(void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info)) +{ +#ifdef BUILD_ASYNC_EVENTS + Evas_Event_Async new; + ssize_t check; + int offset = 0; + Evas_Bool result = 0; + + if (!func) return 0; + if (_fd_write == -1) return 0; + + new.func = func; + new.target = target; + new.type = type; + new.event_info = event_info; + + pthread_mutex_lock(&_mutex); + + do { + check = write(_fd_write, ((char*)&new) + offset, sizeof(new) - offset); + offset += check; + } while (offset != sizeof(new) && (errno == EINTR || errno == EAGAIN)); + + if (offset == sizeof(new)) + result = 1; + else + switch (errno) + { + case EBADF: + case EINVAL: + case EIO: + case EPIPE: + _fd_write = -1; + } + + pthread_mutex_unlock(&_mutex); + + return result; +#else + return 0; +#endif +} + diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 12a1d1601b..25f1daefef 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -824,6 +824,9 @@ void evas_module_use(Evas_Module *em); void evas_module_clean(void); void evas_module_shutdown(void); +int evas_async_events_init(void); +int evas_async_events_shutdown(void); + void _evas_walk(Evas *e); void _evas_unwalk(Evas *e);