Mercurial > MadButterfly
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 |