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 */