changeset 697:6ddc8b42188f

Merge from HEAD
author wycc
date Mon, 09 Aug 2010 16:43:27 +0800
parents f46a0771fd30 (current diff) 7e64e0f70cb6 (diff)
children 32e1b8005403
files nodejs/testcase.js
diffstat 6 files changed, 174 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Mon Aug 09 16:41:54 2010 +0800
+++ b/configure.ac	Mon Aug 09 16:43:27 2010 +0800
@@ -81,6 +81,14 @@
             (*) AC_MSG_ERROR([bad value ${enableval} for --enable-skia]) ;;
         esac],[skia=false])
 
+AC_ARG_ENABLE([xshm],
+	[AS_HELP_STRING([--disable-xshm],[Turn off XSHM supporting])],
+	[case "${enableval}" in
+	    (yes) xshm=true ;;
+	    (no) xshm=false ;;
+	    (*) AC_MSG_ERROR([bad value ${enableval} for --disable-xshm]) ;;
+	esac], [xshm=true])
+
 AM_CONDITIONAL([SKIA_GRAPH_ENGINE], [test x$skia = xtrue])
 AM_CONDITIONAL([CAIRO_GRAPH_ENGINE], [test x$skia != xtrue])
 
@@ -129,6 +137,12 @@
     AC_DEFINE([DFB_BACKEND])
 [fi]
 
+AM_CONDITIONAL([XSHM], [test x"${xshm}" = xtrue -a x"${cairo}" = xtrue -a x$backend = x'X'])
+
+[if [ x"${xshm}" = xtrue -a x"${cairo}" = xtrue -a x$backend = x'X' ]; then]
+    AC_DEFINE([XSHM])
+[fi]
+
 # Checks for libraries.
 
 [if [ x"${cairo}" = xtrue ]; then]
@@ -162,5 +176,6 @@
 AH_TEMPLATE([CAIRO_GRAPH_ENGINE], [Enable Cairo Graphic Engine])
 AH_TEMPLATE([X_BACKEND], [Enable X backend])
 AH_TEMPLATE([DFB_BACKEND], [Enable DirectFB backend])
+AH_TEMPLATE([XSHM], [Enable XSHM])
 
 AC_OUTPUT
--- a/nodejs/Makefile.am	Mon Aug 09 16:41:54 2010 +0800
+++ b/nodejs/Makefile.am	Mon Aug 09 16:43:27 2010 +0800
@@ -7,6 +7,10 @@
 	@pangocairo_CFLAGS@ $(CFLAGS)
 mbfly_node_LDFLAGS = -L$(abs_top_builddir)/src/.libs @pangocairo_LIBS@
 
+if XSHM
+mbfly_node_LDFLAGS += -lXext
+endif
+
 all: mbfly.node
 clean: clean-mbfly-node
 
--- a/nodejs/mbfly_njs.m4	Mon Aug 09 16:41:54 2010 +0800
+++ b/nodejs/mbfly_njs.m4	Mon Aug 09 16:43:27 2010 +0800
@@ -8,6 +8,7 @@
 		 (([MOD], [xnjsmb_mb_rt_objs_mod]))),
         METHOD([redraw_changed], [xnjsmb_redraw_changed], (), 0, []),
 	METHOD([redraw_all], [xnjsmb_redraw_all], (), 0, []),
+	METHOD([flush], [X_njs_MB_flush], (), 0, []),
 	METHOD([path_new], [xnjsmb_path_new], (STR(txt)), 1,
 	       [OBJ([path], [shape_t])], (([MOD], [xnjsmb_mb_rt_objs_mod]))),
 	METHOD([stext_new], [xnjsmb_stext_new],
--- a/nodejs/testcase.js	Mon Aug 09 16:41:54 2010 +0800
+++ b/nodejs/testcase.js	Mon Aug 09 16:43:27 2010 +0800
@@ -57,6 +57,7 @@
 	var deg = (i++) * 0.1;
 	coord[2] = (i % 20) * 10;
 	mb_rt.redraw_changed();
+	mb_rt.flush();
     }, 20);
 setTimeout(function() { sys.puts("timeout"); }, 1000);
 
--- a/src/Makefile.am	Mon Aug 09 16:41:54 2010 +0800
+++ b/src/Makefile.am	Mon Aug 09 16:43:27 2010 +0800
@@ -36,11 +36,17 @@
 libmbfly_la_SOURCES += X_supp.c
 endif
 
+libmbfly_la_LDFLAGS =
+
 if CAIRO_GRAPH_ENGINE
 libmbfly_la_SOURCES += graph_engine_cairo.c
 
 libmbfly_la_CPPFLAGS = @cairo_CFLAGS@ @pangocairo_CFLAGS@
-libmbfly_la_LDFLAGS = @cairo_LIBS@ @pangocairo_LIBS@
+libmbfly_la_LDFLAGS += @cairo_LIBS@ @pangocairo_LIBS@
+endif
+
+if XSHM
+libmbfly_la_LDFLAGS += -lXext
 endif
 
 if SKIA_GRAPH_ENGINE
--- a/src/X_supp.c	Mon Aug 09 16:41:54 2010 +0800
+++ b/src/X_supp.c	Mon Aug 09 16:43:27 2010 +0800
@@ -3,10 +3,19 @@
 #include <string.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <cairo-xlib.h>
 #include "mb_graph_engine.h"
 #include "mb_redraw_man.h"
 #include "mb_timer.h"
 #include "mb_X_supp.h"
+#include "config.h"
+
+#ifdef XSHM
+/* \sa http://www.xfree86.org/current/mit-shm.html */
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#endif
 
 #define ERR -1
 #define OK 0
@@ -52,8 +61,30 @@
     /* States */
     shape_t *last;
 #endif
+
+#ifdef XSHM
+    XImage *ximage;
+    XShmSegmentInfo shminfo;
+#endif
 };
 
+#ifdef XSHM
+static void
+XSHM_update(X_MB_runtime_t *xmb_rt) {
+    GC gc;
+    
+    gc = DefaultGC(xmb_rt->display, DefaultScreen(xmb_rt->display));
+    if(xmb_rt->ximage) {	/* support XSHM */
+	XShmPutImage(xmb_rt->display,
+		     xmb_rt->win,
+		     gc,
+		     xmb_rt->ximage,
+		     0, 0, 0, 0,
+		     xmb_rt->w, xmb_rt->h, 0);
+    }
+}
+#endif
+
 /*! \defgroup xkb X Keyboard Handling
  *
  * Accept keyboard events from X server and delivery it to
@@ -328,6 +359,9 @@
 	rdman_redraw_area(rdman, ex1, ey1, (ex2 - ex1), (ey2 - ey1));
 	eflag = 0;
     }
+#ifdef XSHM
+    XSHM_update(rt);
+#endif
     XFlush(display);
 }
 
@@ -386,6 +420,9 @@
 	    get_now(&now);
 	    mb_tman_handle_timeout(tman, &now);
 	    rdman_redraw_changed(rdman);
+#ifdef XSHM
+	    XSHM_update(rt);
+#endif
 	    XFlush(display);
 	} else if(FD_ISSET(fd, &rfds)){
 	    handle_x_event(rt);
@@ -453,6 +490,94 @@
     return OK;
 }
 
+#ifdef XSHM
+static void
+xshm_destroy(X_MB_runtime_t *xmb_rt) {
+    XShmSegmentInfo *shminfo;
+
+    shminfo = &xmb_rt->shminfo;
+    
+    if(xmb_rt->shminfo.shmaddr) {
+	XShmDetach(xmb_rt->display, shminfo);
+    }
+    
+    if(xmb_rt->ximage) {
+	XDestroyImage(xmb_rt->ximage);
+	xmb_rt->ximage = NULL;
+    }
+    
+    if(shminfo->shmaddr) {
+	shmdt(shminfo->shmaddr);
+	shminfo->shmaddr = NULL;
+    }
+    
+    if(shminfo->shmid) {
+	shmctl(shminfo->shmid, IPC_RMID, 0);
+	shminfo->shmid = 0;
+    }
+}
+
+static void
+xshm_init(X_MB_runtime_t *xmb_rt) {
+    Display *display;
+    Visual *visual;
+    XImage *ximage;
+    int screen;
+    int depth;
+    int support_shm;
+    int mem_sz;
+    XShmSegmentInfo *shminfo;
+    int surf_fmt;
+
+    display = xmb_rt->display;
+    visual = xmb_rt->visual;
+    shminfo = &xmb_rt->shminfo;
+    
+    support_shm = XShmQueryExtension(display);
+    if(!support_shm)
+	return;
+    
+    screen = DefaultScreen(display);
+    depth = DefaultDepth(display, screen);
+    
+    if(depth != 24 && depth != 32)
+	return;
+    
+    xmb_rt->ximage = XShmCreateImage(display, visual, depth,
+				     ZPixmap, NULL, shminfo,
+				     xmb_rt->w, xmb_rt->h);
+    ximage = xmb_rt->ximage;
+    
+    mem_sz = ximage->bytes_per_line * ximage->height;
+    shminfo->shmid = shmget(IPC_PRIVATE, mem_sz, IPC_CREAT | 0777);
+    if(shminfo->shmid == -1) {
+	xshm_destroy(xmb_rt);
+	return;
+    }
+
+    shminfo->shmaddr = shmat(shminfo->shmid, 0, 0);
+    ximage->data = shminfo->shmaddr;
+    
+    shminfo->readOnly = 0;
+
+    XShmAttach(display, shminfo);
+
+    switch(depth) {
+    case 24: surf_fmt = CAIRO_FORMAT_RGB24; break;
+    case 32: surf_fmt = CAIRO_FORMAT_ARGB32; break;
+    }
+
+    xmb_rt->backend_surface =
+	cairo_image_surface_create_for_data(ximage->data,
+					    surf_fmt,
+					    xmb_rt->w,
+					    xmb_rt->h,
+					    ximage->bytes_per_line);
+    if(xmb_rt->backend_surface == NULL)
+	xshm_destroy(xmb_rt);
+}
+#endif /* XSHM */
+
 /*! \brief Initialize a MadButterfy runtime for Xlib.
  *
  * It setups a runtime environment to run MadButterfly with Xlib.
@@ -461,13 +586,20 @@
 static int X_MB_init(const char *display_name,
 	      int w, int h, X_MB_runtime_t *xmb_rt) {
     mb_img_ldr_t *img_ldr;
+    int r;
     
     memset(xmb_rt, 0, sizeof(X_MB_runtime_t));
 
     xmb_rt->w = w;
     xmb_rt->h = h;
-    X_init_connection(display_name, w, h, &xmb_rt->display,
-		      &xmb_rt->visual, &xmb_rt->win);
+    r = X_init_connection(display_name, w, h, &xmb_rt->display,
+			  &xmb_rt->visual, &xmb_rt->win);
+    if(r != OK)
+	return ERR;
+
+#ifdef XSHM
+    xshm_init(xmb_rt);
+#endif
 
     xmb_rt->surface =
 	mbe_image_surface_create(MB_IFMT_ARGB32, w, h);
@@ -475,11 +607,12 @@
     xmb_rt->surface_ptn =
 	mbe_pattern_create_for_surface(xmb_rt->surface);
     
-    xmb_rt->backend_surface =
-	mbe_xlib_surface_create(xmb_rt->display,
-				  xmb_rt->win,
-				  xmb_rt->visual,
-				  w, h);
+    if(xmb_rt->backend_surface == NULL) /* xshm_init() may create one */
+	xmb_rt->backend_surface =
+	    mbe_xlib_surface_create(xmb_rt->display,
+				    xmb_rt->win,
+				    xmb_rt->visual,
+				    w, h);
 
     xmb_rt->cr = mbe_create(xmb_rt->surface);
     xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface);
@@ -588,7 +721,7 @@
 
 mb_img_ldr_t *X_MB_img_ldr(void *rt) {
     X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
-    X_MB_runtime_t *img_ldr;
+    mb_img_ldr_t *img_ldr;
 
     img_ldr = xmb_rt->img_ldr;
 
@@ -667,7 +800,11 @@
 /*! \brief Flush buffer for the X connection of a runtime object.
  */
 int _X_MB_flush_x_conn_for_nodejs(void *rt) {
-    return XFlush(((X_MB_runtime_t *)rt)->display);
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *)rt;
+#ifdef XSHM
+    XSHM_update(xmb_rt);
+#endif
+    return XFlush(xmb_rt->display);
 }
 
 /* @} */