Mercurial > MadButterfly
comparison nodejs/njs_mb_supp.c @ 1067:7b4e80ab671a openvg
merge from default branch
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 01 Dec 2010 12:25:56 +0800 |
parents | 88bd0eee2b00 |
children |
comparison
equal
deleted
inserted
replaced
630:bd18951b51d5 | 1067:7b4e80ab671a |
---|---|
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- | |
2 // vim: sw=4:ts=8:sts=4 | |
3 /*! \brief Implement X11 backend for nodejs plugin. | |
4 * | |
5 * Since nodejs use libev to handle event loops, part of X11 backend | |
6 * code can not be used directly. The part of code should be rewrote. | |
7 * The part is about | |
8 */ | |
9 #include <stdio.h> | |
10 #include <string.h> | |
11 #include <ev.h> | |
12 #include "mb_tools.h" | |
13 #include <mb_backend.h> | |
14 #include "njs_mb_supp.h" | |
15 | |
16 #ifndef ASSERT | |
17 #define ASSERT(x) | |
18 #endif | |
19 | |
20 #define OK 0 | |
21 #define ERR -1 | |
22 | |
23 | |
24 /*! \defgroup njs_timer_man Timer manager for nodejs. | |
25 * @{ | |
26 */ | |
27 struct _njs_timer_timeout { | |
28 ev_timer tmwatcher; | |
29 mb_timer_cb_t cb; | |
30 mb_timeval_t *timeout; | |
31 void *data; | |
32 }; | |
33 | |
34 static int njs_timer_man_timeout(mb_timer_man_t *tm_man, | |
35 mb_timeval_t *tm_out, | |
36 mb_timer_cb_t cb, void *data); | |
37 static void njs_timer_man_remove(mb_timer_man_t *tm_man, int tm_hdl); | |
38 static mb_timer_man_t *njs_timer_man_new(void); | |
39 static void njs_timer_man_free(mb_timer_man_t *timer_man); | |
40 | |
41 static mb_timer_man_t njs_timer_man = { | |
42 njs_timer_man_timeout, | |
43 njs_timer_man_remove | |
44 }; | |
45 | |
46 static mb_timer_factory_t njs_timer_factory = { | |
47 njs_timer_man_new, | |
48 njs_timer_man_free | |
49 }; | |
50 | |
51 static void | |
52 njs_timer_man_cb(EV_P_ ev_timer *tmwatcher, int revent) { | |
53 struct _njs_timer_timeout *timer_timeout = | |
54 MEM2OBJ(tmwatcher, struct _njs_timer_timeout, tmwatcher); | |
55 mb_timeval_t now; | |
56 | |
57 get_now(&now); | |
58 timer_timeout->cb((int)timer_timeout, timer_timeout->timeout, &now, | |
59 timer_timeout->data); | |
60 } | |
61 | |
62 static int | |
63 njs_timer_man_timeout(mb_timer_man_t *tm_man, | |
64 mb_timeval_t *timeout, | |
65 mb_timer_cb_t cb, void *data) { | |
66 struct _njs_timer_timeout *timer_timeout; | |
67 mb_timeval_t now, timeout_diff; | |
68 ev_tstamp timeout_stamp; | |
69 | |
70 timer_timeout = O_ALLOC(struct _njs_timer_timeout); | |
71 if(timer_timeout == NULL) | |
72 return ERR; | |
73 | |
74 timer_timeout->cb = cb; | |
75 timer_timeout->timeout = timeout; | |
76 | |
77 get_now(&now); | |
78 | |
79 memcpy(&timeout_diff, timeout, sizeof(mb_timeval_t)); | |
80 MB_TIMEVAL_DIFF(&timeout_diff, &now); | |
81 timeout_stamp = (ev_tstamp)MB_TIMEVAL_SEC(&timeout_diff) + | |
82 (ev_tstamp)MB_TIMEVAL_USEC(&timeout_diff) / 1000000; | |
83 ev_timer_init(&timer_timeout->tmwatcher, njs_timer_man_cb, | |
84 timeout_stamp, 0); | |
85 ev_timer_start(&timer_timeout->tmwatcher); | |
86 | |
87 return (int)timer_timeout; | |
88 } | |
89 | |
90 static void | |
91 njs_timer_man_remove(struct _mb_timer_man *tm_man, int tm_hdl) { | |
92 struct _njs_timer_timeout *timer_timeout = | |
93 (struct _njs_timer_timeout *)tm_hdl; | |
94 | |
95 ev_timer_stop(&timer_timeout->tmwatcher); | |
96 free(timer_timeout); | |
97 } | |
98 | |
99 static mb_timer_man_t * | |
100 njs_timer_man_new(void) { | |
101 return &njs_timer_man; | |
102 } | |
103 | |
104 static void | |
105 njs_timer_man_free(mb_timer_man_t *timer_man) { | |
106 } | |
107 | |
108 void | |
109 njs_mb_reg_timer_man(void) { | |
110 mb_reg_timer_factory(&njs_timer_factory); | |
111 } | |
112 | |
113 /* @} */ | |
114 | |
115 | |
116 /*! \defgroup njs_io_man IO manager for nodejs. | |
117 * @{ | |
118 */ | |
119 struct _njs_io_reg { | |
120 ev_io iowatcher; | |
121 int fd; | |
122 mb_IO_cb_t cb; | |
123 void *data; | |
124 }; | |
125 | |
126 static int njs_io_man_reg(struct _mb_IO_man *io_man, | |
127 int fd, MB_IO_TYPE type, mb_IO_cb_t cb, void *data); | |
128 static void njs_io_man_unreg(struct _mb_IO_man *io_man, int io_hdl); | |
129 static mb_IO_man_t *njs_io_man_new(void); | |
130 static void njs_io_man_free(mb_IO_man_t *io_man); | |
131 | |
132 static mb_IO_man_t njs_io_man = { | |
133 njs_io_man_reg, | |
134 njs_io_man_unreg | |
135 }; | |
136 | |
137 /*! \brief IO factory to integrate MadButterfly to event loop of nodejs. | |
138 */ | |
139 static mb_IO_factory_t njs_io_factory = { | |
140 njs_io_man_new, | |
141 njs_io_man_free | |
142 }; | |
143 | |
144 /*! \brief Bridge libev callback to IO manager callback. | |
145 */ | |
146 static void | |
147 njs_io_man_cb(EV_P_ ev_io *iowatcher, int revent) { | |
148 struct _njs_io_reg *io_reg = | |
149 MEM2OBJ(iowatcher, struct _njs_io_reg, iowatcher); | |
150 MB_IO_TYPE type; | |
151 | |
152 switch(revent & (EV_READ | EV_WRITE)) { | |
153 case EV_READ: | |
154 type = MB_IO_R; | |
155 break; | |
156 case EV_WRITE: | |
157 type = MB_IO_W; | |
158 break; | |
159 case EV_READ | EV_WRITE: | |
160 type = MB_IO_RW; | |
161 break; | |
162 } | |
163 | |
164 io_reg->cb((int)io_reg, io_reg->fd, type, io_reg->data); | |
165 } | |
166 | |
167 static int | |
168 njs_io_man_reg(struct _mb_IO_man *io_man, | |
169 int fd, MB_IO_TYPE type, mb_IO_cb_t cb, void *data) { | |
170 int _type; | |
171 struct _njs_io_reg *io_reg; | |
172 | |
173 if(type == MB_IO_R) | |
174 _type = EV_READ; | |
175 else if(type == MB_IO_W) | |
176 _type = EV_WRITE; | |
177 else if(type == MB_IO_RW) | |
178 _type = EV_READ | EV_WRITE; | |
179 else | |
180 return ERR; | |
181 | |
182 io_reg = O_ALLOC(struct _njs_io_reg); | |
183 if(io_reg == NULL) | |
184 return ERR; | |
185 | |
186 io_reg->fd = fd; | |
187 io_reg->cb = cb; | |
188 io_reg->data = data; | |
189 | |
190 ev_io_init(&io_reg->iowatcher, njs_io_man_cb, fd, _type); | |
191 ev_io_start(&io_reg->iowatcher); | |
192 | |
193 return (int)io_reg; | |
194 } | |
195 | |
196 static void | |
197 njs_io_man_unreg(struct _mb_IO_man *io_man, int io_hdl) { | |
198 struct _njs_io_reg *io_reg = (struct _njs_io_reg *)io_hdl; | |
199 | |
200 ev_io_stop(&io_reg->iowatcher); | |
201 free(io_reg); | |
202 } | |
203 | |
204 static mb_IO_man_t * | |
205 njs_io_man_new(void) { | |
206 return &njs_io_man; | |
207 } | |
208 | |
209 static void | |
210 njs_io_man_free(mb_IO_man_t *io_man) { | |
211 } | |
212 | |
213 /*! \brief Register an IO factory with MadButterfly backend. | |
214 */ | |
215 void | |
216 njs_mb_reg_IO_man(void) { | |
217 mb_reg_IO_factory(&njs_io_factory); | |
218 } | |
219 | |
220 /* @} */ | |
221 | |
222 /*! \brief Free njs_runtime_t. | |
223 */ | |
224 void | |
225 njs_mb_free(njs_runtime_t *rt) { | |
226 /*! | |
227 * TODO: Release all IO and timer request. | |
228 */ | |
229 mb_runtime_free(rt->mb_rt); | |
230 free(rt); | |
231 } | |
232 | |
233 /*! \brief Free njs_runtime_t. | |
234 */ | |
235 void | |
236 njs_mb_free_keep_win(njs_runtime_t *rt) { | |
237 /* | |
238 * TODO: Release all IO and timer request. | |
239 */ | |
240 mb_runtime_free_keep_win(rt->mb_rt); | |
241 free(rt); | |
242 } | |
243 | |
244 int | |
245 njs_mb_flush(njs_runtime_t *rt) { | |
246 mb_rt_t *mb_rt = rt->mb_rt; | |
247 int r; | |
248 | |
249 r = mb_runtime_flush(mb_rt); | |
250 return r; | |
251 } | |
252 | |
253 njs_runtime_t * | |
254 njs_mb_new(char *display_name, int w, int h) { | |
255 njs_runtime_t *rt; | |
256 mb_rt_t *mb_rt; | |
257 | |
258 rt = (njs_runtime_t *)malloc(sizeof(njs_runtime_t)); | |
259 ASSERT(rt != NULL); | |
260 | |
261 mb_rt = mb_runtime_new(display_name, w, h); | |
262 | |
263 rt->mb_rt = mb_rt; | |
264 | |
265 return rt; | |
266 } | |
267 | |
268 /*! \brief Create a njs_runtime_t for an existed window. | |
269 * | |
270 * The njs_runtime_t created by this function must be free by | |
271 * njs_mb_free_keep_win(). | |
272 */ | |
273 njs_runtime_t * | |
274 njs_mb_new_with_win(void *display, long win) { | |
275 njs_runtime_t *rt; | |
276 mb_rt_t *mb_rt; | |
277 | |
278 rt = (njs_runtime_t *)malloc(sizeof(njs_runtime_t)); | |
279 ASSERT(rt != NULL); | |
280 | |
281 mb_rt = mb_runtime_new_with_win((Display *)display, win); | |
282 | |
283 rt->mb_rt = mb_rt; | |
284 | |
285 return rt; | |
286 } | |
287 | |
288 /*! \brief Pass a X event to X runtime. | |
289 */ | |
290 void | |
291 njs_mb_handle_single_event(njs_runtime_t *rt, void *evt) { | |
292 #if 0 | |
293 void *mb_rt = rt->mb_rt; | |
294 extern void _X_MB_handle_single_event(void *rt, void *evt); | |
295 | |
296 _X_MB_handle_single_event(mb_rt, evt); | |
297 #endif | |
298 } | |
299 | |
300 /*! \brief Called at end of an iteration of event loop. | |
301 */ | |
302 void | |
303 njs_mb_no_more_event(njs_runtime_t *rt) { | |
304 #if 0 | |
305 mb_rt_t *mb_rt = rt->mb_rt; | |
306 extern void _X_MB_no_more_event(mb_rt_t *rt); | |
307 | |
308 _X_MB_no_more_event(mb_rt); | |
309 #endif | |
310 } | |
311 | |
312 /*! \brief Get X runtime that is backend of this njs runtime. | |
313 */ | |
314 mb_rt_t * | |
315 _njs_mb_get_runtime(njs_runtime_t *rt) { | |
316 return rt->mb_rt; | |
317 } |