Hi,

   This patch doesn't break anything at this time :-) It's a
standalone feature that just add the possibility to evas to receive
events from another thread. It introduce 3 new API.

* Retrieve the fd that need to be monitored by ecore :
EAPI int evas_async_events_fd_get();

* Process all pending event in the pipe (This function could be called
without any event in the pipe) :
EAPI int evas_async_events_process();

* Push an event inside the pipe from another thread :
EAPI Evas_Bool evas_async_events_put(Evas_Object *obj,
Evas_Callback_Type type, void *event_info);

I currently don't have any code using it, but I plan to use this for
the coming background loading of image. So please review it.

-- 
Cedric BAIL
diff --git a/src/lib/Evas.h b/src/lib/Evas.h
index e78e9a9..06f8a83 100644
--- a/src/lib/Evas.h
+++ b/src/lib/Evas.h
@@ -815,6 +815,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          ();
+   EAPI int		  evas_async_events_process	    ();
+   EAPI Evas_Bool	  evas_async_events_put             (Evas_Object *obj, 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/src/lib/canvas/Makefile.am b/src/lib/canvas/Makefile.am
index 9dda0e1..db66ba6 100644
--- a/src/lib/canvas/Makefile.am
+++ b/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/src/lib/canvas/evas_async_events.c b/src/lib/canvas/evas_async_events.c
new file mode 100644
index 0000000..fb21c02
--- /dev/null
+++ b/src/lib/canvas/evas_async_events.c
@@ -0,0 +1,121 @@
+#include "evas_common.h"
+#include "evas_private.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <errno.h>
+
+static int		_fd_write = -1;
+static int		_fd_read = -1;
+
+static int		_init_evas_event = 0;
+static pthread_mutex_t	_mutex;
+
+typedef struct _Evas_Event_Async	Evas_Event_Async;
+struct _Evas_Event_Async
+{
+   Evas_Object		*obj;
+   Evas_Callback_Type	 type;
+   void			*event_info;
+};
+
+int
+evas_async_events_init()
+{
+   if (_init_evas_event++ == 0)
+     {
+	int	filedes[2];
+
+	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);
+
+	pthread_mutex_init(&_mutex, NULL);
+     }
+
+   return _init_evas_event;
+}
+
+int
+evas_async_events_shutdown()
+{
+   if (--_init_evas_event == 0)
+     {
+	close(_fd_read);
+	close(_fd_write);
+	_fd_read = -1;
+	_fd_write = -1;
+
+	pthread_mutex_destroy(&_mutex);
+     }
+
+   return _init_evas_event;
+}
+
+EAPI int
+evas_async_events_fd_get()
+{
+   return _fd_read;
+}
+
+EAPI int
+evas_async_events_process()
+{
+   Evas_Event_Async	current;
+   int			check;
+   int			count = 0;
+
+   do
+     {
+	check = read(_fd_read, &current, sizeof(current));
+
+	if (check == sizeof(current))
+	  {
+	     evas_object_event_callback_call(current.obj, current.type, current.event_info);
+	     ++count;
+	  }
+     }
+   while (check == sizeof(current));
+
+   return count;
+}
+
+EAPI Evas_Bool
+evas_async_events_put(Evas_Object *obj, Evas_Callback_Type type, void *event_info)
+{
+   Evas_Event_Async	new;
+   Evas_Bool		result;
+
+   result = 0;
+
+   new.obj = obj;
+   new.type = type;
+   new.event_info = event_info;
+
+   pthread_mutex_lock(&_mutex);
+   if (_fd_write != -1)
+     {
+	ssize_t	check;
+	int	offset = 0;
+
+	do {
+	   check = write(_fd_write, &new + offset, sizeof(new) - offset);
+	   offset += check;
+	} while (offset != sizeof(new) && (errno == EINTR || errno == EAGAIN));
+
+	if (offset == sizeof(new))
+	  result = 1;
+     }
+   pthread_mutex_unlock(&_mutex);
+
+   return result;
+}
+
diff --git a/src/lib/canvas/evas_main.c b/src/lib/canvas/evas_main.c
index 7313a33..ca1b8dc 100644
--- a/src/lib/canvas/evas_main.c
+++ b/src/lib/canvas/evas_main.c
@@ -7,8 +7,12 @@ static int initcount = 0;
 EAPI int
 evas_init(void)
 {
+   if (evas_async_events_init() == 0)
+     return 0;
+
    if (initcount == 0)
      evas_module_init();
+
    return ++initcount;
 }
 
@@ -22,6 +26,7 @@ evas_shutdown(void)
 	evas_common_shutdown();
 	evas_module_shutdown();
      }
+   evas_async_events_shutdown();
    return initcount;
 }
 
diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h
index 5927d25..f8fcc2b 100644
--- a/src/lib/include/evas_private.h
+++ b/src/lib/include/evas_private.h
@@ -795,6 +795,9 @@ void evas_module_use(Evas_Module *em);
 void evas_module_clean(void);
 void evas_module_shutdown(void);
 
+int evas_async_events_init();
+int evas_async_events_shutdown();
+
 void _evas_walk(Evas *e);
 void _evas_unwalk(Evas *e);
        
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Register now and save $200. Hurry, offer ends at 11:59 p.m., 
Monday, April 7! Use priority code J8TLD2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to