Mercurial > MadButterfly
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); }