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);