Mercurial > MadButterfly
changeset 1124:b5ff72dbc910
merge
author | wycc |
---|---|
date | Thu, 09 Dec 2010 07:48:46 +0800 |
parents | aad659b6b625 (current diff) 17cbb862a8c6 (diff) |
children | 5b2394f67ad0 |
files | |
diffstat | 23 files changed, 1022 insertions(+), 116 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac Thu Dec 09 07:48:08 2010 +0800 +++ b/configure.ac Thu Dec 09 07:48:46 2010 +0800 @@ -83,6 +83,7 @@ [case "${withval}" in ('X') backend='X'; default_graphic_engine="cairo" ;; ('dfb') backend='dfb'; default_graphic_engine="dfb" ;; + ('console') backend='console'; default_graphic_engine="openvg" ;; ('no') backend='none'; default_graphic_engine="cairo" ;; (*) AC_MSG_ERROR([bad value ${withval} for --with-backend]) ;; esac],[backend='X'; default_graphic_engine="cairo"]) @@ -105,7 +106,7 @@ [case "${withval}" in ('cairo') image_loader="cairo" ;; ('imlib2') image_loader="imlib2" ;; - ('no') image_loader="none" ;; + ('dummy') image_loader="dummy" ;; (*) AC_MSG_ERROR([bad value ${withval} for --with-image-loader]) ;; esac], [image_loader="cairo"]) @@ -123,8 +124,9 @@ # Validate options [case "${backend}-${graphic_engine}-${image_loader}" in - X-cairo-*|X-openvg-imlib2) ;; + X-cairo-*|X-openvg-imlib2|X-openvg-dummy) ;; dfb-cairo-*) ;; + console-openvg-imlib2|console-openvg-dummy) ;; none-*-*) ;; *)] AC_MSG_ERROR([The combination of --with-backend=${backend}, --with-graphic-engine=${graphic_engine} and --with-image-loader=${image_loader} is invalid]) [;; esac] @@ -185,6 +187,13 @@ AC_DEFINE([DFB_BACKEND]) [fi] +AM_CONDITIONAL([CONSOLE_BACKEND], + [test x$backend = x'console' -a x"${graphic_engine}" = x"openvg"]) + +[if [ x"${backend}" = x'console' -a x"${graphic_engine}" = x"openvg" ]; then] + AC_DEFINE([CONSOLE_BACKEND]) +[fi] + AM_CONDITIONAL([CAIRO_IMG_LOADER], [test x"${image_loader}" = x"cairo"]) @@ -202,6 +211,13 @@ AC_DEFINE([IMLIB2_IMG_LOADER]) [fi] +AM_CONDITIONAL([DUMMY_IMG_LOADER], + [test x"${image_loader}" = x"dummy"]) + +[if [ x"${image_loader}" = x"dummy" ]; then] + AC_DEFINE([DUMMY_IMG_LOADER]) +[fi] + AM_CONDITIONAL([XSHM], [test x"${xshm}" = xtrue -a x"${graphic_engine}" = x"cairo" -a x$backend = x'X']) @@ -252,8 +268,10 @@ AH_TEMPLATE([DFB_GRAPH_ENGINE], [Enable DirectFB Graphic Engine]) AH_TEMPLATE([CAIRO_IMG_LOADER], [Enable Cairo Image Loader]) AH_TEMPLATE([IMLIB2_IMG_LOADER], [Enable Imlib2 Image Loader]) +AH_TEMPLATE([DUMMY_IMG_LOADER], [Enable Dummy Image Loader]) AH_TEMPLATE([X_BACKEND], [Enable X backend]) AH_TEMPLATE([DFB_BACKEND], [Enable DirectFB backend]) +AH_TEMPLATE([CONSOLE_BACKEND], [Enable console backend]) AH_TEMPLATE([XSHM], [Enable XSHM]) AC_OUTPUT
--- a/examples/calculator/main.c Thu Dec 09 07:48:08 2010 +0800 +++ b/examples/calculator/main.c Thu Dec 09 07:48:46 2010 +0800 @@ -179,7 +179,11 @@ calculator_scr_t *calculator_scr; calc_data_t calc_data; +#ifdef CONSOLE_BACKEND + rt = mb_runtime_new(NULL, 300, 400); +#else rt = mb_runtime_new(":0.0", 300, 400); +#endif rdman = mb_runtime_rdman(rt); calculator_scr = calculator_scr_new(rdman, rdman->root_coord); @@ -187,6 +191,8 @@ calc_data.rt = rt; calc_data.code = calculator_scr; setup_observers(&calc_data); + + mb_runtime_flush(rt); mb_runtime_event_loop(rt);
--- a/examples/tank/enemy.c Thu Dec 09 07:48:08 2010 +0800 +++ b/examples/tank/enemy.c Thu Dec 09 07:48:46 2010 +0800 @@ -11,6 +11,38 @@ }; typedef struct _enemy enemy_t; +/*! \brief Pheromone Map trace the freq. the enemy tanks moving on an area. + * + * Every time a tank move to an area, it leaves 100 units of pheromone + * on the area. And 9 of 10 pheromone are removed from the area for + * every time slice (1/3 second). The max value of phereomone in an + * area is 991. + */ +static int pheromone_map[MAP_H][MAP_W]; + +static void +init_pheromone_map(void) { + int i, j; + + for(i = 0; i < MAP_H; i++) + for(j = 0; j < MAP_W; j++) + pheromone_map[i][j] = 0; +} + +static void +remove_pheromone(void) { + int i, j; + + for(i = 0; i < MAP_H; i++) + for(j = 0; j < MAP_W; j++) + pheromone_map[i][j] = pheromone_map[i][j] * 9 / 10; +} + +static void +leave_pheromone(int x, int y) { + pheromone_map[y][x] += 100; +} + /* \brief Fire and move to the target tank if they are in a row or column. */ static int @@ -75,6 +107,8 @@ if(me->direction == target_dir && me->bullet == NULL) tank_fire_bullet(tank_rt, me); tank_move(me, target_dir, tank_rt); + + leave_pheromone(me->map_x, me->map_y); return 1; } @@ -95,8 +129,11 @@ int x, y; int i, tank_i; int dir, chk_dir; + int interest_areas[4]; + int all_interest; + int min_interest; int possibles; - int which_dir; + int interest_dir; me = enemy->tank; tanks = tank_rt->tanks; @@ -106,15 +143,18 @@ x = me->map_x + shift_xy[i][0]; y = me->map_y + shift_xy[i][1]; + interest_areas[i] = 0; + /* Check obstacles */ if(x == -1 || y == -1 || x >= MAP_W || y >= MAP_H) { /* Out of range */ status[i] = SOMETHING; continue; } - if(map[y][x] == MUD) + if(map[y][x] == MUD) { status[i] = NOTHING; - else + interest_areas[i] = 992 - pheromone_map[y][x]; + } else status[i] = SOMETHING; /* Check tanks */ @@ -134,6 +174,8 @@ } if(i == 4) { /* Status is not changed */ tank_move(me, me->direction, tank_rt); + + leave_pheromone(me->map_x, me->map_y); return; } @@ -155,12 +197,22 @@ break; } + /* Compute itnerest for nearby areas */ possibles = 0; + all_interest = 0; + min_interest = 992; for(i = 0; i < 3; i++) { chk_dir = (dir + 3 + i) % 4; - if(status[chk_dir] == NOTHING) + if(status[chk_dir] == NOTHING) { possibles++; + all_interest += interest_areas[chk_dir]; + if(min_interest > interest_areas[chk_dir]) + min_interest = interest_areas[chk_dir]; + } } + all_interest -= (min_interest * possibles) + possibles; + for(i = 0; i < 4; i++) + interest_areas[i] = interest_areas[i] - min_interest + 1; if(possibles == 0) { /* Only can move backward */ switch(me->direction) { @@ -177,15 +229,17 @@ tank_move(me, TD_RIGHT, tank_rt); break; } + + leave_pheromone(me->map_x, me->map_y); return; } - which_dir = (rand() % possibles) + 1; + interest_dir = (rand() % all_interest) + 1; for(i = 0; i < 3; i++) { chk_dir = (dir + 3 + i) % 4; if(status[chk_dir] == NOTHING) { - which_dir--; - if(which_dir == 0) + interest_dir -= interest_areas[chk_dir]; + if(interest_dir <= 0) break; } } @@ -203,6 +257,8 @@ tank_move(me, TD_UP, tank_rt); break; } + + leave_pheromone(me->map_x, me->map_y); } static void @@ -229,17 +285,18 @@ static enemy_t *enemies = NULL; static mb_timer_man_t *timer_man; +static void enemy_tick(int hdl, const mb_timeval_t *tmo, + const mb_timeval_t *now, void *data); + /*! \brief Drive every enemy tanks. */ static void -enemy_tank_driver(int hdl, const mb_timeval_t *tmo, - const mb_timeval_t *now, void *data) { - tank_rt_t *tank_rt = (tank_rt_t *)data; +enemy_tank_driver(tank_rt_t *tank_rt) { enemy_t *enemy; int n_enemy; mb_timeval_t timeout, addend; int i; - + n_enemy = tank_rt->n_enemy; for(i = 0; i < n_enemy; i++) { enemy = enemies + i; @@ -250,7 +307,16 @@ get_now(&timeout); MB_TIMEVAL_SET(&addend, 0, 300000); MB_TIMEVAL_ADD(&timeout, &addend); - mb_timer_man_timeout(timer_man, &timeout, enemy_tank_driver, tank_rt); + mb_timer_man_timeout(timer_man, &timeout, enemy_tick, tank_rt); +} + +static void +enemy_tick(int hdl, const mb_timeval_t *tmo, + const mb_timeval_t *now, void *data) { + tank_rt_t *tank_rt = (tank_rt_t *)data; + + remove_pheromone(); + enemy_tank_driver(tank_rt); } /*! \brief Start a timer for enemy tank driver. @@ -264,7 +330,7 @@ get_now(&timeout); MB_TIMEVAL_SET(&addend, 0, 300000); MB_TIMEVAL_ADD(&timeout, &addend); - mb_timer_man_timeout(timer_man, &timeout, enemy_tank_driver, tank_rt); + mb_timer_man_timeout(timer_man, &timeout, enemy_tick, tank_rt); } void
--- a/examples/tank/tank_main.c Thu Dec 09 07:48:08 2010 +0800 +++ b/examples/tank/tank_main.c Thu Dec 09 07:48:46 2010 +0800 @@ -508,7 +508,7 @@ } while(0) static void keyboard_handler(event_t *event, void *arg) { - X_kb_event_t *xkey = (X_kb_event_t *)event; + mb_kb_event_t *xkey = (mb_kb_event_t *)event; tank_rt_t *tank_rt = (tank_rt_t *)arg; int direction; @@ -662,7 +662,11 @@ mb_rt_t *rt; tank_rt_t tank_rt; +#ifdef CONSOLE_BACKEND + rt = mb_runtime_new(NULL, 800, 600); +#else rt = mb_runtime_new(":0.0", 800, 600); +#endif initial_tank(&tank_rt, rt);
--- a/include/mb_X_supp.h Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_X_supp.h Thu Dec 09 07:48:46 2010 +0800 @@ -4,26 +4,6 @@ #define __X_SUPP_H_ #include <X11/Xlib.h> -#include "mb_types.h" -#include "mb_timer.h" -#include "mb_redraw_man.h" -#include "mb_img_ldr.h" - -/*! \ingroup xkb - * @{ - */ -typedef struct _X_kb_info X_kb_info_t; - -struct _X_kb_event { - event_t event; - int keycode; - int sym; -}; -typedef struct _X_kb_event X_kb_event_t; - -/* @} */ - -typedef struct _X_supp_runtime X_supp_runtime_t; typedef Window MB_WINDOW; typedef Display *MB_DISPLAY;
--- a/include/mb_ani_menu.h Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_ani_menu.h Thu Dec 09 07:48:46 2010 +0800 @@ -18,7 +18,7 @@ void (*callback)(struct _mb_animated_menu *m, int sel); void (*update_callback)(struct _mb_animated_menu *m, int sel); mb_progm_t *progm; - X_kb_event_t pending_keys[16]; + mb_kb_event_t pending_keys[16]; int pending_pos, pending_last; } mb_animated_menu_t; /** \brief Create an instace of animated menu.
--- a/include/mb_backend.h Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_backend.h Thu Dec 09 07:48:46 2010 +0800 @@ -16,6 +16,10 @@ #inclde "mb_dfb_supp.h" #endif +#ifdef CONSOLE_BACKEND +#include "mb_cons_supp.h" +#endif + struct _mb_rt; typedef struct _mb_rt mb_rt_t;
--- a/include/mb_config.h.in Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_config.h.in Thu Dec 09 07:48:46 2010 +0800 @@ -21,6 +21,9 @@ /* Enable Imlib2 Image Loader */ #undef IMLIB2_IMG_LOADER +/* Enable Dummy Image Loader */ +#undef DUMMY_IMG_LOADER + /* Enable sh_text */ #undef SH_TEXT @@ -33,4 +36,10 @@ /* Enable DirectFB backend */ #undef DFB_BACKEND +/* Enable console backend */ +#undef CONSOLE_BACKEND + +/* Enable XSHM */ +#undef XSHM + #endif /* __MB_CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_cons_supp.h Thu Dec 09 07:48:46 2010 +0800 @@ -0,0 +1,9 @@ +// -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- +// vim: sw=4:ts=8:sts=4 +#ifndef __CONS_SUPP_H_ +#define __CONS_SUPP_H_ + +typedef void *MB_WINDOW; +typedef void *MB_DISPLAY; + +#endif
--- a/include/mb_graph_engine_cairo.h Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_graph_engine_cairo.h Thu Dec 09 07:48:46 2010 +0800 @@ -26,7 +26,6 @@ #define mbe_image_surface_get_width cairo_image_surface_get_width #define mbe_image_surface_get_data cairo_image_surface_get_data #define mbe_scaled_font_reference cairo_scaled_font_reference -#define mbe_win_surface_create cairo_xlib_surface_create #define mbe_scaled_font_destroy cairo_scaled_font_destroy #define mbe_font_face_reference cairo_font_face_reference #define mbe_font_face_destroy cairo_font_face_destroy @@ -57,6 +56,7 @@ #define mbe_stroke cairo_stroke #define mbe_create cairo_create #define mbe_paint cairo_paint +#define mbe_flush(canvas) #define mbe_save cairo_save #define mbe_fill cairo_fill #define mbe_init() @@ -78,6 +78,12 @@ } +extern mbe_surface_t *mbe_win_surface_create(void *display, + void *drawable, + int fmt, + int width, + int height); + extern mbe_font_face_t * mbe_query_font_face(const char *family, int slant, int weight); extern void mbe_free_font_face(mbe_font_face_t *face);
--- a/include/mb_graph_engine_openvg.h Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_graph_engine_openvg.h Thu Dec 09 07:48:46 2010 +0800 @@ -12,8 +12,8 @@ * @{ */ #define mbe_scaled_font_text_extents(scaled, utf8, extents) -#define mbe_image_surface_get_stride(surface) (20) -#define mbe_image_surface_get_format(surface) ((mb_img_fmt_t)0) +#define mbe_image_surface_get_stride(surface) ((surface)->w * 4) +#define mbe_image_surface_get_format(surface) ((surface)->fmt) #define mbe_image_surface_get_height(surface) (surface)->h #define mbe_image_surface_get_width(surface) (surface)->w #define mbe_image_surface_get_data(surface) ((unsigned char *)NULL) @@ -207,9 +207,12 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> -extern mbe_surface_t *mbe_win_surface_create(Display *display, - Drawable drawable, - Visual *visual, +/* + * TODO: define a proper type for display and drawable. + */ +extern mbe_surface_t *mbe_win_surface_create(void *display, + void *drawable, + int fmt, int width, int height); #endif @@ -223,6 +226,7 @@ extern void mbe_surface_destroy(mbe_surface_t *surface); extern void mbe_copy_source(mbe_t *src_canvas, mbe_t *dst_canvas); +extern void mbe_flush(mbe_t *canvas); extern mbe_t *mbe_create(mbe_surface_t *surface); extern void mbe_destroy(mbe_t *canvas); extern void mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha);
--- a/include/mb_observer.h Thu Dec 09 07:48:08 2010 +0800 +++ b/include/mb_observer.h Thu Dec 09 07:48:46 2010 +0800 @@ -82,6 +82,13 @@ observer_t *observer; /*!< \brief Observer been added or removed. */ }; +struct _mb_kb_event { + event_t event; + int keycode; + int sym; +}; +typedef struct _mb_kb_event mb_kb_event_t; + /*! \brief Observer factory. * * It provides functions for allocation of subject and observer objects,
--- a/nodejs/observer.cc Thu Dec 09 07:48:08 2010 +0800 +++ b/nodejs/observer.cc Thu Dec 09 07:48:46 2010 +0800 @@ -31,7 +31,7 @@ static void xnjsmb_event_mod(Handle<Object> self, event_t *evt) { mouse_event_t *mevt; - X_kb_event_t *xkbevt; + mb_kb_event_t *xkbevt; switch(evt->type) { case EVT_ANY: @@ -49,7 +49,7 @@ case EVT_KB_PRESS: case EVT_KB_RELEASE: - xkbevt = (X_kb_event_t *)evt; + xkbevt = (mb_kb_event_t *)evt; SET(self, "keycode", Integer::New(xkbevt->keycode)); SET(self, "sym", Integer::New(xkbevt->sym)); break;
--- a/src/Makefile.am Thu Dec 09 07:48:08 2010 +0800 +++ b/src/Makefile.am Thu Dec 09 07:48:46 2010 +0800 @@ -45,6 +45,10 @@ libmbfly_la_SOURCES += dfb_supp.c endif +if CONSOLE_BACKEND +libmbfly_la_SOURCES += cons_supp.c +endif + if CAIRO_IMG_LOADER libmbfly_la_SOURCES += img_ldr.c endif @@ -56,6 +60,10 @@ libmbfly_la_LDFLAGS += @imlib2_LIBS@ endif +if DUMMY_IMG_LOADER +libmbfly_la_SOURCES += img_ldr_dummy.c +endif + if CAIRO_GRAPH_ENGINE libmbfly_la_SOURCES += graph_engine_cairo.c
--- a/src/X_supp.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/X_supp.c Thu Dec 09 07:48:46 2010 +0800 @@ -18,7 +18,6 @@ #include <sys/ipc.h> #include <sys/shm.h> #include <X11/extensions/XShm.h> -static void XSHM_update(X_supp_runtime_t *xmb_rt); #endif #define ERR -1 @@ -40,6 +39,7 @@ subject_t *kbevents; observer_factory_t *observer_factory; }; +typedef struct _X_kb_info X_kb_info_t; /* @} */ @@ -80,6 +80,7 @@ int mx, my; /* Position of last motion event */ int mbut_state; /* Button state of last motion event */ }; +typedef struct _X_supp_runtime X_supp_runtime_t; static void _x_supp_handle_x_event(X_supp_runtime_t *rt); @@ -160,6 +161,10 @@ xmb_io_man->monitors[io_hdl].type = MB_IO_DUMMY; } +#ifdef XSHM +static void XSHM_update(X_supp_runtime_t *xmb_rt); +#endif + /*! \brief Handle connection coming data and timeout of timers. * * \param display is a Display returned by XOpenDisplay(). @@ -321,7 +326,7 @@ static void X_kb_handle_event(X_kb_info_t *kbinfo, XKeyEvent *xkey) { unsigned int code; int sym; - X_kb_event_t event; + mb_kb_event_t event; code = xkey->keycode; sym = keycode2sym(kbinfo, code); @@ -755,6 +760,48 @@ } #endif /* XSHM */ +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +static int +_get_img_fmt_from_xvisual(Display *display, Visual *visual) { + VisualID visual_id; + XVisualInfo temp; + XVisualInfo *infos; + int n; + int fmt = -1; + + visual_id = XVisualIDFromVisual(visual); + temp.visualid = visual_id; + infos = XGetVisualInfo(display, VisualIDMask, &temp, &n); + if(n != 1) + return -1; + + switch(infos->depth) { + case 32: + fmt = MB_IFMT_ARGB32; + break; + + case 24: + fmt = MB_IFMT_RGB24; + break; + + case 16: + fmt = MB_IFMT_RGB16_565; + break; + + case 8: + fmt = MB_IFMT_A8; + break; + + case 1: + fmt = MB_IFMT_A1; + break; + } + + return fmt; +} + /*! \brief Initialize a MadButterfy runtime for Xlib. * * This one is very like _x_supp_init(), except it accepts a @@ -772,6 +819,7 @@ mb_img_ldr_t *img_ldr; int w, h; int disp_fd; + int fmt; w = xmb_rt->w; h = xmb_rt->h; @@ -785,17 +833,24 @@ xmb_rt->surface = mbe_image_surface_create(MB_IFMT_ARGB32, w, h); - if(xmb_rt->backend_surface == NULL) /* xshm_init() may create one */ + if(xmb_rt->backend_surface == NULL) { /* xshm_init() may create one */ + fmt = _get_img_fmt_from_xvisual(xmb_rt->display, xmb_rt->visual); + if(fmt == -1) + return ERR; + xmb_rt->backend_surface = mbe_win_surface_create(xmb_rt->display, xmb_rt->win, - xmb_rt->visual, + fmt, w, h); + } xmb_rt->cr = mbe_create(xmb_rt->surface); xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface); xmb_rt->rdman = (redraw_man_t *)malloc(sizeof(redraw_man_t)); + xmb_rt->rdman->w = w; + xmb_rt->rdman->h = h; redraw_man_init(xmb_rt->rdman, xmb_rt->cr, xmb_rt->backend_cr); /* FIXME: This is a wired loopback reference. This is inly * required when we need to get the xmb_rt->tman for the
--- a/src/animate.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/animate.c Thu Dec 09 07:48:46 2010 +0800 @@ -246,7 +246,7 @@ #endif /* UNITTEST */ mb_timeval_t next_tmo; mb_word_t *word; - mb_timer_t *timer; + int timer; int i; MB_TIMEVAL_SET(&next_tmo, 0, STEP_INTERVAL);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cons_supp.c Thu Dec 09 07:48:46 2010 +0800 @@ -0,0 +1,667 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <poll.h> +#include "mb_graph_engine.h" +#include "mb_redraw_man.h" +#include "mb_timer.h" +#include "mb_cons_supp.h" +#include "mb_backend.h" +#include "mb_backend_utils.h" +#include "config.h" + +#define ERR -1 +#define OK 0 + +#define FALSE 0 +#define TRUE 1 + +#define ASSERT(x) + +#define ONLY_MOUSE_MOVE_RAW 1 + +typedef int keysym; + +static mb_timer_factory_t *_timer_factory = &tman_timer_factory; + +/*! \ingroup console_kb + * @{ + */ +struct _cons_kb_info { + int kb_fd; + + int keycode_min, keycode_max; + int ksym_per_code; + keysym *syms; + subject_t *kbevents; + observer_factory_t *observer_factory; +}; +typedef struct _cons_kb_info cons_kb_info_t; + +/* @} */ + +struct _cons_supp_runtime { + MB_DISPLAY display; + MB_WINDOW win; + + mbe_surface_t *surface; + mbe_t *cr; + redraw_man_t *rdman; + mb_img_ldr_t *img_ldr; + int w, h; + + cons_kb_info_t kbinfo; + mb_IO_man_t *io_man; + mb_timer_man_t *timer_man; + +#ifndef ONLY_MOUSE_MOVE_RAW + /* States */ + shape_t *last; +#endif + + /* For handle connection */ + int io_hdl; + + /* + * Following variables are used by handle_single_cons_event() + */ + int last_evt_type; /* Type of last event */ + int ex1, ey1, ex2, ey2; /* Aggregate expose events */ + int mx, my; /* Position of last motion event */ + int mbut_state; /* Button state of last motion event */ +}; +typedef struct _cons_supp_runtime cons_supp_runtime_t; + +static void _cons_supp_handle_cons_event(cons_supp_runtime_t *rt); + +/*! \defgroup cons_supp_io IO manager for console. + * @{ + */ +#define MAX_MONITORS 200 + +typedef struct { + int type; + int fd; + mb_IO_cb_t cb; + void *data; +} monitor_t; + +struct _cons_supp_IO_man { + mb_IO_man_t io_man; + monitor_t monitors[MAX_MONITORS]; + int n_monitor; +}; + +static int _cons_supp_io_man_reg(struct _mb_IO_man *io_man, + int fd, MB_IO_TYPE type, + mb_IO_cb_t cb, void *data); +static void _cons_supp_io_man_unreg(struct _mb_IO_man *io_man, int io_hdl); +static mb_IO_man_t *_cons_supp_io_man_new(void); +static void _cons_supp_io_man_free(mb_IO_man_t *io_man); + +static mb_IO_factory_t _cons_supp_default_io_factory = { + _cons_supp_io_man_new, + _cons_supp_io_man_free +}; +static mb_IO_factory_t *_io_factory = &_cons_supp_default_io_factory; + +static struct _cons_supp_IO_man _default_io_man = { + {_cons_supp_io_man_reg, _cons_supp_io_man_unreg}, + {}, /* monitors */ + 0 /* n_monitor */ +}; + +static mb_IO_man_t * +_cons_supp_io_man_new(void) { + return (mb_IO_man_t *)&_default_io_man; +} + +static void +_cons_supp_io_man_free(mb_IO_man_t *io_man) { +} + +static int +_cons_supp_io_man_reg(struct _mb_IO_man *io_man, + int fd, MB_IO_TYPE type, mb_IO_cb_t cb, void *data) { + struct _cons_supp_IO_man *cmb_io_man = (struct _cons_supp_IO_man *)io_man; + int i; + + for(i = 0; i < cmb_io_man->n_monitor; i++) { + if (cmb_io_man->monitors[i].type == MB_IO_DUMMY) + break; + } + if (i == MAX_MONITORS) + return ERR; + + cmb_io_man->monitors[i].type = type; + cmb_io_man->monitors[i].fd = fd; + cmb_io_man->monitors[i].cb = cb; + cmb_io_man->monitors[i].data = data; + i++; + if(i > cmb_io_man->n_monitor) + cmb_io_man->n_monitor = i; + return i - 1; +} + +static void +_cons_supp_io_man_unreg(struct _mb_IO_man *io_man, int io_hdl) { + struct _cons_supp_IO_man *cmb_io_man = (struct _cons_supp_IO_man *)io_man; + + ASSERT(io_hdl < cmb_io_man->n_monitor); + cmb_io_man->monitors[io_hdl].type = MB_IO_DUMMY; +} + +/*! \brief Handle connection coming data and timeout of timers. + * + */ +static void +_cons_supp_event_loop(mb_rt_t *rt) { + struct _cons_supp_runtime *cmb_rt = (struct _cons_supp_runtime *)rt; + struct _cons_supp_IO_man *io_man = + (struct _cons_supp_IO_man *)cmb_rt->io_man; + mb_timer_man_t *timer_man = (mb_timer_man_t *)cmb_rt->timer_man; + redraw_man_t *rdman; + mb_tman_t *tman = tman_timer_man_get_tman(timer_man); + mb_timeval_t now, tmo; + struct timeval tv; + fd_set rfds, wfds; + int nfds = 0; + int r, r1,i; + + rdman = mb_runtime_rdman(rt); + rdman_redraw_all(rdman); + + _cons_supp_handle_cons_event(cmb_rt); + + while(1) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + for(i = 0; i < io_man->n_monitor; i++) { + if(io_man->monitors[i].type == MB_IO_R || + io_man->monitors[i].type == MB_IO_RW) { + FD_SET(io_man->monitors[i].fd, &rfds); + nfds = MB_MAX(nfds, io_man->monitors[i].fd + 1); + } + if(io_man->monitors[i].type == MB_IO_W || + io_man->monitors[i].type == MB_IO_RW) { + FD_SET(io_man->monitors[i].fd, &wfds); + nfds = MB_MAX(nfds, io_man->monitors[i].fd + 1); + } + } + + get_now(&now); + r = mb_tman_next_timeout(tman, &now, &tmo); + + if(r == 0) { + tv.tv_sec = MB_TIMEVAL_SEC(&tmo); + tv.tv_usec = MB_TIMEVAL_USEC(&tmo); + r1 = select(nfds, &rfds, NULL, NULL, &tv); + } else + r1 = select(nfds, &rfds, NULL, NULL, NULL); + + if(r1 == -1) { + perror("select"); + break; + } + + if(r1 == 0) { + get_now(&now); + mb_tman_handle_timeout(tman, &now); + rdman_redraw_changed(rdman); + } else { + for(i = 0; i < io_man->n_monitor; i++) { + if(io_man->monitors[i].type == MB_IO_R || + io_man->monitors[i].type == MB_IO_RW) { + if(FD_ISSET(io_man->monitors[i].fd, &rfds)) + io_man->monitors[i].cb(i, io_man->monitors[i].fd, + MB_IO_R, + io_man->monitors[i].data); + } + if(io_man->monitors[i].type == MB_IO_W || + io_man->monitors[i].type == MB_IO_RW) { + if(FD_ISSET(io_man->monitors[i].fd, &wfds)) + io_man->monitors[i].cb(i, io_man->monitors[i].fd, + MB_IO_W, + io_man->monitors[i].data); + } + } + } + } +} + +/* @} */ + +/*! \defgroup console_kb Console Keyboard Handling + * + * Accept keyboard events from console and delivery it to + * application through observer pattern. There is a subject, + * per X-connection, for that. + * @{ + */ +static int keycode2sym(cons_kb_info_t *kbinfo, unsigned int keycode) { + /* TODO: implement keycode to key symbol translation */ + return 0; +} + +static int cons_kb_init(cons_kb_info_t *kbinfo, MB_DISPLAY display, + redraw_man_t *rdman) { + int n_syms; + observer_factory_t *factory; + int r; + + /* TODO: set keycode_min, keycode_max and syms */ + if((int)display != -1) + kbinfo->kb_fd = (int)display; + else + kbinfo->kb_fd = STDIN_FILENO; + + factory = rdman_get_observer_factory(rdman); + kbinfo->kbevents = subject_new(factory, kbinfo, OBJT_KB); + if(kbinfo->kbevents == NULL) + return ERR; + /*! \todo Make sure observer_factory is still need. */ + kbinfo->observer_factory = factory; + + return OK; +} + +static void cons_kb_destroy(cons_kb_info_t *kbinfo) { + subject_free(kbinfo->kbevents); +} +/* @} */ + +/*! \brief Notify observers of the shape at specified + * position for mouse event. + * + * Observers of parent shapes may be called if the subject is not + * with SUBF_STOP_PROPAGATE flag. The subject of mouse event + * for a shape is returned by sh_get_mouse_event_subject(). + */ +static void notify_coord_or_shape(redraw_man_t *rdman, + mb_obj_t *obj, + co_aix x, co_aix y, int etype, + unsigned int state, + unsigned int button) { + mouse_event_t mouse_event; + subject_t *subject; + + mouse_event.event.type = etype; + mouse_event.x = x; + mouse_event.y = y; + mouse_event.but_state = state; + mouse_event.button = button; + + if(IS_MBO_SHAPES(obj)) + subject = sh_get_mouse_event_subject((shape_t *)obj); + else + subject = coord_get_mouse_event((coord_t *)obj); + + subject_notify(subject, (event_t *)&mouse_event); +} + +/*! \brief Handle keyboard event and maintain internal states. + * + * It keeps internal state in rt to improve performance. + */ +static void +handle_single_cons_event(cons_supp_runtime_t *rt) { + /* TODO: handle keyboard and mouse events. */ + printf("handle_single_cons_event() will be implemented later\n"); +} + +/*! \brief Call when no more event in an event iteration. + * + * No more event means event queue is emplty. This function will + * perform some actions according current internal state. + */ +static void +no_more_event(cons_supp_runtime_t *rt) { +} + +/*! \brief Dispatch all console events in the queue. + */ +static void _cons_supp_handle_cons_event(cons_supp_runtime_t *cmb_rt) { + int console_fd = (int)cmb_rt->display; + struct pollfd pfd = {console_fd, POLLIN, 0}; + int r; + + while((r = poll(&pfd, 1, 0)) > 0) { + handle_single_cons_event(cmb_rt); + } + no_more_event(cmb_rt); +} + +static void +_cons_supp_handle_connection(int hdl, int fd, MB_IO_TYPE type, void *data) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *)data; + + _cons_supp_handle_cons_event(cmb_rt); +} + +/*! \brief Initialize a MadButterfy runtime for Xlib. + * + * This one is very like _cons_supp_init(), except it accepts a + * cons_supp_runtime_t object initialized with a display connected to a X + * server and an opened window. + * + * Following field of the cons_supp_runtime_t object should be initialized. + * - w, h + * - win + * - display + * - visual + */ +static int +_cons_supp_init_with_win_internal(cons_supp_runtime_t *cmb_rt) { + mb_img_ldr_t *img_ldr; + int w, h; + int console_fd; + + w = cmb_rt->w; + h = cmb_rt->h; + + mbe_init(); + + cmb_rt->surface = + mbe_win_surface_create(cmb_rt->display, cmb_rt->win, + MB_IFMT_ARGB32, w, h); + + cmb_rt->cr = mbe_create(cmb_rt->surface); + + cmb_rt->rdman = (redraw_man_t *)malloc(sizeof(redraw_man_t)); + redraw_man_init(cmb_rt->rdman, cmb_rt->cr, NULL); + cmb_rt->rdman->w = w; + cmb_rt->rdman->h = h; + /* FIXME: This is a wired loopback reference. This is inly + * required when we need to get the cmb_rt->tman for the + * animation. We should relocate the tman to the + * redraw_man_t instead. + */ + cmb_rt->rdman->rt = cmb_rt; + + cmb_rt->io_man = mb_io_man_new(_io_factory); + cmb_rt->timer_man = mb_timer_man_new(_timer_factory); + + img_ldr = simple_mb_img_ldr_new(""); + cmb_rt->img_ldr = img_ldr; + /*! \todo Remove rdman_set_img_ldr() */ + rdman_set_img_ldr(cmb_rt->rdman, img_ldr); /* this is ncessary? */ + +#ifndef ONLY_MOUSE_MOVE_RAW + cmb_rt->last = NULL; +#endif + + cons_kb_init(&cmb_rt->kbinfo, cmb_rt->display, cmb_rt->rdman); + + console_fd = (int)cmb_rt->display; + cmb_rt->io_hdl = mb_io_man_reg(cmb_rt->io_man, console_fd, + MB_IO_R, + _cons_supp_handle_connection, + cmb_rt); + + return OK; +} + +/*! \brief Initialize a MadButterfy runtime for console. + * + * It setups a runtime environment to run MadButterfly with console. + * Users should specify width and height of the opening window. + * + * \param display_name is actually the path to the console/input device. + */ +static int _cons_supp_init(cons_supp_runtime_t *cmb_rt, + const char *display_name, + int w, int h) { + int r; + int console_fd; + + memset(cmb_rt, 0, sizeof(cons_supp_runtime_t)); + + if(display_name == NULL || strlen(display_name) == 0) + console_fd = STDIN_FILENO; + else { + console_fd = open(display_name, O_RDONLY); + if(console_fd == -1) + return ERR; + } + + cmb_rt->display = (MB_DISPLAY)console_fd; + cmb_rt->win = NULL; + cmb_rt->w = w; + cmb_rt->h = h; + + r = _cons_supp_init_with_win_internal(cmb_rt); + + return r; +} + +/*! \brief Initialize a MadButterfly runtime for a window of console. + * + * This function is equivalent to _cons_supp_init() with fixed width + * and height. Since, there is no window for console. + * + * Runtimes initialized with this function should be destroyed with + * cons_supp_destroy_keep_win(). + * + * \param display is actually a file descriptor of console (input device). + */ +static int +_cons_supp_init_with_win(cons_supp_runtime_t *cmb_rt, + MB_DISPLAY display, MB_WINDOW win) { + int r; + + memset(cmb_rt, 0, sizeof(cons_supp_runtime_t)); + + cmb_rt->display = display; + cmb_rt->w = 800; + cmb_rt->h = 600; + + r = _cons_supp_init_with_win_internal(cmb_rt); + + return r; +} + +static void cons_supp_destroy_keep_win(cons_supp_runtime_t *cmb_rt); + +static void cons_supp_destroy(cons_supp_runtime_t *cmb_rt) { + int console_fd = cmb_rt = (int)cmb_rt->display; + + close(console_fd); + cons_supp_destroy_keep_win(cmb_rt); +} + +/*! \brief Destroy a MadButterfly runtime initialized with + * _cons_supp_init_with_win(). + * + * Destroying a runtime with this function prevent the window and + * display associated with the runtime being closed. + */ +static void +cons_supp_destroy_keep_win(cons_supp_runtime_t *cmb_rt) { + if(cmb_rt->rdman) { + redraw_man_destroy(cmb_rt->rdman); + free(cmb_rt->rdman); + } + + if(cmb_rt->io_hdl) + mb_io_man_unreg(cmb_rt->io_man, cmb_rt->io_hdl); + + if(cmb_rt->io_man) + mb_io_man_free(_io_factory, cmb_rt->io_man); + if(cmb_rt->timer_man) + mb_timer_man_free(_timer_factory, cmb_rt->timer_man); + + if(cmb_rt->img_ldr) + MB_IMG_LDR_FREE(cmb_rt->img_ldr); + + if(cmb_rt->cr) + mbe_destroy(cmb_rt->cr); + + if(cmb_rt->surface) + mbe_surface_destroy(cmb_rt->surface); + + cons_kb_destroy(&cmb_rt->kbinfo); +} + +static mb_rt_t * +_cons_supp_new(const char *display_name, int w, int h) { + cons_supp_runtime_t *rt; + int r; + + rt = O_ALLOC(cons_supp_runtime_t); + if(rt == NULL) + return NULL; + + r = _cons_supp_init(rt, display_name, w, h); + if(r != OK) { + free(rt); + return NULL; + } + + return (mb_rt_t *)rt; +} + +/*! \brief Create a new runtime for existed window for console. + * + * The object returned by this function must be free with + * _cons_supp_free_keep_win() to prevent the window from closed. + */ +static mb_rt_t * +_cons_supp_new_with_win(MB_DISPLAY display, MB_WINDOW win) { + cons_supp_runtime_t *rt; + int r; + + rt = O_ALLOC(cons_supp_runtime_t); + if(rt == NULL) + return NULL; + + r = _cons_supp_init_with_win(rt, display, win); + if(r != OK) { + free(rt); + return NULL; + } + + return (mb_rt_t *)rt; +} + +static void +_cons_supp_free(mb_rt_t *rt) { + cons_supp_destroy((cons_supp_runtime_t *) rt); + free(rt); +} + +/*! \brief Free runtime created with _cons_supp_new_with_win(). + */ +static void +_cons_supp_free_keep_win(mb_rt_t *rt) { + cons_supp_destroy_keep_win((cons_supp_runtime_t *) rt); + free(rt); +} + +static subject_t * +_cons_supp_kbevents(mb_rt_t *rt) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + return cmb_rt->kbinfo.kbevents; +} + +static redraw_man_t * +_cons_supp_rdman(mb_rt_t *rt) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + return cmb_rt->rdman; +} + +static mb_timer_man_t * +_cons_supp_timer_man(mb_rt_t *rt) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + return cmb_rt->timer_man; +} + +static observer_factory_t * +_cons_supp_observer_factory(mb_rt_t *rt) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + observer_factory_t *factory; + + factory = rdman_get_observer_factory(cmb_rt->rdman); + return factory; +} + +static mb_img_ldr_t * +_cons_supp_img_ldr(mb_rt_t *rt) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + mb_img_ldr_t *img_ldr; + + img_ldr = cmb_rt->img_ldr; + + return img_ldr; +} + +static int +_cons_supp_add_event(mb_rt_t *rt, int fd, MB_IO_TYPE type, + mb_IO_cb_t cb, void *data) +{ + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + mb_IO_man_t *io_man = cmb_rt->io_man; + int hdl; + + hdl = mb_io_man_reg(io_man, fd, type, cb, data); + return hdl; +} + +static void +_cons_supp_remove_event(mb_rt_t *rt, int hdl) +{ + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *) rt; + mb_IO_man_t *io_man = cmb_rt->io_man; + + mb_io_man_unreg(io_man, hdl); +} + +static int +_cons_supp_flush(mb_rt_t *rt) { + cons_supp_runtime_t *cmb_rt = (cons_supp_runtime_t *)rt; + + mbe_flush(cmb_rt->cr); + return OK; +} + +static void +_cons_supp_reg_IO_factory(mb_IO_factory_t *io_factory) { + _io_factory = io_factory; +} + +static void +_cons_supp_reg_timer_factory(mb_timer_factory_t *timer_factory) { + _timer_factory = timer_factory; +} + +mb_backend_t mb_dfl_backend = { _cons_supp_new, + _cons_supp_new_with_win, + + _cons_supp_free, + _cons_supp_free_keep_win, + _cons_supp_add_event, + _cons_supp_remove_event, + _cons_supp_event_loop, + _cons_supp_flush, + + _cons_supp_kbevents, + _cons_supp_rdman, + _cons_supp_timer_man, + _cons_supp_observer_factory, + _cons_supp_img_ldr, + + _cons_supp_reg_IO_factory, + _cons_supp_reg_timer_factory, +}; + +/* + * Local Variables: + * indent-tabs-mode: t + * tab-width: 8 + * c-basic-offset: 4 + * c-file-style:"stroustrup" + * fill-column:79 + * End: + */ +// vim: sw=4:ts=8:sts=4:textwidth=79
--- a/src/graph_engine_cairo.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/graph_engine_cairo.c Thu Dec 09 07:48:46 2010 +0800 @@ -1,5 +1,6 @@ // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- // vim: sw=4:ts=8:sts=4 +#include <X11/Xlib.h> #include <fontconfig/fontconfig.h> #include <cairo-ft.h> #include "mb_graph_engine_cairo.h" @@ -82,6 +83,23 @@ } +extern mbe_surface_t * +mbe_win_surface_create(void *display, void *drawable, + int fmt, int width, int height) { + XWindowAttributes attrs; + mbe_surface_t *surf; + int r; + + r = XGetWindowAttributes((Display *)display, (Drawable)drawable, &attrs); + if(r == 0) + return NULL; + + surf = cairo_xlib_surface_create((Display *)display, (Drawable)drawable, + attrs.visual, width, height); + + return surf; +} + /*! \brief Find out a font face for a pattern specified. * * The pattern, here, is a vector of family, slant, and weight.
--- a/src/graph_engine_openvg.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/graph_engine_openvg.c Thu Dec 09 07:48:46 2010 +0800 @@ -540,76 +540,30 @@ } #ifdef EGL_GLX -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -static int -_get_img_fmt_from_xvisual(Display *display, Visual *visual) { - VisualID visual_id; - XVisualInfo temp; - XVisualInfo *infos; - int n; - int fmt = -1; - - visual_id = XVisualIDFromVisual(visual); - temp.visualid = visual_id; - infos = XGetVisualInfo(display, VisualIDMask, &temp, &n); - if(n != 1) - return -1; - - switch(infos->depth) { - case 32: - fmt = MB_IFMT_ARGB32; - break; - - case 24: - fmt = MB_IFMT_RGB24; - break; - - case 16: - fmt = MB_IFMT_RGB16_565; - break; - - case 8: - fmt = MB_IFMT_A8; - break; - - case 1: - fmt = MB_IFMT_A1; - break; - } - - return fmt; -} - /*! \brief Create an EGL window surface for X11. * * This function is compiled only for GLX enabled. */ mbe_surface_t * -mbe_win_surface_create(Display *display, Drawable drawable, - Visual *visual, int width, int height) { +mbe_win_surface_create(void *display, void *drawable, + int fmt, int width, int height) { EGLDisplay egl_disp; EGLSurface egl_surface; mbe_surface_t *surface; EGLConfig config; EGLint attrib_list[2] = {EGL_NONE}; - int fmt; int r; - fmt = _get_img_fmt_from_xvisual(display, visual); - if(fmt == -1) - return NULL; - r = _openvg_find_config(fmt, width, height, &config); if(r != 0) return NULL; - egl_disp = eglGetDisplay(display); + egl_disp = eglGetDisplay((Display *)display); if(egl_disp == EGL_NO_DISPLAY || egl_disp != _VG_DISPLAY()) return NULL; - egl_surface = eglCreateWindowSurface(egl_disp, config, drawable, + egl_surface = eglCreateWindowSurface(egl_disp, config, + (Drawable)drawable, attrib_list); surface = O_ALLOC(mbe_surface_t); @@ -721,6 +675,17 @@ eglSwapBuffers(display, VG_MBE_SURFACE(dst_canvas)); } +void +mbe_flush(mbe_t *canvas) { + EGLDisplay display; + mbe_surface_t *surface; + + _MK_CURRENT_CTX(canvas); + display = _VG_DISPLAY(); + surface = VG_MBE_SURFACE(canvas); + eglSwapBuffers(display, surface); +} + mbe_t * mbe_create(mbe_surface_t *surface) { EGLDisplay display;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/img_ldr_dummy.c Thu Dec 09 07:48:46 2010 +0800 @@ -0,0 +1,38 @@ +#include <stdio.h> +#include "mb_img_ldr.h" + +static mb_img_data_t *img_ldr_dummy_load(mb_img_ldr_t *ldr, + const char *img_id); +static void img_ldr_dummy_free(mb_img_ldr_t *ldr); + +static mb_img_ldr_t img_ldr = { + img_ldr_dummy_load, + img_ldr_dummy_free +}; + +#ifndef ERR +#include <stdio.h> +#include <stdlib.h> +#define ERR(msg) do { fprintf(stderr, __FILE__ ":%d: %s", __LINE__, msg); abort(); } while(0) +#endif +#ifndef NOT_IMPLEMENT +#define NOT_IMPLEMENT(func) \ + ERR(func " is not impmemented\n") +#endif + +static mb_img_data_t * +img_ldr_dummy_load(mb_img_ldr_t *ldr, const char *img_id) { + NOT_IMPLEMENT("img_ldr_dummy_load"); + return NULL; +} + +static void +img_ldr_dummy_free(mb_img_ldr_t *ldr) { + NOT_IMPLEMENT("img_ldr_dummy_free"); +} + +mb_img_ldr_t * +simple_mb_img_ldr_new(const char *img_repository) { + return &img_ldr; +} +
--- a/src/img_ldr_imlib2.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/img_ldr_imlib2.c Thu Dec 09 07:48:46 2010 +0800 @@ -1,6 +1,7 @@ // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- // vim: sw=4:ts=8:sts=4 #include <stdio.h> +#include <stdint.h> #include <string.h> #include <Imlib2.h> #include "mb_graph_engine.h" @@ -19,7 +20,6 @@ struct _simple_mb_img_data { mb_img_data_t img; - Imlib_Image img_hdl; }; typedef struct _simple_mb_img_data simple_mb_img_data_t; @@ -31,7 +31,11 @@ simple_mb_img_data_t *img; Imlib_Image img_hdl; int w, h; - void *data; + int i, j, pos; + uint32_t alpha; + uint32_t value; + uint32_t *data; + uint32_t *premultiple_data; char *fname; int sz; @@ -50,21 +54,56 @@ imlib_context_set_image(img_hdl); w = imlib_image_get_width(); h = imlib_image_get_height(); - data = imlib_image_get_data_for_reading_only(); + data = (uint32_t *)imlib_image_get_data_for_reading_only(); img = O_ALLOC(simple_mb_img_data_t); if(img == NULL) { imlib_free_image(); return NULL; } - img->img.content = data; + + premultiple_data = (uint32_t *)malloc(4 * w * h); + if(premultiple_data == NULL) { + free(img); + imlib_free_image(); + return NULL; + } + memcpy(premultiple_data, data, 4 * w * h); + + /* Pre-multiply + * + * Our reference model is Cairo. In Cairo model, image is + * pre-multiplied with alpha, but imlib2 is not. So, we do it + * here. + */ + pos = 0; + for(i = 0; i < h; i++) { + for(j = 0; j < w; j++) { + value = data[pos]; + alpha = value >> 24; + if(alpha != 0xff) { + if(alpha == 0) + value = 0; + else { + value = (value & 0xff000000) | + (((value & 0xff0000) * alpha / 0xff) & 0xff0000) | + (((value & 0xff00) * alpha / 0xff) & 0xff00) | + ((value & 0xff) * alpha / 0xff); + } + } + premultiple_data[pos++] = value; + } + } + + img->img.content = premultiple_data; img->img.w = w; img->img.h = h; img->img.stride = w * 4; img->img.fmt = MB_IFMT_ARGB32; img->img.free = simple_mb_img_ldr_img_free; - img->img_hdl = img_hdl; + imlib_free_image(); + return (mb_img_data_t *)img; } @@ -72,8 +111,7 @@ void simple_mb_img_ldr_img_free(mb_img_data_t *img) { simple_mb_img_data_t *simg = (simple_mb_img_data_t *)img; - imlib_context_set_image(simg->img_hdl); - imlib_free_image(); + free(simg->img.content); free(img); }
--- a/src/mbaf/animated_menu.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/mbaf/animated_menu.c Thu Dec 09 07:48:46 2010 +0800 @@ -259,7 +259,7 @@ static void mb_animated_menu_send_pending_key(event_t *ev,void *arg) { mb_animated_menu_t *m = (mb_animated_menu_t *) arg; - X_kb_event_t *xkey; + mb_kb_event_t *xkey; xkey = &m->pending_keys[m->pending_pos]; m->pending_pos = (m->pending_pos + 1) & 0xf; @@ -268,7 +268,7 @@ static void mb_animated_menu_keyHandler(event_t *ev, void *arg) { mb_animated_menu_t *m = (mb_animated_menu_t *) arg; - X_kb_event_t *xkey = (X_kb_event_t *)ev; + mb_kb_event_t *xkey = (mb_kb_event_t *)ev; if(xkey->event.type != EVT_KB_PRESS) { return; }
--- a/src/redraw_man.c Thu Dec 09 07:48:08 2010 +0800 +++ b/src/redraw_man.c Thu Dec 09 07:48:46 2010 +0800 @@ -2474,10 +2474,14 @@ * rules. */ draw_shapes_in_dirty_areas(rdman); - n_areas = _coord_get_dirty_areas(rdman->root_coord)->num; - areas = _coord_get_dirty_areas(rdman->root_coord)->ds; - copy_cr_2_backend(rdman, n_areas, areas); - reset_clip(rdman->backend); + if(rdman->backend) { + n_areas = _coord_get_dirty_areas(rdman->root_coord)->num; + areas = _coord_get_dirty_areas(rdman->root_coord)->ds; + copy_cr_2_backend(rdman, n_areas, areas); + reset_clip(rdman->backend); + } else { + mbe_flush(rdman->cr); + } for(i = 0; i < rdman->zeroing_coords.num; i++) { coord = rdman->zeroing_coords.ds[i]; DARRAY_CLEAN(_coord_get_dirty_areas(coord)); @@ -2515,8 +2519,8 @@ area.x = area.y = 0; #ifndef UNITTEST surface = mbe_get_target(rdman->cr); - area.w = mbe_image_surface_get_width(surface); - area.h = mbe_image_surface_get_height(surface); + area.w = rdman->w; + area.h = rdman->h; #else area.w = 1024; area.h = 1024;