changeset 462:af4b506ad56f

Add backend layer to seperate the backend with the MBAF. Currently, X is the only backend. If we have more than one backend, we need to modify the Makefile to sleect the backend or implement a backend selection mechanism in the runtime.
author wycc@122-116-38-188.HINET-IP.hinet.net
date Wed, 28 Oct 2009 02:39:02 +0800
parents 61a0bceb369d
children aa2b388fba4e
files include/mb_X_supp.h include/mb_redraw_man.h include/mb_shapes.h src/X_supp.c src/mbaf/mbapp.c
diffstat 5 files changed, 148 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/include/mb_X_supp.h	Wed Oct 28 02:35:08 2009 +0800
+++ b/include/mb_X_supp.h	Wed Oct 28 02:39:02 2009 +0800
@@ -23,14 +23,14 @@
 
 typedef struct _X_MB_runtime X_MB_runtime_t;
 
-extern void X_MB_handle_connection(X_MB_runtime_t *rt);
-extern X_MB_runtime_t *X_MB_new(const char *display_name, int w, int h);
-extern void X_MB_free(X_MB_runtime_t *xmb_rt);
+extern void X_MB_handle_connection(void *rt);
+extern void *X_MB_new(const char *display_name, int w, int h);
+extern void X_MB_free(void *xmb_rt);
 
-extern subject_t *X_MB_kbevents(X_MB_runtime_t *xmb_rt);
-extern redraw_man_t *X_MB_rdman(X_MB_runtime_t *xmb_rt);
-extern mb_tman_t *X_MB_tman(X_MB_runtime_t *xmb_rt);
-extern ob_factory_t *X_MB_ob_factory(X_MB_runtime_t *xmb_rt);
-extern mb_img_ldr_t *X_MB_img_ldr(X_MB_runtime_t *xmb_rt);
+extern subject_t *X_MB_kbevents(void *xmb_rt);
+extern redraw_man_t *X_MB_rdman(void *xmb_rt);
+extern mb_tman_t *X_MB_tman(void *xmb_rt);
+extern ob_factory_t *X_MB_ob_factory(void *xmb_rt);
+extern mb_img_ldr_t *X_MB_img_ldr(void *xmb_rt);
 
 #endif
--- a/include/mb_redraw_man.h	Wed Oct 28 02:35:08 2009 +0800
+++ b/include/mb_redraw_man.h	Wed Oct 28 02:39:02 2009 +0800
@@ -6,6 +6,7 @@
 #include "mb_types.h"
 #include "mb_observer.h"
 #include "mb_img_ldr.h"
+#include "mb_timer.h"
 
 typedef struct _redraw_man redraw_man_t;
 
@@ -225,4 +226,35 @@
 extern paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman,
 					 const char *img_id);
 
+typedef void (*mb_eventcb_t )(int fd,void *arg);
+#define MONITOR_READ   1
+#define MONITOR_WRITE  2
+
+/*! \brief The backend engine mb_backend_t is used to define the interface to realize the MB.
+ *
+ * A backend is used to receive events from the system. The MB does not define the backend by itself.
+ * Instead, it define an interface which allow the lower layer to implement the event system. Each
+ * backend need to provides the following events.
+ *
+ * - keyboard event
+ * - timer event
+ * - image loader(?)
+ * - render manager(?)
+ */
+typedef struct {
+    
+    void *(*init)(char *display,int w,int h);
+    void (*free)(void *be);
+    void (*add_event)(void *be,int type, int fd, mb_eventcb_t f,void *arg);
+    void (*remove_event)(void *be,int type, int fd);
+    void (*loop)(void *be);
+    subject_t *(*kbevents)(void *be);
+    redraw_man_t *(*rdman)(void *be);
+    mb_tman_t *(*tman)(void *be);
+    ob_factory_t *(*factory)(void *be);
+    mb_img_ldr_t *(*loader)(void *be);
+} mb_backend_t;
+
+extern mb_backend_t backend;
+
 #endif /* __REDRAW_MAN_H_ */
--- a/include/mb_shapes.h	Wed Oct 28 02:35:08 2009 +0800
+++ b/include/mb_shapes.h	Wed Oct 28 02:39:02 2009 +0800
@@ -176,6 +176,9 @@
 {
     style->property = 0;
 }
+/*! \brief Get the dimension of the text
+ */
+extern void sh_text_get_size(shape_t *sh, int *w, int *h);
 extern void mb_textstyle_set_font(mb_textstyle_t *style, char *font);
 static inline char *mb_textstyle_get_font(mb_textstyle_t *style)
 {
@@ -230,7 +233,6 @@
 extern void mb_text_set_text(mb_text_t *text, char *string,int begin,int end);
 extern void mb_text_get_text(mb_text_t *text, int begin,int end, char *string);
 
-
 /* @} */
 
 /*! \defgroup shape_rect Shape of Rectangle
--- a/src/X_supp.c	Wed Oct 28 02:35:08 2009 +0800
+++ b/src/X_supp.c	Wed Oct 28 02:39:02 2009 +0800
@@ -25,7 +25,13 @@
 };
 
 /* @} */
-
+#define MAX_MONITORS 200
+typedef struct {
+    int type;
+    int fd;
+    mb_eventcb_t f;
+    void *arg;
+}  monitor_t;
 struct _X_MB_runtime {
     Display *display;
     Window win;
@@ -38,6 +44,8 @@
     int w, h;
 
     X_kb_info_t kbinfo;
+    monitor_t monitors[MAX_MONITORS];
+    int n_monitor;
 
 #ifndef ONLY_MOUSE_MOVE_RAW
     /* States */
@@ -327,16 +335,17 @@
  * The display is managed by specified rdman and tman.  rdman draws
  * on the display, and tman trigger actions according timers.
  */
-void X_MB_handle_connection(X_MB_runtime_t *rt) {
+void X_MB_handle_connection(void *be) {
+    X_MB_runtime_t *rt = (X_MB_runtime_t *) be;
     Display *display = rt->display;
     redraw_man_t *rdman = rt->rdman;
     mb_tman_t *tman = rt->tman;
     int fd;
     mb_timeval_t now, tmo;
     struct timeval tv;
-    fd_set rfds;
+    fd_set rfds,wfds;
     int nfds;
-    int r, r1;
+    int r, r1,i;
 
     handle_x_event(rt);
 
@@ -344,7 +353,14 @@
     nfds = fd + 1;
     while(1) {
 	FD_ZERO(&rfds);
+	FD_ZERO(&wfds);
 	FD_SET(fd, &rfds);
+        for(i=0;i<rt->n_monitor;i++) {
+	    if (rt->monitors[i].type == MONITOR_READ)
+		FD_SET(rt->monitors[i].fd, &rfds);
+	    else if (rt->monitors[i].type == MONITOR_WRITE)
+		FD_SET(rt->monitors[i].fd, &wfds);
+        }
 	
 	get_now(&now);
 	r = mb_tman_next_timeout(tman, &now, &tmo);
@@ -368,6 +384,15 @@
 	    XFlush(display);
 	} else if(FD_ISSET(fd, &rfds)){
 	    handle_x_event(rt);
+	} else {
+            for(i=0;i<rt->n_monitor;i++) {
+	        if (rt->monitors[i].type == MONITOR_READ)
+		    if (FD_ISSET(rt->monitors[i].fd, &rfds))
+		    	rt->monitors[i].f(rt->monitors[i].fd,rt->monitors[i].arg);
+	        else if (rt->monitors[i].type == MONITOR_WRITE)
+		    if (FD_ISSET(rt->monitors[i].fd, &wfds))
+		    	rt->monitors[i].f(rt->monitors[i].fd,rt->monitors[i].arg);
+            }
 	}
     }
 }
@@ -467,6 +492,7 @@
     img_ldr = simple_mb_img_ldr_new("");
     xmb_rt->img_ldr = img_ldr;
     rdman_set_img_ldr(xmb_rt->rdman, img_ldr);
+    memset(xmb_rt->monitors,0,sizeof(xmb_rt->monitors));
     
 #ifndef ONLY_MOUSE_MOVE_RAW
     xmb_rt->last = NULL;
@@ -505,7 +531,7 @@
     X_kb_destroy(&xmb_rt->kbinfo);
 }
 
-X_MB_runtime_t *X_MB_new(const char *display_name, int w, int h) {
+void *X_MB_new(const char *display_name, int w, int h) {
     X_MB_runtime_t *rt;
     int r;
 
@@ -520,34 +546,93 @@
     return rt;
 }
 
-void X_MB_free(X_MB_runtime_t *rt) {
-    X_MB_destroy(rt);
+void X_MB_free(void *rt) {
+    X_MB_destroy((X_MB_runtime_t *) rt);
     free(rt);
 }
 
-subject_t *X_MB_kbevents(X_MB_runtime_t *xmb_rt) {
+subject_t *X_MB_kbevents(void *rt) {
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
     return xmb_rt->kbinfo.kbevents;
 }
 
-redraw_man_t *X_MB_rdman(X_MB_runtime_t *xmb_rt) {
+redraw_man_t *X_MB_rdman(void *rt) {
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
     return xmb_rt->rdman;
 }
 
-mb_tman_t *X_MB_tman(X_MB_runtime_t *xmb_rt) {
+mb_tman_t *X_MB_tman(void *rt) {
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
     return xmb_rt->tman;
 }
 
-ob_factory_t *X_MB_ob_factory(X_MB_runtime_t *xmb_rt) {
+ob_factory_t *X_MB_ob_factory(void *rt) {
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
     ob_factory_t *factory;
 
     factory = rdman_get_ob_factory(xmb_rt->rdman);
     return factory;
 }
 
-mb_img_ldr_t *X_MB_img_ldr(X_MB_runtime_t *xmb_rt) {
+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;
 
     img_ldr = xmb_rt->img_ldr;
 
     return img_ldr;
 }
+
+void X_add_event(void *rt, int type, int fd, mb_eventcb_t f,void *arg)
+{
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
+    int i;
+
+    for(i=0;i<xmb_rt->n_monitor;i++) {
+        if (xmb_rt->monitors[i].type == type && xmb_rt->monitors[i].fd == fd) {
+	    xmb_rt->monitors[i].f = f;
+	    xmb_rt->monitors[i].arg = arg;
+	    return;
+	}
+    }
+    for(i=0;i<xmb_rt->n_monitor;i++) {
+        if (xmb_rt->monitors[i].type == 0) {
+	    xmb_rt->monitors[i].type = type;
+	    xmb_rt->monitors[i].fd = fd;
+	    xmb_rt->monitors[i].f = f;
+	    xmb_rt->monitors[i].arg = arg;
+	    return;
+	}
+    }
+    if (i == MAX_MONITORS) return;
+    xmb_rt->monitors[i].type = type;
+    xmb_rt->monitors[i].fd = fd;
+    xmb_rt->monitors[i].f = f;
+    xmb_rt->monitors[i].arg = arg;
+    i++;
+    xmb_rt->n_monitor=i;
+}
+
+void X_remove_event(void *rt, int type, int fd)
+{
+    X_MB_runtime_t *xmb_rt = (X_MB_runtime_t *) rt;
+    int i;
+    for(i=0;i<xmb_rt->n_monitor;i++) {
+        if (xmb_rt->monitors[i].type == type && xmb_rt->monitors[i].fd == fd) {
+	    xmb_rt->monitors[i].type = 0;
+	    return;
+	}
+    }
+}
+mb_backend_t backend = { X_MB_new,
+			 X_MB_free,
+			 X_add_event,
+			 X_remove_event,
+			 X_MB_handle_connection,
+			 X_MB_kbevents,
+			 X_MB_rdman,
+			 X_MB_tman,
+			 X_MB_ob_factory,
+			 X_MB_img_ldr
+		};
+			 
--- a/src/mbaf/mbapp.c	Wed Oct 28 02:35:08 2009 +0800
+++ b/src/mbaf/mbapp.c	Wed Oct 28 02:39:02 2009 +0800
@@ -4,21 +4,21 @@
 mbaf_t *mbaf_init(const char *module, const char *module_dir)
 {
     mbaf_t *app = (mbaf_t *) malloc(sizeof(mbaf_t));
-    X_MB_runtime_t *rt;
+    void *rt;
 
-    rt = X_MB_new(":0.0", 800, 600);
+    rt = backend.init(":0.0", 800, 600);
     if(rt == NULL)
 	return NULL;
 
     sprite_set_search_path(module_dir);
 
     app->rt = rt;
-    app->rdman =  X_MB_rdman(rt);
-    app->kbevents = X_MB_kbevents(rt);
+    app->rdman =  backend.rdman(rt);
+    app->kbevents = backend.kbevents(rt);
     
     app->rootsprite= sprite_load(module,app->rdman, app->rdman->root_coord);
     if(app->rootsprite == NULL) {
-	X_MB_free(rt);
+	backend.free(rt);
 	free(app);
 	return NULL;
     }
@@ -36,7 +36,7 @@
 
 mb_tman_t *mbaf_get_timer(mbaf_t *app)
 {
-    return X_MB_tman(app->rt);
+    return backend.tman(app->rt);
 }
 
 void mbaf_loop(mbaf_t *app)
@@ -45,11 +45,11 @@
      * Start handle connections, includes one to X server.
      * User start to interact with the application.
      */
-    X_MB_handle_connection(app->rt);
+    backend.loop(app->rt);
 
     /*
      * Clean
      */
-    X_MB_free(app->rt);
+    backend.free(app->rt);
     free(app);
 }