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 }