# HG changeset patch # User John Tsiombikas # Date 1360064436 -7200 # Node ID 88a2049be27bce48e985941e1f067689bad9648f fbee initial diff -r 000000000000 -r 88a2049be27b src/fbee.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fbee.c Tue Feb 05 13:40:36 2013 +0200 @@ -0,0 +1,63 @@ +#include +#include "fbee.h" +#include "fbeeimpl.h" + +static struct closure evfunc[NUM_FBEE_EVENTS]; + +int fbee_init(void) +{ + memset(evfunc, 0, sizeof evfunc); + + return fbee_sys_init(); +} + +void fbee_destroy(void) +{ + fbee_sys_destroy(); +} + +int fbee_set_video_mode(int width, int height, int bpp, unsigned int flags) +{ + return fbee_sys_set_video(width, height, bpp, flags); +} + +int fbee_get_video_mode(int *width, int *height, int *bpp) +{ + return fbee_sys_get_video(width, height, bpp); +} + +void fbee_event_func(int evtype, void (*func)(), void *cls) +{ + evfunc[evtype].func = func; + evfunc[evtype].cls = cls; +} + +int fbee_process_events(void) +{ + return fbee_sys_process_events(); +} + +void fbee_evloop(void) +{ + fbee_sys_evloop(); +} + +void *fbee_framebuffer(void) +{ + return fbee_sys_framebuffer(); +} + +void fbee_update(void *img) +{ + fbee_sys_update(img); +} + + +struct closure *fbee_get_callback(int ev) +{ + if(ev < 0 || ev >= NUM_FBEE_EVENTS) { + return 0; + } + + return evfunc[ev].func ? evfunc + ev : 0; +} diff -r 000000000000 -r 88a2049be27b src/fbee.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fbee.h Tue Feb 05 13:40:36 2013 +0200 @@ -0,0 +1,57 @@ +#ifndef FBEE_H_ +#define FBEE_H_ + +enum { + FBEE_EV_DRAW, + FBEE_EV_RESIZE, + FBEE_EV_KEY, + FBEE_EV_BUTTON, + FBEE_EV_MOTION, + FBEE_EV_IDLE, + + NUM_FBEE_EVENTS +}; + +/* callback prototypes: + * + * void draw_callback(void *cls); + * void resize_callback(int x, int y, void *cls); + * void keyb_callback(int key, int state, void *cls); + * void button_callback(int bn, int state, void *cls); + * void motion_callback(int x, int y, void *cls); + * void idle_callback(void *cls); + */ + +#ifdef __cplusplus +extern "C" { +#endif + +int fbee_init(void); +void fbee_destroy(void); + +int fbee_set_video_mode(int width, int height, int bpp, unsigned int flags); +int fbee_get_video_mode(int *width, int *height, int *bpp); + +/* register an event callback */ +void fbee_event_func(int evtype, void (*func)(), void *cls); + +/* run a single iteration of the event loop and return */ +int fbee_process_events(void); + +/* start event processing (never returns) */ +void fbee_evloop(void); + +/* signal fbee to redraw the window */ +void fbee_redisplay(void); + +/* get a pointer to the framebuffer */ +void *fbee_framebuffer(void); + +/* copy an image to the framebuffer (size and format must match) */ +void fbee_update(void *img); + +#ifdef __cplusplus +} +#endif + +#endif /* FBEE_H_ */ diff -r 000000000000 -r 88a2049be27b src/fbeeimpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fbeeimpl.h Tue Feb 05 13:40:36 2013 +0200 @@ -0,0 +1,21 @@ +#ifndef FBEEIMPL_H_ +#define FBEEIMPL_H_ + +struct closure { + void (*func)(); + void *cls; +}; + +/* functions implemented by each graphics system module */ +int fbee_sys_init(void); +void fbee_sys_destroy(void); +int fbee_sys_set_video(int width, int height, int bpp, unsigned int flags); +int fbee_sys_get_video(int *width, int *height, int *bpp); +int fbee_sys_process_events(void); +void fbee_sys_evloop(void); +void *fbee_sys_framebuffer(void); +void fbee_sys_update(void *img); + +struct closure *fbee_get_callback(int evtype); + +#endif /* FBEEIMPL_H_ */ diff -r 000000000000 -r 88a2049be27b src/sys_sdl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sys_sdl.c Tue Feb 05 13:40:36 2013 +0200 @@ -0,0 +1,134 @@ +#include +#include "fbee.h" +#include "fbeeimpl.h" + +static int quit, dirty; +static SDL_Surface *fbsurf; + +int fbee_sys_init(void) +{ + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); + quit = 0; + dirty = 1; + return 0; +} + +int fbee_sys_set_video(int width, int height, int bpp, unsigned int flags) +{ + unsigned int sdl_flags = SDL_HWSURFACE; + if(!(fbsurf = SDL_SetVideoMode(width, height, bpp, sdl_flags))) { + fprintf(stderr, "failed to set video mode\n"); + return -1; + } + SDL_WM_SetCaption("fbee", "fbee"); + return 0; +} + +int fbee_sys_get_video(int *width, int *height, int *bpp) +{ + if(fbsurf) { + *width = fbsurf->w; + *height = fbsurf->h; + *bpp = fbsurf->format->BitsPerPixel; + return 0; + } + return -1; +} + +void fbee_sys_destroy(void) +{ + SDL_Quit(); +} + +int fbee_sys_process_events(void) +{ + SDL_Event ev; + + if(dirty) { + struct closure *cb = fbee_get_callback(FBEE_EV_DRAW); + if(cb) { + cb->func(cb->cls); + dirty = 0; + } + } + + if(!fbee_get_callback(FBEE_EV_IDLE)) { + if(SDL_WaitEvent(&ev)) { + SDL_PushEvent(&ev); + } + } + + while(SDL_PollEvent(&ev)) { + struct closure *cb; + + switch(ev.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + if((cb = fbee_get_callback(FBEE_EV_KEY))) { + int pressed = ev.key.state == SDL_PRESSED ? 1 : 0; + cb->func(ev.key.keysym.sym, pressed, cb->cls); + } + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if((cb = fbee_get_callback(FBEE_EV_BUTTON))) { + int pressed = ev.button.state == SDL_PRESSED ? 1 : 0; + int idx = ev.button.button - SDL_BUTTON_LEFT; + cb->func(idx, pressed, cb->cls); + } + break; + + case SDL_MOUSEMOTION: + if((cb = fbee_get_callback(FBEE_EV_MOTION))) { + cb->func(ev.motion.x, ev.motion.y, cb->cls); + } + break; + + case SDL_QUIT: + quit = 1; + return 0; + + default: + break; + } + } + return 1; +} + +void fbee_sys_evloop(void) +{ + while(!quit && fbee_sys_process_events()) { + struct closure *cb = fbee_get_callback(FBEE_EV_IDLE); + if(cb) { + cb->func(cb->cls); + } + } +} + +void fbee_redisplay(void) +{ + dirty = 1; +} + +void *fbee_sys_framebuffer(void) +{ + return fbsurf->pixels; +} + +void fbee_sys_update(void *img) +{ + if(img && img != fbsurf->pixels) { + if(SDL_MUSTLOCK(fbsurf)) { + SDL_LockSurface(fbsurf); + } + + memcpy(fbsurf->pixels, img, fbsurf->pitch * fbsurf->h); + + if(SDL_MUSTLOCK(fbsurf)) { + SDL_UnlockSurface(fbsurf); + } + } + + SDL_UpdateRect(fbsurf, 0, 0, 0, 0); +} diff -r 000000000000 -r 88a2049be27b test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test.c Tue Feb 05 13:40:36 2013 +0200 @@ -0,0 +1,68 @@ +#include +#include +#include +#include "fbee.h" + +void draw(void *cls); +void keyb(int key, int state, void *cls); +void mouse_button(int bn, int state, void *cls); +void mouse_motion(int x, int y, void *cls); + +int width = 640, height = 480, bpp = 32; +int mouse_x, mouse_y; +int bnstate[8]; + +int main(void) +{ + if(fbee_init() == -1) { + return 1; + } + + fbee_set_video_mode(width, height, bpp, 0); + fbee_get_video_mode(&width, &height, &bpp); + + printf("got video mode: %dx%d-%dbpp\n", width, height, bpp); + + fbee_event_func(FBEE_EV_DRAW, draw, 0); + fbee_event_func(FBEE_EV_KEY, keyb, 0); + fbee_event_func(FBEE_EV_BUTTON, mouse_button, 0); + fbee_event_func(FBEE_EV_MOTION, mouse_motion, 0); + + { + unsigned char *fb = fbee_framebuffer(); + memset(fb, 0x80, width * height * bpp / 8); + } + + fbee_evloop(); + return 0; +} + +void draw(void *cls) +{ + unsigned char *fb = fbee_framebuffer(); + if(bnstate[0]) { + fb[(mouse_y * width + mouse_x) * 4 + 1] = 255; + } + + fbee_update(0); +} + +void keyb(int key, int state, void *cls) +{ + if(key == 27) { + exit(0); + } +} + +void mouse_button(int bn, int state, void *cls) +{ + bnstate[bn] = state; + fbee_redisplay(); +} + +void mouse_motion(int x, int y, void *cls) +{ + mouse_x = x; + mouse_y = y; + fbee_redisplay(); +}