Mercurial > MadButterfly
comparison src/X_supp.c @ 691:05a453e07d01
X_supp.c uses XSHM to avoid overhead of transmission
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Mon, 09 Aug 2010 09:01:19 +0800 |
parents | c9d23f7279a4 |
children | 201cc86720a3 |
comparison
equal
deleted
inserted
replaced
690:86c6ebf1de25 | 691:05a453e07d01 |
---|---|
5 #include <X11/Xutil.h> | 5 #include <X11/Xutil.h> |
6 #include "mb_graph_engine.h" | 6 #include "mb_graph_engine.h" |
7 #include "mb_redraw_man.h" | 7 #include "mb_redraw_man.h" |
8 #include "mb_timer.h" | 8 #include "mb_timer.h" |
9 #include "mb_X_supp.h" | 9 #include "mb_X_supp.h" |
10 | |
11 #define XSHM 1 | |
12 | |
13 #ifdef XSHM | |
14 /* \sa http://www.xfree86.org/current/mit-shm.html */ | |
15 #include <sys/ipc.h> | |
16 #include <sys/shm.h> | |
17 #include <X11/extensions/XShm.h> | |
18 #endif | |
10 | 19 |
11 #define ERR -1 | 20 #define ERR -1 |
12 #define OK 0 | 21 #define OK 0 |
13 | 22 |
14 #define ONLY_MOUSE_MOVE_RAW 1 | 23 #define ONLY_MOUSE_MOVE_RAW 1 |
49 int n_monitor; | 58 int n_monitor; |
50 | 59 |
51 #ifndef ONLY_MOUSE_MOVE_RAW | 60 #ifndef ONLY_MOUSE_MOVE_RAW |
52 /* States */ | 61 /* States */ |
53 shape_t *last; | 62 shape_t *last; |
63 #endif | |
64 | |
65 #ifdef XSHM | |
66 XImage *ximage; | |
67 XShmSegmentInfo shminfo; | |
54 #endif | 68 #endif |
55 }; | 69 }; |
56 | 70 |
57 /*! \defgroup xkb X Keyboard Handling | 71 /*! \defgroup xkb X Keyboard Handling |
58 * | 72 * |
451 *winp = win; | 465 *winp = win; |
452 | 466 |
453 return OK; | 467 return OK; |
454 } | 468 } |
455 | 469 |
470 #ifdef XSHM | |
471 static void | |
472 xshm_destroy(X_MB_runtime_t *xmb_rt) { | |
473 XShmSegmentInfo *shminfo; | |
474 | |
475 shminfo = &xmb_rt->shminfo; | |
476 | |
477 if(xmb_rt->shminfo.shmaddr) { | |
478 XShmDetach(xmb_rt->display, shminfo); | |
479 } | |
480 | |
481 if(xmb_rt->ximage) { | |
482 XDestroyImage(xmb_rt->ximage); | |
483 xmb_rt->ximage = NULL; | |
484 } | |
485 | |
486 if(shminfo->shmaddr) { | |
487 shmdt(shminfo->shmaddr); | |
488 shminfo->shmaddr = NULL; | |
489 } | |
490 | |
491 if(shminfo->shmid) { | |
492 shmctl(shminfo->shmid, IPC_RMID, 0); | |
493 shminfo->shmid = 0; | |
494 } | |
495 } | |
496 | |
497 static void | |
498 xshm_init(X_MB_runtime_t *xmb_rt) { | |
499 Display *display; | |
500 Visual *visual; | |
501 XImage *ximage; | |
502 int screen; | |
503 int depth; | |
504 int support_shm; | |
505 int mem_sz; | |
506 XShmSegmentInfo *shminfo; | |
507 int surf_fmt; | |
508 | |
509 display = xmb_rt->display; | |
510 visual = xmb_rt->visual; | |
511 shminfo = &xmb_rt->shminfo; | |
512 | |
513 support_shm = XShmQueryExtension(display); | |
514 if(!support_shm) | |
515 return; | |
516 | |
517 screen = DefaultScreen(display); | |
518 depth = DefaultDepth(display, screen); | |
519 | |
520 if(depth != 24 && depth != 32) | |
521 return; | |
522 | |
523 xmb_rt->ximage = XShmCreateImage(display, visual, depth, | |
524 ZPixmap, NULL, shminfo, | |
525 xmb_rt->w, xmb_rt->h); | |
526 ximage = xmb_rt->ximage; | |
527 | |
528 mem_sz = ximage->bytes_per_line * ximage->height; | |
529 shminfo->shmid = shmget(IPC_PRIVATE, mem_sz, IPC_CREAT | 0777); | |
530 if(shminfo->shmid == -1) { | |
531 xshm_destroy(xmb_rt); | |
532 return; | |
533 } | |
534 | |
535 shminfo->shmaddr = shmat(shminfo->shmid, 0, 0); | |
536 ximage->data = shminfo->shmaddr; | |
537 | |
538 shminfo->readOnly = 0; | |
539 | |
540 XShmAttach(display, shminfo); | |
541 | |
542 switch(depth) { | |
543 case 24: surf_fmt = CAIRO_FORMAT_RGB24; break; | |
544 case 32: surf_fmt = CAIRO_FORMAT_ARGB32; break; | |
545 } | |
546 | |
547 xmb_rt->backend_surface = | |
548 cairo_image_surface_create_for_data(ximage->data, | |
549 surf_fmt, | |
550 xmb_rt->w, | |
551 xmb_rt->h, | |
552 ximage->bytes_per_line); | |
553 if(xmb_rt->backend_surface == NULL) | |
554 xshm_destroy(xmb_rt); | |
555 } | |
556 #endif /* XSHM */ | |
557 | |
456 /*! \brief Initialize a MadButterfy runtime for Xlib. | 558 /*! \brief Initialize a MadButterfy runtime for Xlib. |
457 * | 559 * |
458 * It setups a runtime environment to run MadButterfly with Xlib. | 560 * It setups a runtime environment to run MadButterfly with Xlib. |
459 * Users should specify width and height of the opening window. | 561 * Users should specify width and height of the opening window. |
460 */ | 562 */ |
461 static int X_MB_init(const char *display_name, | 563 static int X_MB_init(const char *display_name, |
462 int w, int h, X_MB_runtime_t *xmb_rt) { | 564 int w, int h, X_MB_runtime_t *xmb_rt) { |
463 mb_img_ldr_t *img_ldr; | 565 mb_img_ldr_t *img_ldr; |
566 int r; | |
464 | 567 |
465 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); | 568 memset(xmb_rt, 0, sizeof(X_MB_runtime_t)); |
466 | 569 |
467 xmb_rt->w = w; | 570 xmb_rt->w = w; |
468 xmb_rt->h = h; | 571 xmb_rt->h = h; |
469 X_init_connection(display_name, w, h, &xmb_rt->display, | 572 r = X_init_connection(display_name, w, h, &xmb_rt->display, |
470 &xmb_rt->visual, &xmb_rt->win); | 573 &xmb_rt->visual, &xmb_rt->win); |
574 if(r != OK) | |
575 return ERR; | |
576 | |
577 #ifdef XSHM | |
578 xshm_init(xmb_rt); | |
579 #endif | |
471 | 580 |
472 xmb_rt->surface = | 581 xmb_rt->surface = |
473 mbe_image_surface_create(MB_IFMT_ARGB32, w, h); | 582 mbe_image_surface_create(MB_IFMT_ARGB32, w, h); |
474 | 583 |
475 xmb_rt->surface_ptn = | 584 xmb_rt->surface_ptn = |
476 mbe_pattern_create_for_surface(xmb_rt->surface); | 585 mbe_pattern_create_for_surface(xmb_rt->surface); |
477 | 586 |
478 xmb_rt->backend_surface = | 587 if(xmb_rt->backend_surface != NULL) /* xshm_init() may create one */ |
479 mbe_xlib_surface_create(xmb_rt->display, | 588 xmb_rt->backend_surface = |
480 xmb_rt->win, | 589 mbe_xlib_surface_create(xmb_rt->display, |
481 xmb_rt->visual, | 590 xmb_rt->win, |
482 w, h); | 591 xmb_rt->visual, |
592 w, h); | |
483 | 593 |
484 xmb_rt->cr = mbe_create(xmb_rt->surface); | 594 xmb_rt->cr = mbe_create(xmb_rt->surface); |
485 xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface); | 595 xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface); |
486 | 596 |
487 mbe_set_source(xmb_rt->backend_cr, xmb_rt->surface_ptn); | 597 mbe_set_source(xmb_rt->backend_cr, xmb_rt->surface_ptn); |