comparison src/dfb_supp.c @ 905:e3a5e05f00c1

Roughly DirectFB backend porting.
author Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
date Sun, 03 Oct 2010 18:12:11 +0800
parents f838e5207ec4
children e415c55b4a0d
comparison
equal deleted inserted replaced
904:f838e5207ec4 905:e3a5e05f00c1
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- 1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*-
2 // vim: sw=4:ts=8:sts=4 2 // vim: sw=4:ts=8:sts=4
3 #include <stdio.h> 3 #include <stdio.h>
4 #include <stdlib.h> 4 #include <stdlib.h>
5 #include <string.h> 5 #include <string.h>
6 #include <directfb.h>
7 #include <cairo/cairo.h>
6 #include <cairo-directfb.h> 8 #include <cairo-directfb.h>
7 #include "mb_graph_engine.h" 9 #include "mb_graph_engine.h"
8 #include "mb_redraw_man.h" 10 #include "mb_redraw_man.h"
9 #include "mb_timer.h" 11 #include "mb_timer.h"
10 #include "mb_X_supp.h" 12 #include "mb_dfb_supp.h"
11 #include "config.h" 13 #include "config.h"
12 14
13 #define ERR -1 15 #define ERR -1
14 #define OK 0 16 #define OK 0
15 17
19 * @{ 21 * @{
20 */ 22 */
21 struct _X_kb_info { 23 struct _X_kb_info {
22 int keycode_min, keycode_max; 24 int keycode_min, keycode_max;
23 int ksym_per_code; 25 int ksym_per_code;
24 KeySym *syms;
25 subject_t *kbevents; 26 subject_t *kbevents;
26 ob_factory_t *ob_factory; 27 ob_factory_t *ob_factory;
27 }; 28 };
28 29
29 /* @} */ 30 /* @} */
34 mb_eventcb_t f; 35 mb_eventcb_t f;
35 void *arg; 36 void *arg;
36 } monitor_t; 37 } monitor_t;
37 38
38 struct _X_MB_runtime { 39 struct _X_MB_runtime {
39 Display *display; 40 IDirectFB *dfb;
40 Window win; 41 IDirectFBSurface *primary;
41 Visual *visual;
42 mbe_surface_t *surface, *backend_surface; 42 mbe_surface_t *surface, *backend_surface;
43 mbe_pattern_t *surface_ptn; 43 mbe_pattern_t *surface_ptn;
44 mbe_t *cr, *backend_cr; 44 mbe_t *cr, *backend_cr;
45 redraw_man_t *rdman; 45 redraw_man_t *rdman;
46 mb_tman_t *tman; 46 mb_tman_t *tman;
77 static int keycode2sym(X_kb_info_t *kbinfo, unsigned int keycode) { 77 static int keycode2sym(X_kb_info_t *kbinfo, unsigned int keycode) {
78 int sym_idx; 78 int sym_idx;
79 int sym; 79 int sym;
80 80
81 sym_idx = kbinfo->ksym_per_code * (keycode - kbinfo->keycode_min); 81 sym_idx = kbinfo->ksym_per_code * (keycode - kbinfo->keycode_min);
82 sym = kbinfo->syms[sym_idx]; 82 /* sym = kbinfo->syms[sym_idx];*/
83 return sym; 83 return sym;
84 }
85
86 static int X_kb_init(X_kb_info_t *kbinfo, Display *display,
87 redraw_man_t *rdman) {
88 int n_syms;
89 ob_factory_t *factory;
90 int r;
91
92 r = XDisplayKeycodes(display,
93 &kbinfo->keycode_min,
94 &kbinfo->keycode_max);
95 if(r == 0)
96 return ERR;
97
98 n_syms = kbinfo->keycode_max - kbinfo->keycode_min + 1;
99 kbinfo->syms = XGetKeyboardMapping(display, kbinfo->keycode_min,
100 n_syms,
101 &kbinfo->ksym_per_code);
102 if(kbinfo->syms == NULL)
103 return ERR;
104
105 factory = rdman_get_ob_factory(rdman);
106 kbinfo->kbevents = subject_new(factory, kbinfo, OBJT_KB);
107 if(kbinfo->kbevents == NULL)
108 return ERR;
109 /*! \todo Make sure ob_factory is still need. */
110 kbinfo->ob_factory = factory;
111
112 return OK;
113 } 84 }
114 85
115 static void X_kb_destroy(X_kb_info_t *kbinfo) { 86 static void X_kb_destroy(X_kb_info_t *kbinfo) {
116 subject_free(kbinfo->kbevents); 87 subject_free(kbinfo->kbevents);
117 XFree(kbinfo->syms);
118 }
119
120 /*! \brief Accept X keyboard events from handle_x_event() and dispatch it.
121 */
122 static void X_kb_handle_event(X_kb_info_t *kbinfo, XKeyEvent *xkey) {
123 unsigned int code;
124 int sym;
125 X_kb_event_t event;
126
127 code = xkey->keycode;
128 sym = keycode2sym(kbinfo, code);
129 if(xkey->type == KeyPress)
130 event.event.type = EVT_KB_PRESS;
131 else if(xkey->type == KeyRelease)
132 event.event.type = EVT_KB_RELEASE;
133 event.event.tgt = event.event.cur_tgt = kbinfo->kbevents;
134 event.keycode = code;
135 event.sym = sym;
136
137 subject_notify(kbinfo->kbevents, &event.event);
138 } 88 }
139 89
140 /* @} */ 90 /* @} */
141 91
142 static unsigned int get_button_state(unsigned int state) { 92 static unsigned int get_button_state(unsigned int state) {
143 unsigned int but = 0; 93 return 0;
144
145 if(state & Button1Mask)
146 but |= MOUSE_BUT1;
147 if(state & Button2Mask)
148 but |= MOUSE_BUT2;
149 if(state & Button3Mask)
150 but |= MOUSE_BUT3;
151
152 return but;
153 } 94 }
154 95
155 static unsigned int get_button(unsigned int button) { 96 static unsigned int get_button(unsigned int button) {
156 switch(button) {
157 case Button1:
158 return MOUSE_BUT1;
159 case Button2:
160 return MOUSE_BUT2;
161 case Button3:
162 return MOUSE_BUT3;
163 }
164 return 0; 97 return 0;
165 } 98 }
166 99
167 /*! \brief Notify observers of the shape at specified 100 /*! \brief Notify observers of the shape at specified
168 * position for mouse event. 101 * position for mouse event.
258 rdman_redraw_area(rdman, ex1, ey1, (ex2 - ex1), (ey2 - ey1)); 191 rdman_redraw_area(rdman, ex1, ey1, (ex2 - ex1), (ey2 - ey1));
259 192
260 rt->eflag = 0; 193 rt->eflag = 0;
261 } 194 }
262 195
263 /*! \brief Handle single X event and maintain internal states.
264 *
265 * It keeps internal state in rt to improve performance.
266 */
267 static void
268 handle_single_x_event(X_MB_runtime_t *rt, XEvent *evt) {
269 redraw_man_t *rdman = rt->rdman;
270 XMotionEvent *mevt;
271 XButtonEvent *bevt;
272 XExposeEvent *eevt;
273 XKeyEvent *xkey;
274 int x, y, w, h;
275
276 shape_t *shape;
277
278 unsigned int state, button;
279 int in_stroke;
280
281 if(evt->type != MotionNotify && rt->mflag)
282 handle_motion_event(rt);
283
284 switch(evt->type) {
285 case ButtonPress:
286 bevt = (XButtonEvent *)evt;
287 x = bevt->x;
288 y = bevt->y;
289 state = get_button_state(bevt->state);
290 button = get_button(bevt->button);
291
292 shape = find_shape_at_pos(rdman, x, y,
293 &in_stroke);
294 if(shape)
295 notify_coord_or_shape(rdman, (mb_obj_t *)shape,
296 x, y, EVT_MOUSE_BUT_PRESS,
297 state, button);
298 break;
299
300 case ButtonRelease:
301 bevt = (XButtonEvent *)evt;
302 x = bevt->x;
303 y = bevt->y;
304 state = get_button_state(bevt->state);
305 button = get_button(bevt->button);
306
307 shape = find_shape_at_pos(rdman, x, y,
308 &in_stroke);
309 if(shape)
310 notify_coord_or_shape(rdman, (mb_obj_t *)shape,
311 x, y, EVT_MOUSE_BUT_RELEASE,
312 state, button);
313 break;
314
315 case MotionNotify:
316 mevt = (XMotionEvent *)evt;
317 rt->mx = mevt->x;
318 rt->my = mevt->y;
319 rt->mbut_state = get_button_state(mevt->state);
320 rt->mflag = 1;
321 break;
322
323 case KeyPress:
324 case KeyRelease:
325 xkey = &evt->xkey;
326 X_kb_handle_event(&rt->kbinfo, xkey);
327 break;
328
329 case Expose:
330 eevt = &evt->xexpose;
331 x = eevt->x;
332 y = eevt->y;
333 w = eevt->width;
334 h = eevt->height;
335
336 if(rt->eflag) {
337 if(x < rt->ex1)
338 rt->ex1 = x;
339 if(y < rt->ey1)
340 rt->ey1 = y;
341 if((x + w) > rt->ex2)
342 rt->ex2 = x + w;
343 if((y + h) > rt->ey2)
344 rt->ey2 = y + h;
345 } else {
346 rt->ex1 = x;
347 rt->ey1 = y;
348 rt->ex2 = x + w;
349 rt->ey2 = y + h;
350 rt->eflag = 1;
351 }
352 break;
353 }
354 }
355
356 /*! \brief Call when no more event in an event iteration. 196 /*! \brief Call when no more event in an event iteration.
357 * 197 *
358 * No more event means event queue is emplty. This function will 198 * No more event means event queue is emplty. This function will
359 * perform some actions according current internal state. 199 * perform some actions according current internal state.
360 */ 200 */
364 handle_motion_event(rt); 204 handle_motion_event(rt);
365 if(rt->eflag) 205 if(rt->eflag)
366 handle_expose_event(rt); 206 handle_expose_event(rt);
367 } 207 }
368 208
369 /*! \brief Dispatch all X events in the queue.
370 */
371 static void handle_x_event(X_MB_runtime_t *rt) {
372 Display *display = rt->display;
373 XEvent evt;
374 int r;
375
376 /* XXX: For some unknown reason, it causes a segmentation fault to
377 * called XEventsQueued() after receiving first Expose event
378 * and before redraw for the event.
379 */
380 while(XEventsQueued(display, QueuedAfterReading) > 0) {
381 r = XNextEvent(display, &evt);
382 if(r == -1)
383 break;
384
385 handle_single_x_event(rt, &evt);
386 }
387 no_more_event(rt);
388
389 XFlush(display);
390 }
391
392 /*! \brief Handle connection coming data and timeout of timers. 209 /*! \brief Handle connection coming data and timeout of timers.
393 * 210 *
394 * \param display is a Display returned by XOpenDisplay(). 211 * \param display is a Display returned by XOpenDisplay().
395 * \param rdman is a redraw manager. 212 * \param rdman is a redraw manager.
396 * \param tman is a timer manager. 213 * \param tman is a timer manager.
398 * The display is managed by specified rdman and tman. rdman draws 215 * The display is managed by specified rdman and tman. rdman draws
399 * on the display, and tman trigger actions according timers. 216 * on the display, and tman trigger actions according timers.
400 */ 217 */
401 void X_MB_handle_connection(void *be) { 218 void X_MB_handle_connection(void *be) {
402 X_MB_runtime_t *rt = (X_MB_runtime_t *) be; 219 X_MB_runtime_t *rt = (X_MB_runtime_t *) be;
403 Display *display = rt->display;
404 redraw_man_t *rdman = rt->rdman; 220 redraw_man_t *rdman = rt->rdman;
405 mb_tman_t *tman = rt->tman; 221 mb_tman_t *tman = rt->tman;
406 int fd; 222 int fd = 0;
407 mb_timeval_t now, tmo; 223 mb_timeval_t now, tmo;
408 struct timeval tv; 224 struct timeval tv;
409 fd_set rfds,wfds; 225 fd_set rfds,wfds;
410 int nfds; 226 int nfds;
411 int r, r1,i; 227 int r, r1,i;
412 228
413 handle_x_event(rt); 229 handle_x_event(rt);
414 230
415 fd = XConnectionNumber(display); 231 /* fd = XConnectionNumber(display);*/
416 nfds = fd + 1; 232 nfds = fd + 1;
417 while(1) { 233 while(1) {
418 FD_ZERO(&rfds); 234 FD_ZERO(&rfds);
419 FD_ZERO(&wfds); 235 FD_ZERO(&wfds);
420 FD_SET(fd, &rfds); 236 FD_SET(fd, &rfds);
442 258
443 if(r1 == 0) { 259 if(r1 == 0) {
444 get_now(&now); 260 get_now(&now);
445 mb_tman_handle_timeout(tman, &now); 261 mb_tman_handle_timeout(tman, &now);
446 rdman_redraw_changed(rdman); 262 rdman_redraw_changed(rdman);
447 XFlush(display);
448 } else if(FD_ISSET(fd, &rfds)){ 263 } else if(FD_ISSET(fd, &rfds)){
449 handle_x_event(rt); 264 handle_x_event(rt);
450 } else { 265 } else {
451 for(i=0;i<rt->n_monitor;i++) { 266 for(i=0;i<rt->n_monitor;i++) {
452 if (rt->monitors[i].type == MONITOR_READ) { 267 if (rt->monitors[i].type == MONITOR_READ) {
462 } 277 }
463 278
464 #define ERR -1 279 #define ERR -1
465 #define OK 0 280 #define OK 0
466 281
467 static int X_init_connection(const char *display_name, 282 static int dfb_init_connection(int w, int h,
468 int w, int h, 283 IDirectFB **dfb,
469 Display **displayp, 284 IDirectFBSurface **primary) {
470 Visual **visualp, 285 DFBSurfaceDescription dsc;
471 Window *winp) { 286
472 Display *display; 287 DirectFBInit(NULL, NULL);
473 Window root, win; 288 DirectFBCreate(dfb);
474 Visual *visual; 289 (*dfb)->SetCooperativeLevel(*dfb, DFSCL_FULLSCREEN);
475 int screen; 290 dsc.flags = DSDESC_CAPS;
476 XSetWindowAttributes wattr; 291 dsc.caps = DSCAPS_PRIMARY;
477 int depth; 292 (*dfb)->CreateSurface(*dfb, &dsc, primary);
478 int x, y; 293 (*primary)->GetSize(*primary, &w, &h);
479 int draw_root = 0; 294 (*primary)->SetColor(*primary, 0xff, 0xff, 0xff, 0xff);
480 const char *disp_name; 295 (*primary)->FillRectangle(*primary, 0, 0, w, h);
481 char disp_buf[32];
482 int cp;
483 int r;
484
485 /*
486 * Support drawing on the root window.
487 */
488 disp_name = display_name;
489 if(strstr(display_name, ":root") != NULL) {
490 draw_root = 1;
491 cp = strlen(display_name) - 5;
492 if(cp >= 32)
493 cp = 31;
494 memcpy(disp_buf, display_name, cp);
495 disp_buf[cp] = 0;
496 disp_name = disp_buf;
497 }
498
499 display = XOpenDisplay(disp_name);
500 if(display == NULL)
501 return ERR;
502
503 screen = DefaultScreen(display);
504 root = DefaultRootWindow(display);
505 visual = DefaultVisual(display, screen);
506 depth = DefaultDepth(display, screen);
507 wattr.override_redirect = False;
508 x = 10;
509 y = 10;
510 if(draw_root)
511 win = RootWindowOfScreen(ScreenOfDisplay(display, screen));
512 else {
513 win = XCreateWindow(display, root,
514 x, y,
515 w, h,
516 1, depth, InputOutput, visual,
517 CWOverrideRedirect, &wattr);
518 r = XMapWindow(display, win);
519 if(r == -1) {
520 XCloseDisplay(display);
521 return ERR;
522 }
523 }
524
525 XSelectInput(display, win, PointerMotionMask | ExposureMask |
526 ButtonPressMask | ButtonReleaseMask |
527 KeyPressMask | KeyReleaseMask);
528 XFlush(display);
529
530 *displayp = display;
531 *visualp = visual;
532 *winp = win;
533 296
534 return OK; 297 return OK;
535 } 298 }
536 299
537 /*! \brief Initialize a MadButterfy runtime for Xlib. 300 /*! \brief Initialize a MadButterfy runtime for DirectFB.
538 * 301 *
539 * This one is very like X_MB_init(), except it accepts a 302 * This one is very like X_MB_init(), except it accepts a
540 * X_MB_runtime_t object initialized with a display connected to a X 303 * X_MB_runtime_t object initialized with a display connected to a DirectFB
541 * server and an opened window. 304 * server and an opened window.
542 * 305 *
543 * Following field of the X_MB_runtime_t object should be initialized. 306 * Following field of the X_MB_runtime_t object should be initialized.
544 * - w, h 307 * - w, h
545 * - win 308 * - win
546 * - display 309 * - dfb
547 * - visual 310 * - primary
548 */ 311 */
549 static int 312 static int X_MB_init_with_win_internal(X_MB_runtime_t *xmb_rt) {
550 X_MB_init_with_win_internal(X_MB_runtime_t *xmb_rt) {
551 mb_img_ldr_t *img_ldr; 313 mb_img_ldr_t *img_ldr;
552 int w, h; 314 int w, h;
553 315
554 w = xmb_rt->w; 316 w = xmb_rt->w;
555 h = xmb_rt->h; 317 h = xmb_rt->h;
558 mbe_image_surface_create(MB_IFMT_ARGB32, w, h); 320 mbe_image_surface_create(MB_IFMT_ARGB32, w, h);
559 321
560 xmb_rt->surface_ptn = 322 xmb_rt->surface_ptn =
561 mbe_pattern_create_for_surface(xmb_rt->surface); 323 mbe_pattern_create_for_surface(xmb_rt->surface);
562 324
563 if(xmb_rt->backend_surface == NULL) /* xshm_init() may create one */ 325 if (xmb_rt->backend_surface == NULL)
564 xmb_rt->backend_surface = 326 xmb_rt->backend_surface =
565 mbe_xlib_surface_create(xmb_rt->display, 327 mbe_directfb_surface_create(xmb_rt->dfb, xmb_rt->primary);
566 xmb_rt->win,
567 xmb_rt->visual,
568 w, h);
569 328
570 xmb_rt->cr = mbe_create(xmb_rt->surface); 329 xmb_rt->cr = mbe_create(xmb_rt->surface);
571 xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface); 330 xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface);
572 331
573 mbe_set_source(xmb_rt->backend_cr, xmb_rt->surface_ptn); 332 mbe_set_source(xmb_rt->backend_cr, xmb_rt->surface_ptn);
588 347
589 #ifndef ONLY_MOUSE_MOVE_RAW 348 #ifndef ONLY_MOUSE_MOVE_RAW
590 xmb_rt->last = NULL; 349 xmb_rt->last = NULL;
591 #endif 350 #endif
592 351
593 X_kb_init(&xmb_rt->kbinfo, xmb_rt->display, xmb_rt->rdman); 352 /* X_kb_init(&xmb_rt->kbinfo, xmb_rt->display, xmb_rt->rdman);*/
594 353
595 return OK; 354 return OK;
596 } 355 }
597 356
598 /*! \brief Initialize a MadButterfy runtime for Xlib. 357 /*! \brief Initialize a MadButterfy runtime for DirectFB.
599 * 358 *
600 * It setups a runtime environment to run MadButterfly with Xlib. 359 * It setups a runtime environment to run MadButterfly with DirectFB.
601 * Users should specify width and height of the opening window. 360 * Users should specify width and height of the opening window.
602 */ 361 */
603 static int X_MB_init(X_MB_runtime_t *xmb_rt, const char *display_name, 362 static int X_MB_init(X_MB_runtime_t *xmb_rt, const char *display_name,
604 int w, int h) { 363 int w, int h) {
605 int r; 364 int r;
606 365
607 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); 366 memset(xmb_rt, 0, sizeof(X_MB_runtime_t));
608 367
609 xmb_rt->w = w; 368 xmb_rt->w = w;
610 xmb_rt->h = h; 369 xmb_rt->h = h;
611 r = X_init_connection(display_name, w, h, &xmb_rt->display, 370 r = dfb_init_connection(w, h, &xmb_rt->dfb, &xmb_rt->primary);
612 &xmb_rt->visual, &xmb_rt->win); 371
613 if(r != OK) 372 if(r != OK)
614 return ERR; 373 return ERR;
615 374
616 r = X_MB_init_with_win_internal(xmb_rt); 375 r = X_MB_init_with_win_internal(xmb_rt);
617 376
618 return r; 377 return r;
619 } 378 }
620 379
621 /*! \brief Initialize a MadButterfly runtime for a window of X.
622 *
623 * Runtimes initialized with this function should be destroyed with
624 * X_MB_destroy_keep_win().
625 */
626 static int
627 X_MB_init_with_win(X_MB_runtime_t *xmb_rt,
628 Display *display, Window win) {
629 XWindowAttributes attrs;
630 int r;
631
632 r = XGetWindowAttributes(display, win, &attrs);
633 if(r == 0)
634 return ERR;
635
636 memset(xmb_rt, 0, sizeof(X_MB_runtime_t));
637
638 xmb_rt->display = display;
639 xmb_rt->win = win;
640 xmb_rt->visual = attrs.visual;
641 xmb_rt->w = attrs.width;
642 xmb_rt->h = attrs.height;
643
644 r = X_MB_init_with_win_internal(xmb_rt);
645
646 return r;
647 }
648
649 static void X_MB_destroy(X_MB_runtime_t *xmb_rt) { 380 static void X_MB_destroy(X_MB_runtime_t *xmb_rt) {
650 if(xmb_rt->rdman) { 381 if (xmb_rt->rdman) {
651 redraw_man_destroy(xmb_rt->rdman); 382 redraw_man_destroy(xmb_rt->rdman);
652 free(xmb_rt->rdman); 383 free(xmb_rt->rdman);
653 } 384 }
654 385
655 if(xmb_rt->tman) 386 if (xmb_rt->tman)
656 mb_tman_free(xmb_rt->tman); 387 mb_tman_free(xmb_rt->tman);
657 388
658 if(xmb_rt->img_ldr) 389 if (xmb_rt->img_ldr)
659 MB_IMG_LDR_FREE(xmb_rt->img_ldr); 390 MB_IMG_LDR_FREE(xmb_rt->img_ldr);
660 391
661 if(xmb_rt->cr) 392 if (xmb_rt->cr)
662 mbe_destroy(xmb_rt->cr); 393 mbe_destroy(xmb_rt->cr);
663 if(xmb_rt->backend_cr) 394
395 if (xmb_rt->backend_cr)
664 mbe_destroy(xmb_rt->backend_cr); 396 mbe_destroy(xmb_rt->backend_cr);
665 397
666 if(xmb_rt->surface) 398 if(xmb_rt->surface)
667 mbe_surface_destroy(xmb_rt->surface); 399 mbe_surface_destroy(xmb_rt->surface);
400
668 if(xmb_rt->surface_ptn) 401 if(xmb_rt->surface_ptn)
669 mbe_pattern_destroy(xmb_rt->surface_ptn); 402 mbe_pattern_destroy(xmb_rt->surface_ptn);
403
670 if(xmb_rt->backend_surface) 404 if(xmb_rt->backend_surface)
671 mbe_surface_destroy(xmb_rt->backend_surface); 405 mbe_surface_destroy(xmb_rt->backend_surface);
672 406
673 if(xmb_rt->display) 407 if (xmb_rt->primary)
674 XCloseDisplay(xmb_rt->display); 408 xmb_rt->primary->Release(xmb_rt->primary);
675 409
676 X_kb_destroy(&xmb_rt->kbinfo); 410 if (xmb_rt->dfb)
677 } 411 xmb_rt->dfb->Release(xmb_rt->dfb);
678
679 /*! \brief Destroy a MadButterfly runtime initialized with
680 * X_MB_init_with_win().
681 *
682 * Destroying a runtime with this function prevent the window and
683 * display associated with the runtime being closed.
684 */
685 static void
686 X_MB_destroy_keep_win(X_MB_runtime_t *xmb_rt) {
687 Display *display;
688 Window win;
689
690 display = xmb_rt->display;
691 xmb_rt->display = NULL;
692 win = xmb_rt->win;
693 xmb_rt->win = 0;
694
695 X_MB_destroy(xmb_rt);
696
697 xmb_rt->display = display;
698 xmb_rt->win = win;
699 } 412 }
700 413
701 void *X_MB_new(const char *display_name, int w, int h) { 414 void *X_MB_new(const char *display_name, int w, int h) {
702 X_MB_runtime_t *rt; 415 X_MB_runtime_t *rt;
703 int r; 416 int r;
704 417
705 rt = O_ALLOC(X_MB_runtime_t); 418 rt = O_ALLOC(X_MB_runtime_t);
706 if(rt == NULL) 419
420 if (rt == NULL)
707 return NULL; 421 return NULL;
708 422
709 r = X_MB_init(rt, display_name, w, h); 423 r = X_MB_init(rt, display_name, w, h);
710 if(r != OK) { 424
711 free(rt); 425 if (r != OK) {
712 return NULL;
713 }
714
715 return rt;
716 }
717
718 /*! \brief Create a new runtime for existed window for X.
719 *
720 * The object returned by this function must be free with
721 * X_MB_free_keep_win() to prevent the window from closed.
722 */
723 void *X_MB_new_with_win(Display *display, Window win) {
724 X_MB_runtime_t *rt;
725 int r;
726
727 rt = O_ALLOC(X_MB_runtime_t);
728 if(rt == NULL)
729 return NULL;
730
731 r = X_MB_init_with_win(rt, display, win);
732 if(r != OK) {
733 free(rt); 426 free(rt);
734 return NULL; 427 return NULL;
735 } 428 }
736 429
737 return rt; 430 return rt;
821 xmb_rt->monitors[i].type = 0; 514 xmb_rt->monitors[i].type = 0;
822 return; 515 return;
823 } 516 }
824 } 517 }
825 } 518 }
519
826 mb_backend_t backend = { X_MB_new, 520 mb_backend_t backend = { X_MB_new,
827 X_MB_free, 521 X_MB_free,
828 X_MB_add_event, 522 X_MB_add_event,
829 X_MB_remove_event, 523 X_MB_remove_event,
830 X_MB_handle_connection, 524 X_MB_handle_connection,
832 X_MB_rdman, 526 X_MB_rdman,
833 X_MB_tman, 527 X_MB_tman,
834 X_MB_ob_factory, 528 X_MB_ob_factory,
835 X_MB_img_ldr 529 X_MB_img_ldr
836 }; 530 };
531
837 /*! \defgroup x_supp_nodejs_sup Export functions for supporting nodejs plugin. 532 /*! \defgroup x_supp_nodejs_sup Export functions for supporting nodejs plugin.
838 * 533 *
839 * These functions are for internal using. 534 * These functions are for internal using.
840 * @{ 535 * @{
841 */ 536 */
842 /*! \brief Exported for nodejs plugin to call handle_x_event. 537 /*! \brief Exported for nodejs plugin to call handle_x_event.
843 */ 538 */
844 void _X_MB_handle_x_event_for_nodejs(void *rt) { 539 void _X_MB_handle_x_event_for_nodejs(void *rt) {
845 handle_x_event((X_MB_runtime_t *)rt); 540 handle_x_event((X_MB_runtime_t *)rt);
846 }
847
848 /*! \brief Get X connect for nodejs plugin.
849 */
850 int _X_MB_get_x_conn_for_nodejs(void *rt) {
851 return XConnectionNumber(((X_MB_runtime_t *)rt)->display);
852 }
853
854 /*! \brief Flush buffer for the X connection of a runtime object.
855 */
856 int _X_MB_flush_x_conn_for_nodejs(void *rt) {
857 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *)rt;
858 return XFlush(xmb_rt->display);
859 }
860
861 /*! \brief Handle single X event.
862 */
863 void
864 _X_MB_handle_single_event(void *rt, void *evt) {
865 X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *)rt;
866
867 handle_single_x_event(xmb_rt, (XEvent *)evt);
868 } 541 }
869 542
870 /*! \brief Called at end of an iteration of X event loop. 543 /*! \brief Called at end of an iteration of X event loop.
871 */ 544 */
872 void 545 void