Mercurial > MadButterfly
comparison src/X_supp.c @ 1044:5d4bc2a93c09
Merge from refine_backend_if branch
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 23 Nov 2010 11:58:04 +0800 |
parents | 769921baf111 |
children | bf5adf1e275e |
comparison
equal
deleted
inserted
replaced
1035:18329b6f77a4 | 1044:5d4bc2a93c09 |
---|---|
8 #include <cairo-xlib.h> | 8 #include <cairo-xlib.h> |
9 #include "mb_graph_engine.h" | 9 #include "mb_graph_engine.h" |
10 #include "mb_redraw_man.h" | 10 #include "mb_redraw_man.h" |
11 #include "mb_timer.h" | 11 #include "mb_timer.h" |
12 #include "mb_X_supp.h" | 12 #include "mb_X_supp.h" |
13 #include "mb_backend.h" | |
14 #include "mb_backend_utils.h" | |
13 #include "config.h" | 15 #include "config.h" |
14 | 16 |
15 #ifdef XSHM | 17 #ifdef XSHM |
16 /* \sa http://www.xfree86.org/current/mit-shm.html */ | 18 /* \sa http://www.xfree86.org/current/mit-shm.html */ |
17 #include <sys/ipc.h> | 19 #include <sys/ipc.h> |
20 #endif | 22 #endif |
21 | 23 |
22 #define ERR -1 | 24 #define ERR -1 |
23 #define OK 0 | 25 #define OK 0 |
24 | 26 |
27 #define ASSERT(x) | |
28 | |
25 #define ONLY_MOUSE_MOVE_RAW 1 | 29 #define ONLY_MOUSE_MOVE_RAW 1 |
30 | |
31 static mb_timer_factory_t *_timer_factory = &tman_timer_factory; | |
26 | 32 |
27 /*! \ingroup xkb | 33 /*! \ingroup xkb |
28 * @{ | 34 * @{ |
29 */ | 35 */ |
30 struct _X_kb_info { | 36 struct _X_kb_info { |
34 subject_t *kbevents; | 40 subject_t *kbevents; |
35 ob_factory_t *ob_factory; | 41 ob_factory_t *ob_factory; |
36 }; | 42 }; |
37 | 43 |
38 /* @} */ | 44 /* @} */ |
39 #define MAX_MONITORS 200 | 45 |
40 typedef struct { | 46 struct _X_supp_runtime { |
41 int type; | |
42 int fd; | |
43 mb_eventcb_t f; | |
44 void *arg; | |
45 } monitor_t; | |
46 | |
47 struct _X_MB_runtime { | |
48 Display *display; | 47 Display *display; |
49 Window win; | 48 Window win; |
50 Visual *visual; | 49 Visual *visual; |
51 mbe_surface_t *surface, *backend_surface; | 50 mbe_surface_t *surface, *backend_surface; |
52 mbe_pattern_t *surface_ptn; | 51 mbe_pattern_t *surface_ptn; |
53 mbe_t *cr, *backend_cr; | 52 mbe_t *cr, *backend_cr; |
54 redraw_man_t *rdman; | 53 redraw_man_t *rdman; |
55 mb_tman_t *tman; | |
56 mb_img_ldr_t *img_ldr; | 54 mb_img_ldr_t *img_ldr; |
57 int w, h; | 55 int w, h; |
58 | 56 |
59 X_kb_info_t kbinfo; | 57 X_kb_info_t kbinfo; |
60 monitor_t monitors[MAX_MONITORS]; | 58 mb_IO_man_t *io_man; |
61 int n_monitor; | 59 mb_timer_man_t *timer_man; |
62 | 60 |
63 #ifndef ONLY_MOUSE_MOVE_RAW | 61 #ifndef ONLY_MOUSE_MOVE_RAW |
64 /* States */ | 62 /* States */ |
65 shape_t *last; | 63 shape_t *last; |
66 #endif | 64 #endif |
67 | 65 |
68 #ifdef XSHM | 66 #ifdef XSHM |
69 XImage *ximage; | 67 XImage *ximage; |
70 XShmSegmentInfo shminfo; | 68 XShmSegmentInfo shminfo; |
71 #endif | 69 #endif |
70 | |
71 /* For handle connection */ | |
72 int io_hdl; | |
72 | 73 |
73 /* | 74 /* |
74 * Following variables are used by handle_single_x_event() | 75 * Following variables are used by handle_single_x_event() |
75 */ | 76 */ |
76 int last_evt_type; /* Type of last event */ | 77 int last_evt_type; /* Type of last event */ |
79 int mflag; | 80 int mflag; |
80 int mx, my; /* Position of last motion event */ | 81 int mx, my; /* Position of last motion event */ |
81 int mbut_state; /* Button state of last motion event */ | 82 int mbut_state; /* Button state of last motion event */ |
82 }; | 83 }; |
83 | 84 |
85 static void _x_supp_handle_x_event(X_supp_runtime_t *rt); | |
86 | |
87 /*! \defgroup x_supp_io IO manager for X. | |
88 * @{ | |
89 */ | |
90 #define MAX_MONITORS 200 | |
91 | |
92 typedef struct { | |
93 int type; | |
94 int fd; | |
95 mb_IO_cb_t cb; | |
96 void *data; | |
97 } monitor_t; | |
98 | |
99 struct _X_supp_IO_man { | |
100 mb_IO_man_t io_man; | |
101 monitor_t monitors[MAX_MONITORS]; | |
102 int n_monitor; | |
103 }; | |
104 | |
105 static int _x_supp_io_man_reg(struct _mb_IO_man *io_man, | |
106 int fd, MB_IO_TYPE type, | |
107 mb_IO_cb_t cb, void *data); | |
108 static void _x_supp_io_man_unreg(struct _mb_IO_man *io_man, int io_hdl); | |
109 static mb_IO_man_t *_x_supp_io_man_new(void); | |
110 static void _x_supp_io_man_free(mb_IO_man_t *io_man); | |
111 | |
112 static mb_IO_factory_t _X_supp_default_io_factory = { | |
113 _x_supp_io_man_new, | |
114 _x_supp_io_man_free | |
115 }; | |
116 static mb_IO_factory_t *_io_factory = &_X_supp_default_io_factory; | |
117 | |
118 static struct _X_supp_IO_man _default_io_man = { | |
119 {_x_supp_io_man_reg, _x_supp_io_man_unreg}, | |
120 {}, /* monitors */ | |
121 0 /* n_monitor */ | |
122 }; | |
123 | |
124 static mb_IO_man_t * | |
125 _x_supp_io_man_new(void) { | |
126 return (mb_IO_man_t *)&_default_io_man; | |
127 } | |
128 | |
129 static void | |
130 _x_supp_io_man_free(mb_IO_man_t *io_man) { | |
131 } | |
132 | |
133 static int | |
134 _x_supp_io_man_reg(struct _mb_IO_man *io_man, | |
135 int fd, MB_IO_TYPE type, mb_IO_cb_t cb, void *data) { | |
136 struct _X_supp_IO_man *xmb_io_man = (struct _X_supp_IO_man *)io_man; | |
137 int i; | |
138 | |
139 for(i = 0; i < xmb_io_man->n_monitor; i++) { | |
140 if (xmb_io_man->monitors[i].type == MB_IO_DUMMY) | |
141 break; | |
142 } | |
143 if (i == MAX_MONITORS) | |
144 return ERR; | |
145 | |
146 xmb_io_man->monitors[i].type = type; | |
147 xmb_io_man->monitors[i].fd = fd; | |
148 xmb_io_man->monitors[i].cb = cb; | |
149 xmb_io_man->monitors[i].data = data; | |
150 i++; | |
151 if(i > xmb_io_man->n_monitor) | |
152 xmb_io_man->n_monitor = i; | |
153 return i - 1; | |
154 } | |
155 | |
156 static void | |
157 _x_supp_io_man_unreg(struct _mb_IO_man *io_man, int io_hdl) { | |
158 struct _X_supp_IO_man *xmb_io_man = (struct _X_supp_IO_man *)io_man; | |
159 | |
160 ASSERT(io_hdl < xmb_io_man->n_monitor); | |
161 xmb_io_man->monitors[io_hdl].type = MB_IO_DUMMY; | |
162 } | |
163 | |
164 /*! \brief Handle connection coming data and timeout of timers. | |
165 * | |
166 * \param display is a Display returned by XOpenDisplay(). | |
167 * \param rdman is a redraw manager. | |
168 * \param tman is a timer manager. | |
169 * | |
170 * The display is managed by specified rdman and tman. rdman draws | |
171 * on the display, and tman trigger actions according timers. | |
172 */ | |
173 static void | |
174 _x_supp_event_loop(mb_rt_t *rt) { | |
175 struct _X_supp_runtime *xmb_rt = (struct _X_supp_runtime *)rt; | |
176 struct _X_supp_IO_man *io_man = (struct _X_supp_IO_man *)xmb_rt->io_man; | |
177 mb_timer_man_t *timer_man = (mb_timer_man_t *)xmb_rt->timer_man; | |
178 redraw_man_t *rdman; | |
179 mb_tman_t *tman = tman_timer_man_get_tman(timer_man); | |
180 mb_timeval_t now, tmo; | |
181 struct timeval tv; | |
182 fd_set rfds, wfds; | |
183 int nfds = 0; | |
184 int r, r1,i; | |
185 | |
186 rdman = mb_runtime_rdman(rt); | |
187 | |
188 _x_supp_handle_x_event(xmb_rt); | |
189 | |
190 while(1) { | |
191 FD_ZERO(&rfds); | |
192 FD_ZERO(&wfds); | |
193 for(i = 0; i < io_man->n_monitor; i++) { | |
194 if(io_man->monitors[i].type == MB_IO_R || | |
195 io_man->monitors[i].type == MB_IO_RW) { | |
196 FD_SET(io_man->monitors[i].fd, &rfds); | |
197 nfds = MB_MAX(nfds, io_man->monitors[i].fd + 1); | |
198 } | |
199 if(io_man->monitors[i].type == MB_IO_W || | |
200 io_man->monitors[i].type == MB_IO_RW) { | |
201 FD_SET(io_man->monitors[i].fd, &wfds); | |
202 nfds = MB_MAX(nfds, io_man->monitors[i].fd + 1); | |
203 } | |
204 } | |
205 | |
206 get_now(&now); | |
207 r = mb_tman_next_timeout(tman, &now, &tmo); | |
208 | |
209 if(r == 0) { | |
210 tv.tv_sec = MB_TIMEVAL_SEC(&tmo); | |
211 tv.tv_usec = MB_TIMEVAL_USEC(&tmo); | |
212 r1 = select(nfds, &rfds, NULL, NULL, &tv); | |
213 } else | |
214 r1 = select(nfds, &rfds, NULL, NULL, NULL); | |
215 | |
216 if(r1 == -1) { | |
217 perror("select"); | |
218 break; | |
219 } | |
220 | |
221 if(r1 == 0) { | |
222 get_now(&now); | |
223 mb_tman_handle_timeout(tman, &now); | |
224 rdman_redraw_changed(rdman); | |
84 #ifdef XSHM | 225 #ifdef XSHM |
85 static void | 226 XSHM_update(xmb_rt); |
86 XSHM_update(X_MB_runtime_t *xmb_rt) { | 227 #endif |
228 XFlush(xmb_rt->display); | |
229 } else { | |
230 for(i = 0; i < io_man->n_monitor; i++) { | |
231 if(io_man->monitors[i].type == MB_IO_R || | |
232 io_man->monitors[i].type == MB_IO_RW) { | |
233 if(FD_ISSET(io_man->monitors[i].fd, &rfds)) | |
234 io_man->monitors[i].cb(i, io_man->monitors[i].fd, | |
235 MB_IO_R, | |
236 io_man->monitors[i].data); | |
237 } | |
238 if(io_man->monitors[i].type == MB_IO_W || | |
239 io_man->monitors[i].type == MB_IO_RW) { | |
240 if(FD_ISSET(io_man->monitors[i].fd, &wfds)) | |
241 io_man->monitors[i].cb(i, io_man->monitors[i].fd, | |
242 MB_IO_W, | |
243 io_man->monitors[i].data); | |
244 } | |
245 } | |
246 } | |
247 } | |
248 } | |
249 | |
250 /* @} */ | |
251 | |
252 #ifdef XSHM | |
253 static void | |
254 XSHM_update(X_supp_runtime_t *xmb_rt) { | |
87 GC gc; | 255 GC gc; |
88 | 256 |
89 gc = DefaultGC(xmb_rt->display, DefaultScreen(xmb_rt->display)); | 257 gc = DefaultGC(xmb_rt->display, DefaultScreen(xmb_rt->display)); |
90 if(xmb_rt->ximage) { /* support XSHM */ | 258 if(xmb_rt->ximage) { /* support XSHM */ |
91 XShmPutImage(xmb_rt->display, | 259 XShmPutImage(xmb_rt->display, |
146 static void X_kb_destroy(X_kb_info_t *kbinfo) { | 314 static void X_kb_destroy(X_kb_info_t *kbinfo) { |
147 subject_free(kbinfo->kbevents); | 315 subject_free(kbinfo->kbevents); |
148 XFree(kbinfo->syms); | 316 XFree(kbinfo->syms); |
149 } | 317 } |
150 | 318 |
151 /*! \brief Accept X keyboard events from handle_x_event() and dispatch it. | 319 /*! \brief Accept X keyboard events from _x_supp_handle_x_event() and |
320 * dispatch it. | |
152 */ | 321 */ |
153 static void X_kb_handle_event(X_kb_info_t *kbinfo, XKeyEvent *xkey) { | 322 static void X_kb_handle_event(X_kb_info_t *kbinfo, XKeyEvent *xkey) { |
154 unsigned int code; | 323 unsigned int code; |
155 int sym; | 324 int sym; |
156 X_kb_event_t event; | 325 X_kb_event_t event; |
165 event.keycode = code; | 334 event.keycode = code; |
166 event.sym = sym; | 335 event.sym = sym; |
167 | 336 |
168 subject_notify(kbinfo->kbevents, &event.event); | 337 subject_notify(kbinfo->kbevents, &event.event); |
169 } | 338 } |
170 | |
171 /* @} */ | 339 /* @} */ |
172 | 340 |
173 static unsigned int get_button_state(unsigned int state) { | 341 static unsigned int get_button_state(unsigned int state) { |
174 unsigned int but = 0; | 342 unsigned int but = 0; |
175 | 343 |
225 } | 393 } |
226 | 394 |
227 /*! \brief Handle motion event. | 395 /*! \brief Handle motion event. |
228 */ | 396 */ |
229 static void | 397 static void |
230 handle_motion_event(X_MB_runtime_t *rt) { | 398 handle_motion_event(X_supp_runtime_t *rt) { |
231 redraw_man_t *rdman = rt->rdman; | 399 redraw_man_t *rdman = rt->rdman; |
232 int x, y; | 400 int x, y; |
233 int state; | 401 int state; |
234 shape_t *shape; | 402 shape_t *shape; |
235 coord_t *root; | 403 coord_t *root; |
275 } | 443 } |
276 | 444 |
277 /*! \brief Redraw exposed area. | 445 /*! \brief Redraw exposed area. |
278 */ | 446 */ |
279 static void | 447 static void |
280 handle_expose_event(X_MB_runtime_t *rt) { | 448 handle_expose_event(X_supp_runtime_t *rt) { |
281 redraw_man_t *rdman = rt->rdman; | 449 redraw_man_t *rdman = rt->rdman; |
282 int ex1, ey1, ex2, ey2; | 450 int ex1, ey1, ex2, ey2; |
283 | 451 |
284 ex1 = rt->ex1; | 452 ex1 = rt->ex1; |
285 ey1 = rt->ey1; | 453 ey1 = rt->ey1; |
294 /*! \brief Handle single X event and maintain internal states. | 462 /*! \brief Handle single X event and maintain internal states. |
295 * | 463 * |
296 * It keeps internal state in rt to improve performance. | 464 * It keeps internal state in rt to improve performance. |
297 */ | 465 */ |
298 static void | 466 static void |
299 handle_single_x_event(X_MB_runtime_t *rt, XEvent *evt) { | 467 handle_single_x_event(X_supp_runtime_t *rt, XEvent *evt) { |
300 redraw_man_t *rdman = rt->rdman; | 468 redraw_man_t *rdman = rt->rdman; |
301 XMotionEvent *mevt; | 469 XMotionEvent *mevt; |
302 XButtonEvent *bevt; | 470 XButtonEvent *bevt; |
303 XExposeEvent *eevt; | 471 XExposeEvent *eevt; |
304 XKeyEvent *xkey; | 472 XKeyEvent *xkey; |
388 * | 556 * |
389 * No more event means event queue is emplty. This function will | 557 * No more event means event queue is emplty. This function will |
390 * perform some actions according current internal state. | 558 * perform some actions according current internal state. |
391 */ | 559 */ |
392 static void | 560 static void |
393 no_more_event(X_MB_runtime_t *rt) { | 561 no_more_event(X_supp_runtime_t *rt) { |
394 if(rt->mflag) | 562 if(rt->mflag) |
395 handle_motion_event(rt); | 563 handle_motion_event(rt); |
396 if(rt->eflag) | 564 if(rt->eflag) |
397 handle_expose_event(rt); | 565 handle_expose_event(rt); |
398 } | 566 } |
399 | 567 |
400 /*! \brief Dispatch all X events in the queue. | 568 /*! \brief Dispatch all X events in the queue. |
401 */ | 569 */ |
402 static void handle_x_event(X_MB_runtime_t *rt) { | 570 static void _x_supp_handle_x_event(X_supp_runtime_t *rt) { |
403 Display *display = rt->display; | 571 Display *display = rt->display; |
404 XEvent evt; | 572 XEvent evt; |
405 int r; | 573 int r; |
406 | 574 |
407 /* XXX: For some unknown reason, it causes a segmentation fault to | 575 /* XXX: For some unknown reason, it causes a segmentation fault to |
421 XSHM_update(rt); | 589 XSHM_update(rt); |
422 #endif | 590 #endif |
423 XFlush(display); | 591 XFlush(display); |
424 } | 592 } |
425 | 593 |
426 /*! \brief Handle connection coming data and timeout of timers. | 594 static void |
427 * | 595 _x_supp_handle_connection(int hdl, int fd, MB_IO_TYPE type, void *data) { |
428 * \param display is a Display returned by XOpenDisplay(). | 596 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *)data; |
429 * \param rdman is a redraw manager. | 597 |
430 * \param tman is a timer manager. | 598 _x_supp_handle_x_event(xmb_rt); |
431 * | 599 } |
432 * The display is managed by specified rdman and tman. rdman draws | |
433 * on the display, and tman trigger actions according timers. | |
434 */ | |
435 void X_MB_handle_connection(void *be) { | |
436 X_MB_runtime_t *rt = (X_MB_runtime_t *) be; | |
437 Display *display = rt->display; | |
438 redraw_man_t *rdman = rt->rdman; | |
439 mb_tman_t *tman = rt->tman; | |
440 int fd; | |
441 mb_timeval_t now, tmo; | |
442 struct timeval tv; | |
443 fd_set rfds,wfds; | |
444 int nfds; | |
445 int r, r1,i; | |
446 | |
447 handle_x_event(rt); | |
448 | |
449 fd = XConnectionNumber(display); | |
450 nfds = fd + 1; | |
451 while(1) { | |
452 FD_ZERO(&rfds); | |
453 FD_ZERO(&wfds); | |
454 FD_SET(fd, &rfds); | |
455 for(i=0;i<rt->n_monitor;i++) { | |
456 if (rt->monitors[i].type == MONITOR_READ) | |
457 FD_SET(rt->monitors[i].fd, &rfds); | |
458 else if (rt->monitors[i].type == MONITOR_WRITE) | |
459 FD_SET(rt->monitors[i].fd, &wfds); | |
460 } | |
461 | |
462 get_now(&now); | |
463 r = mb_tman_next_timeout(tman, &now, &tmo); | |
464 | |
465 if(r == 0) { | |
466 tv.tv_sec = MB_TIMEVAL_SEC(&tmo); | |
467 tv.tv_usec = MB_TIMEVAL_USEC(&tmo); | |
468 r1 = select(nfds, &rfds, NULL, NULL, &tv); | |
469 } else | |
470 r1 = select(nfds, &rfds, NULL, NULL, NULL); | |
471 | |
472 if(r1 == -1) { | |
473 perror("select"); | |
474 break; | |
475 } | |
476 | |
477 if(r1 == 0) { | |
478 get_now(&now); | |
479 mb_tman_handle_timeout(tman, &now); | |
480 rdman_redraw_changed(rdman); | |
481 #ifdef XSHM | |
482 XSHM_update(rt); | |
483 #endif | |
484 XFlush(display); | |
485 } else if(FD_ISSET(fd, &rfds)){ | |
486 handle_x_event(rt); | |
487 } else { | |
488 for(i=0;i<rt->n_monitor;i++) { | |
489 if (rt->monitors[i].type == MONITOR_READ) { | |
490 if (FD_ISSET(rt->monitors[i].fd, &rfds)) | |
491 rt->monitors[i].f(rt->monitors[i].fd,rt->monitors[i].arg); | |
492 } else if (rt->monitors[i].type == MONITOR_WRITE) { | |
493 if (FD_ISSET(rt->monitors[i].fd, &wfds)) | |
494 rt->monitors[i].f(rt->monitors[i].fd,rt->monitors[i].arg); | |
495 } | |
496 } | |
497 } | |
498 } | |
499 } | |
500 | |
501 #define ERR -1 | |
502 #define OK 0 | |
503 | 600 |
504 static int X_init_connection(const char *display_name, | 601 static int X_init_connection(const char *display_name, |
505 int w, int h, | 602 int w, int h, |
506 Display **displayp, | 603 Display **displayp, |
507 Visual **visualp, | 604 Visual **visualp, |
571 return OK; | 668 return OK; |
572 } | 669 } |
573 | 670 |
574 #ifdef XSHM | 671 #ifdef XSHM |
575 static void | 672 static void |
576 xshm_destroy(X_MB_runtime_t *xmb_rt) { | 673 xshm_destroy(X_supp_runtime_t *xmb_rt) { |
577 XShmSegmentInfo *shminfo; | 674 XShmSegmentInfo *shminfo; |
578 | 675 |
579 shminfo = &xmb_rt->shminfo; | 676 shminfo = &xmb_rt->shminfo; |
580 | 677 |
581 if(xmb_rt->shminfo.shmaddr) { | 678 if(xmb_rt->shminfo.shmaddr) { |
597 shminfo->shmid = 0; | 694 shminfo->shmid = 0; |
598 } | 695 } |
599 } | 696 } |
600 | 697 |
601 static void | 698 static void |
602 xshm_init(X_MB_runtime_t *xmb_rt) { | 699 xshm_init(X_supp_runtime_t *xmb_rt) { |
603 Display *display; | 700 Display *display; |
604 Visual *visual; | 701 Visual *visual; |
605 XImage *ximage; | 702 XImage *ximage; |
606 int screen; | 703 int screen; |
607 int depth; | 704 int depth; |
659 } | 756 } |
660 #endif /* XSHM */ | 757 #endif /* XSHM */ |
661 | 758 |
662 /*! \brief Initialize a MadButterfy runtime for Xlib. | 759 /*! \brief Initialize a MadButterfy runtime for Xlib. |
663 * | 760 * |
664 * This one is very like X_MB_init(), except it accepts a | 761 * This one is very like _x_supp_init(), except it accepts a |
665 * X_MB_runtime_t object initialized with a display connected to a X | 762 * X_supp_runtime_t object initialized with a display connected to a X |
666 * server and an opened window. | 763 * server and an opened window. |
667 * | 764 * |
668 * Following field of the X_MB_runtime_t object should be initialized. | 765 * Following field of the X_supp_runtime_t object should be initialized. |
669 * - w, h | 766 * - w, h |
670 * - win | 767 * - win |
671 * - display | 768 * - display |
672 * - visual | 769 * - visual |
673 */ | 770 */ |
674 static int | 771 static int |
675 X_MB_init_with_win_internal(X_MB_runtime_t *xmb_rt) { | 772 _x_supp_init_with_win_internal(X_supp_runtime_t *xmb_rt) { |
676 mb_img_ldr_t *img_ldr; | 773 mb_img_ldr_t *img_ldr; |
677 int w, h; | 774 int w, h; |
775 int disp_fd; | |
678 | 776 |
679 w = xmb_rt->w; | 777 w = xmb_rt->w; |
680 h = xmb_rt->h; | 778 h = xmb_rt->h; |
681 | 779 |
682 #ifdef XSHM | 780 #ifdef XSHM |
706 // FIXME: This is a wired loopback reference. This is inly required when we need | 804 // FIXME: This is a wired loopback reference. This is inly required when we need |
707 // to get the xmb_rt->tman for the animation. We should relocate the tman | 805 // to get the xmb_rt->tman for the animation. We should relocate the tman |
708 // to the redraw_man_t instead. | 806 // to the redraw_man_t instead. |
709 xmb_rt->rdman->rt = xmb_rt; | 807 xmb_rt->rdman->rt = xmb_rt; |
710 | 808 |
711 xmb_rt->tman = mb_tman_new(); | 809 xmb_rt->io_man = mb_io_man_new(_io_factory); |
810 xmb_rt->timer_man = mb_timer_man_new(_timer_factory); | |
712 | 811 |
713 img_ldr = simple_mb_img_ldr_new(""); | 812 img_ldr = simple_mb_img_ldr_new(""); |
714 xmb_rt->img_ldr = img_ldr; | 813 xmb_rt->img_ldr = img_ldr; |
715 rdman_set_img_ldr(xmb_rt->rdman, img_ldr); | 814 /*! \todo Remove rdman_set_img_ldr() */ |
716 memset(xmb_rt->monitors,0,sizeof(xmb_rt->monitors)); | 815 rdman_set_img_ldr(xmb_rt->rdman, img_ldr); /* this is ncessary? */ |
717 | 816 |
718 #ifndef ONLY_MOUSE_MOVE_RAW | 817 #ifndef ONLY_MOUSE_MOVE_RAW |
719 xmb_rt->last = NULL; | 818 xmb_rt->last = NULL; |
720 #endif | 819 #endif |
721 | 820 |
722 X_kb_init(&xmb_rt->kbinfo, xmb_rt->display, xmb_rt->rdman); | 821 X_kb_init(&xmb_rt->kbinfo, xmb_rt->display, xmb_rt->rdman); |
723 | 822 |
823 disp_fd = XConnectionNumber(xmb_rt->display); | |
824 xmb_rt->io_hdl = mb_io_man_reg(xmb_rt->io_man, disp_fd, | |
825 MB_IO_R, | |
826 _x_supp_handle_connection, | |
827 xmb_rt); | |
828 | |
724 return OK; | 829 return OK; |
725 } | 830 } |
726 | 831 |
727 /*! \brief Initialize a MadButterfy runtime for Xlib. | 832 /*! \brief Initialize a MadButterfy runtime for Xlib. |
728 * | 833 * |
729 * It setups a runtime environment to run MadButterfly with Xlib. | 834 * It setups a runtime environment to run MadButterfly with Xlib. |
730 * Users should specify width and height of the opening window. | 835 * Users should specify width and height of the opening window. |
731 */ | 836 */ |
732 static int X_MB_init(X_MB_runtime_t *xmb_rt, const char *display_name, | 837 static int _x_supp_init(X_supp_runtime_t *xmb_rt, const char *display_name, |
733 int w, int h) { | 838 int w, int h) { |
734 int r; | 839 int r; |
735 | 840 |
736 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); | 841 memset(xmb_rt, 0, sizeof(X_supp_runtime_t)); |
737 | 842 |
738 xmb_rt->w = w; | 843 xmb_rt->w = w; |
739 xmb_rt->h = h; | 844 xmb_rt->h = h; |
740 r = X_init_connection(display_name, w, h, &xmb_rt->display, | 845 r = X_init_connection(display_name, w, h, &xmb_rt->display, |
741 &xmb_rt->visual, &xmb_rt->win); | 846 &xmb_rt->visual, &xmb_rt->win); |
742 if(r != OK) | 847 if(r != OK) |
743 return ERR; | 848 return ERR; |
744 | 849 |
745 r = X_MB_init_with_win_internal(xmb_rt); | 850 r = _x_supp_init_with_win_internal(xmb_rt); |
746 | 851 |
747 return r; | 852 return r; |
748 } | 853 } |
749 | 854 |
750 /*! \brief Initialize a MadButterfly runtime for a window of X. | 855 /*! \brief Initialize a MadButterfly runtime for a window of X. |
751 * | 856 * |
752 * Runtimes initialized with this function should be destroyed with | 857 * Runtimes initialized with this function should be destroyed with |
753 * X_MB_destroy_keep_win(). | 858 * x_supp_destroy_keep_win(). |
754 */ | 859 */ |
755 static int | 860 static int |
756 X_MB_init_with_win(X_MB_runtime_t *xmb_rt, | 861 _x_supp_init_with_win(X_supp_runtime_t *xmb_rt, |
757 Display *display, Window win) { | 862 Display *display, Window win) { |
758 XWindowAttributes attrs; | 863 XWindowAttributes attrs; |
759 int r; | 864 int r; |
760 | 865 |
761 r = XGetWindowAttributes(display, win, &attrs); | 866 r = XGetWindowAttributes(display, win, &attrs); |
762 if(r == 0) | 867 if(r == 0) |
763 return ERR; | 868 return ERR; |
764 | 869 |
765 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); | 870 memset(xmb_rt, 0, sizeof(X_supp_runtime_t)); |
766 | 871 |
767 xmb_rt->display = display; | 872 xmb_rt->display = display; |
768 xmb_rt->win = win; | 873 xmb_rt->win = win; |
769 xmb_rt->visual = attrs.visual; | 874 xmb_rt->visual = attrs.visual; |
770 xmb_rt->w = attrs.width; | 875 xmb_rt->w = attrs.width; |
771 xmb_rt->h = attrs.height; | 876 xmb_rt->h = attrs.height; |
772 | 877 |
773 r = X_MB_init_with_win_internal(xmb_rt); | 878 r = _x_supp_init_with_win_internal(xmb_rt); |
774 | 879 |
775 return r; | 880 return r; |
776 } | 881 } |
777 | 882 |
778 static void X_MB_destroy(X_MB_runtime_t *xmb_rt) { | 883 static void x_supp_destroy(X_supp_runtime_t *xmb_rt) { |
779 if(xmb_rt->rdman) { | 884 if(xmb_rt->rdman) { |
780 redraw_man_destroy(xmb_rt->rdman); | 885 redraw_man_destroy(xmb_rt->rdman); |
781 free(xmb_rt->rdman); | 886 free(xmb_rt->rdman); |
782 } | 887 } |
783 | 888 |
784 if(xmb_rt->tman) | 889 if(xmb_rt->io_hdl) |
785 mb_tman_free(xmb_rt->tman); | 890 mb_io_man_unreg(xmb_rt->io_man, xmb_rt->io_hdl); |
891 | |
892 if(xmb_rt->io_man) | |
893 mb_io_man_free(_io_factory, xmb_rt->io_man); | |
894 if(xmb_rt->timer_man) | |
895 mb_timer_man_free(_timer_factory, xmb_rt->timer_man); | |
786 | 896 |
787 if(xmb_rt->img_ldr) | 897 if(xmb_rt->img_ldr) |
788 MB_IMG_LDR_FREE(xmb_rt->img_ldr); | 898 MB_IMG_LDR_FREE(xmb_rt->img_ldr); |
789 | 899 |
790 if(xmb_rt->cr) | 900 if(xmb_rt->cr) |
804 | 914 |
805 X_kb_destroy(&xmb_rt->kbinfo); | 915 X_kb_destroy(&xmb_rt->kbinfo); |
806 } | 916 } |
807 | 917 |
808 /*! \brief Destroy a MadButterfly runtime initialized with | 918 /*! \brief Destroy a MadButterfly runtime initialized with |
809 * X_MB_init_with_win(). | 919 * _x_supp_init_with_win(). |
810 * | 920 * |
811 * Destroying a runtime with this function prevent the window and | 921 * Destroying a runtime with this function prevent the window and |
812 * display associated with the runtime being closed. | 922 * display associated with the runtime being closed. |
813 */ | 923 */ |
814 static void | 924 static void |
815 X_MB_destroy_keep_win(X_MB_runtime_t *xmb_rt) { | 925 x_supp_destroy_keep_win(X_supp_runtime_t *xmb_rt) { |
816 Display *display; | 926 Display *display; |
817 Window win; | 927 Window win; |
818 | 928 |
819 display = xmb_rt->display; | 929 display = xmb_rt->display; |
820 xmb_rt->display = NULL; | 930 xmb_rt->display = NULL; |
821 win = xmb_rt->win; | 931 win = xmb_rt->win; |
822 xmb_rt->win = 0; | 932 xmb_rt->win = 0; |
823 | 933 |
824 X_MB_destroy(xmb_rt); | 934 x_supp_destroy(xmb_rt); |
825 | 935 |
826 xmb_rt->display = display; | 936 xmb_rt->display = display; |
827 xmb_rt->win = win; | 937 xmb_rt->win = win; |
828 } | 938 } |
829 | 939 |
830 void *X_MB_new(const char *display_name, int w, int h) { | 940 static mb_rt_t * |
831 X_MB_runtime_t *rt; | 941 _x_supp_new(const char *display_name, int w, int h) { |
942 X_supp_runtime_t *rt; | |
832 int r; | 943 int r; |
833 | 944 |
834 rt = O_ALLOC(X_MB_runtime_t); | 945 rt = O_ALLOC(X_supp_runtime_t); |
835 if(rt == NULL) | 946 if(rt == NULL) |
836 return NULL; | 947 return NULL; |
837 | 948 |
838 r = X_MB_init(rt, display_name, w, h); | 949 r = _x_supp_init(rt, display_name, w, h); |
839 if(r != OK) { | 950 if(r != OK) { |
840 free(rt); | 951 free(rt); |
841 return NULL; | 952 return NULL; |
842 } | 953 } |
843 | 954 |
844 return rt; | 955 return (mb_rt_t *)rt; |
845 } | 956 } |
846 | 957 |
847 /*! \brief Create a new runtime for existed window for X. | 958 /*! \brief Create a new runtime for existed window for X. |
848 * | 959 * |
849 * The object returned by this function must be free with | 960 * The object returned by this function must be free with |
850 * X_MB_free_keep_win() to prevent the window from closed. | 961 * _x_supp_free_keep_win() to prevent the window from closed. |
851 */ | 962 */ |
852 void *X_MB_new_with_win(Display *display, Window win) { | 963 static mb_rt_t * |
853 X_MB_runtime_t *rt; | 964 _x_supp_new_with_win(MB_DISPLAY display, MB_WINDOW win) { |
965 X_supp_runtime_t *rt; | |
854 int r; | 966 int r; |
855 | 967 |
856 rt = O_ALLOC(X_MB_runtime_t); | 968 rt = O_ALLOC(X_supp_runtime_t); |
857 if(rt == NULL) | 969 if(rt == NULL) |
858 return NULL; | 970 return NULL; |
859 | 971 |
860 r = X_MB_init_with_win(rt, display, win); | 972 r = _x_supp_init_with_win(rt, display, win); |
861 if(r != OK) { | 973 if(r != OK) { |
862 free(rt); | 974 free(rt); |
863 return NULL; | 975 return NULL; |
864 } | 976 } |
865 | 977 |
866 return rt; | 978 return (mb_rt_t *)rt; |
867 } | 979 } |
868 | 980 |
869 void X_MB_free(void *rt) { | 981 static void |
870 X_MB_destroy((X_MB_runtime_t *) rt); | 982 _x_supp_free(mb_rt_t *rt) { |
983 x_supp_destroy((X_supp_runtime_t *) rt); | |
871 free(rt); | 984 free(rt); |
872 } | 985 } |
873 | 986 |
874 /*! \brief Free runtime created with X_MB_new_with_win(). | 987 /*! \brief Free runtime created with _x_supp_new_with_win(). |
875 */ | 988 */ |
876 void | 989 static void |
877 X_MB_free_keep_win(void *rt) { | 990 _x_supp_free_keep_win(mb_rt_t *rt) { |
878 X_MB_destroy_keep_win((X_MB_runtime_t *) rt); | 991 x_supp_destroy_keep_win((X_supp_runtime_t *) rt); |
879 free(rt); | 992 free(rt); |
880 } | 993 } |
881 | 994 |
882 subject_t *X_MB_kbevents(void *rt) { | 995 static subject_t * |
883 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 996 _x_supp_kbevents(mb_rt_t *rt) { |
997 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; | |
884 return xmb_rt->kbinfo.kbevents; | 998 return xmb_rt->kbinfo.kbevents; |
885 } | 999 } |
886 | 1000 |
887 redraw_man_t *X_MB_rdman(void *rt) { | 1001 static redraw_man_t * |
888 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 1002 _x_supp_rdman(mb_rt_t *rt) { |
1003 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; | |
889 return xmb_rt->rdman; | 1004 return xmb_rt->rdman; |
890 } | 1005 } |
891 | 1006 |
892 mb_tman_t *X_MB_tman(void *rt) { | 1007 static mb_timer_man_t * |
893 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 1008 _x_supp_timer_man(mb_rt_t *rt) { |
894 return xmb_rt->tman; | 1009 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; |
895 } | 1010 return xmb_rt->timer_man; |
896 | 1011 } |
897 ob_factory_t *X_MB_ob_factory(void *rt) { | 1012 |
898 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 1013 static ob_factory_t * |
1014 _x_supp_ob_factory(mb_rt_t *rt) { | |
1015 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; | |
899 ob_factory_t *factory; | 1016 ob_factory_t *factory; |
900 | 1017 |
901 factory = rdman_get_ob_factory(xmb_rt->rdman); | 1018 factory = rdman_get_ob_factory(xmb_rt->rdman); |
902 return factory; | 1019 return factory; |
903 } | 1020 } |
904 | 1021 |
905 mb_img_ldr_t *X_MB_img_ldr(void *rt) { | 1022 static mb_img_ldr_t * |
906 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 1023 _x_supp_img_ldr(mb_rt_t *rt) { |
1024 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; | |
907 mb_img_ldr_t *img_ldr; | 1025 mb_img_ldr_t *img_ldr; |
908 | 1026 |
909 img_ldr = xmb_rt->img_ldr; | 1027 img_ldr = xmb_rt->img_ldr; |
910 | 1028 |
911 return img_ldr; | 1029 return img_ldr; |
912 } | 1030 } |
913 | 1031 |
914 void X_MB_add_event(void *rt, int type, int fd, mb_eventcb_t f,void *arg) | 1032 static int |
1033 _x_supp_add_event(mb_rt_t *rt, int fd, MB_IO_TYPE type, | |
1034 mb_IO_cb_t cb, void *data) | |
915 { | 1035 { |
916 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 1036 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; |
917 int i; | 1037 mb_IO_man_t *io_man = xmb_rt->io_man; |
918 | 1038 int hdl; |
919 for(i=0;i<xmb_rt->n_monitor;i++) { | 1039 |
920 if (xmb_rt->monitors[i].type == type && xmb_rt->monitors[i].fd == fd) { | 1040 hdl = mb_io_man_reg(io_man, fd, type, cb, data); |
921 xmb_rt->monitors[i].f = f; | 1041 return hdl; |
922 xmb_rt->monitors[i].arg = arg; | 1042 } |
923 return; | 1043 |
924 } | 1044 static void |
925 } | 1045 _x_supp_remove_event(mb_rt_t *rt, int hdl) |
926 for(i=0;i<xmb_rt->n_monitor;i++) { | |
927 if (xmb_rt->monitors[i].type == 0) { | |
928 xmb_rt->monitors[i].type = type; | |
929 xmb_rt->monitors[i].fd = fd; | |
930 xmb_rt->monitors[i].f = f; | |
931 xmb_rt->monitors[i].arg = arg; | |
932 return; | |
933 } | |
934 } | |
935 if (i == MAX_MONITORS) return; | |
936 xmb_rt->monitors[i].type = type; | |
937 xmb_rt->monitors[i].fd = fd; | |
938 xmb_rt->monitors[i].f = f; | |
939 xmb_rt->monitors[i].arg = arg; | |
940 i++; | |
941 xmb_rt->n_monitor=i; | |
942 } | |
943 | |
944 void X_MB_remove_event(void *rt, int type, int fd) | |
945 { | 1046 { |
946 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt; | 1047 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; |
947 int i; | 1048 mb_IO_man_t *io_man = xmb_rt->io_man; |
948 for(i=0;i<xmb_rt->n_monitor;i++) { | 1049 |
949 if (xmb_rt->monitors[i].type == type && xmb_rt->monitors[i].fd == fd) { | 1050 mb_io_man_unreg(io_man, hdl); |
950 xmb_rt->monitors[i].type = 0; | 1051 } |
951 return; | 1052 |
952 } | 1053 static int |
953 } | 1054 _x_supp_flush(mb_rt_t *rt) { |
954 } | 1055 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *) rt; |
955 mb_backend_t backend = { X_MB_new, | 1056 int r; |
956 X_MB_free, | 1057 |
957 X_MB_add_event, | 1058 #ifdef XSHM |
958 X_MB_remove_event, | 1059 XSHM_update(xmb_rt); |
959 X_MB_handle_connection, | 1060 #endif |
960 X_MB_kbevents, | 1061 r = XFlush(xmb_rt->display); |
961 X_MB_rdman, | 1062 return r == 0? ERR: OK; |
962 X_MB_tman, | 1063 } |
963 X_MB_ob_factory, | 1064 |
964 X_MB_img_ldr | 1065 static void |
965 }; | 1066 _x_supp_reg_IO_factory(mb_IO_factory_t *io_factory) { |
1067 _io_factory = io_factory; | |
1068 } | |
1069 | |
1070 static void | |
1071 _x_supp_reg_timer_factory(mb_timer_factory_t *timer_factory) { | |
1072 _timer_factory = timer_factory; | |
1073 } | |
1074 | |
1075 mb_backend_t mb_dfl_backend = { _x_supp_new, | |
1076 _x_supp_new_with_win, | |
1077 | |
1078 _x_supp_free, | |
1079 _x_supp_free_keep_win, | |
1080 _x_supp_add_event, | |
1081 _x_supp_remove_event, | |
1082 _x_supp_event_loop, | |
1083 _x_supp_flush, | |
1084 | |
1085 _x_supp_kbevents, | |
1086 _x_supp_rdman, | |
1087 _x_supp_timer_man, | |
1088 _x_supp_ob_factory, | |
1089 _x_supp_img_ldr, | |
1090 | |
1091 _x_supp_reg_IO_factory, | |
1092 _x_supp_reg_timer_factory, | |
1093 }; | |
1094 | |
1095 #if 0 | |
966 /*! \defgroup x_supp_nodejs_sup Export functions for supporting nodejs plugin. | 1096 /*! \defgroup x_supp_nodejs_sup Export functions for supporting nodejs plugin. |
967 * | 1097 * |
968 * These functions are for internal using. | 1098 * These functions are for internal using. |
969 * @{ | 1099 * @{ |
970 */ | 1100 */ |
971 /*! \brief Exported for nodejs plugin to call handle_x_event. | 1101 /*! \brief Exported for nodejs plugin to call _x_supp_handle_x_event. |
972 */ | 1102 */ |
973 void _X_MB_handle_x_event_for_nodejs(void *rt) { | 1103 void _x_supp_handle_x_event_for_nodejs(mb_rt_t *rt) { |
974 handle_x_event((X_MB_runtime_t *)rt); | 1104 _x_supp_handle_x_event((X_supp_runtime_t *)rt); |
975 } | 1105 } |
976 | 1106 |
977 /*! \brief Get X connect for nodejs plugin. | 1107 /*! \brief Get X connect for nodejs plugin. |
978 */ | 1108 */ |
979 int _X_MB_get_x_conn_for_nodejs(void *rt) { | 1109 int _x_supp_get_x_conn_for_nodejs(mb_rt_t *rt) { |
980 return XConnectionNumber(((X_MB_runtime_t *)rt)->display); | 1110 return XConnectionNumber(((X_supp_runtime_t *)rt)->display); |
981 } | 1111 } |
982 | 1112 |
983 /*! \brief Flush buffer for the X connection of a runtime object. | 1113 /*! \brief Flush buffer for the X connection of a runtime object. |
984 */ | 1114 */ |
985 int _X_MB_flush_x_conn_for_nodejs(void *rt) { | 1115 int _x_supp_flush_x_conn_for_nodejs(mb_rt_t *rt) { |
986 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *)rt; | 1116 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *)rt; |
987 #ifdef XSHM | 1117 #ifdef XSHM |
988 XSHM_update(xmb_rt); | 1118 XSHM_update(xmb_rt); |
989 #endif | 1119 #endif |
990 return XFlush(xmb_rt->display); | 1120 return XFlush(xmb_rt->display); |
991 } | 1121 } |
992 | 1122 |
993 /*! \brief Handle single X event. | 1123 /*! \brief Handle single X event. |
994 */ | 1124 */ |
995 void | 1125 void |
996 _X_MB_handle_single_event(void *rt, void *evt) { | 1126 _x_supp_handle_single_event(mb_rt_t *rt, void *evt) { |
997 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *)rt; | 1127 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *)rt; |
998 | 1128 |
999 handle_single_x_event(xmb_rt, (XEvent *)evt); | 1129 handle_single_x_event(xmb_rt, (XEvent *)evt); |
1000 } | 1130 } |
1001 | 1131 |
1002 /*! \brief Called at end of an iteration of X event loop. | 1132 /*! \brief Called at end of an iteration of X event loop. |
1003 */ | 1133 */ |
1004 void | 1134 void |
1005 _X_MB_no_more_event(void *rt) { | 1135 _x_supp_no_more_event(mb_rt_t *rt) { |
1006 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *)rt; | 1136 X_supp_runtime_t *xmb_rt = (X_supp_runtime_t *)rt; |
1007 | 1137 |
1008 no_more_event(xmb_rt); | 1138 no_more_event(xmb_rt); |
1009 } | 1139 } |
1010 | 1140 |
1011 /* @} */ | 1141 /* @} */ |
1142 #endif /* 0 */ |