summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/evas_async_events.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/lib/evas/canvas/evas_async_events.c
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/lib/evas/canvas/evas_async_events.c')
-rw-r--r--src/lib/evas/canvas/evas_async_events.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/lib/evas/canvas/evas_async_events.c b/src/lib/evas/canvas/evas_async_events.c
new file mode 100644
index 0000000..c8f114e
--- /dev/null
+++ b/src/lib/evas/canvas/evas_async_events.c
@@ -0,0 +1,170 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#ifndef _MSC_VER
6# include <unistd.h>
7#endif
8#include <fcntl.h>
9#include <errno.h>
10
11#include "evas_common.h"
12#include "evas_private.h"
13
14static int _fd_write = -1;
15static int _fd_read = -1;
16static pid_t _fd_pid = 0;
17
18static int _init_evas_event = 0;
19
20typedef struct _Evas_Event_Async Evas_Event_Async;
21
22struct _Evas_Event_Async
23{
24 const void *target;
25 void *event_info;
26 Evas_Async_Events_Put_Cb func;
27 Evas_Callback_Type type;
28};
29
30int
31evas_async_events_init(void)
32{
33 int filedes[2];
34
35 _init_evas_event++;
36 if (_init_evas_event > 1) return _init_evas_event;
37
38 _fd_pid = getpid();
39
40 if (pipe(filedes) == -1)
41 {
42 _init_evas_event = 0;
43 return 0;
44 }
45
46 _fd_read = filedes[0];
47 _fd_write = filedes[1];
48
49 fcntl(_fd_read, F_SETFL, O_NONBLOCK);
50
51 return _init_evas_event;
52}
53
54int
55evas_async_events_shutdown(void)
56{
57 _init_evas_event--;
58 if (_init_evas_event > 0) return _init_evas_event;
59
60 close(_fd_read);
61 close(_fd_write);
62 _fd_read = -1;
63 _fd_write = -1;
64
65 return _init_evas_event;
66}
67
68static void
69_evas_async_events_fork_handle(void)
70{
71 int i, count = _init_evas_event;
72
73 if (getpid() == _fd_pid) return;
74 for (i = 0; i < count; i++) evas_async_events_shutdown();
75 for (i = 0; i < count; i++) evas_async_events_init();
76}
77
78EAPI int
79evas_async_events_fd_get(void)
80{
81 _evas_async_events_fork_handle();
82 return _fd_read;
83}
84
85EAPI int
86evas_async_events_process(void)
87{
88 Evas_Event_Async *ev;
89 int check;
90 int count = 0;
91
92 if (_fd_read == -1) return 0;
93
94 _evas_async_events_fork_handle();
95
96 do
97 {
98 check = read(_fd_read, &ev, sizeof (Evas_Event_Async *));
99
100 if (check == sizeof (Evas_Event_Async *))
101 {
102 if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
103 free(ev);
104 count++;
105 }
106 }
107 while (check > 0);
108
109 evas_cache_image_wakeup();
110
111 if (check < 0)
112 {
113 switch (errno)
114 {
115 case EBADF:
116 case EINVAL:
117 case EIO:
118 case EISDIR:
119 _fd_read = -1;
120 }
121 }
122
123 return count;
124}
125
126EAPI Eina_Bool
127evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, Evas_Async_Events_Put_Cb func)
128{
129 Evas_Event_Async *ev;
130 ssize_t check;
131 Eina_Bool result = EINA_FALSE;
132
133 if (!func) return 0;
134 if (_fd_write == -1) return 0;
135
136 _evas_async_events_fork_handle();
137
138 ev = calloc(1, sizeof (Evas_Event_Async));
139 if (!ev) return 0;
140
141 ev->func = func;
142 ev->target = target;
143 ev->type = type;
144 ev->event_info = event_info;
145
146 do
147 {
148 check = write(_fd_write, &ev, sizeof (Evas_Event_Async*));
149 }
150 while ((check != sizeof (Evas_Event_Async*)) &&
151 ((errno == EINTR) || (errno == EAGAIN)));
152
153 evas_cache_image_wakeup();
154
155 if (check == sizeof (Evas_Event_Async*))
156 result = EINA_TRUE;
157 else
158 {
159 switch (errno)
160 {
161 case EBADF:
162 case EINVAL:
163 case EIO:
164 case EPIPE:
165 _fd_write = -1;
166 }
167 }
168
169 return result;
170}