fbee

changeset 0:88a2049be27b

fbee initial
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 05 Feb 2013 13:40:36 +0200
parents
children 2471e9b63432
files src/fbee.c src/fbee.h src/fbeeimpl.h src/sys_sdl.c test.c
diffstat 5 files changed, 343 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/fbee.c	Tue Feb 05 13:40:36 2013 +0200
     1.3 @@ -0,0 +1,63 @@
     1.4 +#include <string.h>
     1.5 +#include "fbee.h"
     1.6 +#include "fbeeimpl.h"
     1.7 +
     1.8 +static struct closure evfunc[NUM_FBEE_EVENTS];
     1.9 +
    1.10 +int fbee_init(void)
    1.11 +{
    1.12 +	memset(evfunc, 0, sizeof evfunc);
    1.13 +
    1.14 +	return fbee_sys_init();
    1.15 +}
    1.16 +
    1.17 +void fbee_destroy(void)
    1.18 +{
    1.19 +	fbee_sys_destroy();
    1.20 +}
    1.21 +
    1.22 +int fbee_set_video_mode(int width, int height, int bpp, unsigned int flags)
    1.23 +{
    1.24 +	return fbee_sys_set_video(width, height, bpp, flags);
    1.25 +}
    1.26 +
    1.27 +int fbee_get_video_mode(int *width, int *height, int *bpp)
    1.28 +{
    1.29 +	return fbee_sys_get_video(width, height, bpp);
    1.30 +}
    1.31 +
    1.32 +void fbee_event_func(int evtype, void (*func)(), void *cls)
    1.33 +{
    1.34 +	evfunc[evtype].func = func;
    1.35 +	evfunc[evtype].cls = cls;
    1.36 +}
    1.37 +
    1.38 +int fbee_process_events(void)
    1.39 +{
    1.40 +	return fbee_sys_process_events();
    1.41 +}
    1.42 +
    1.43 +void fbee_evloop(void)
    1.44 +{
    1.45 +	fbee_sys_evloop();
    1.46 +}
    1.47 +
    1.48 +void *fbee_framebuffer(void)
    1.49 +{
    1.50 +	return fbee_sys_framebuffer();
    1.51 +}
    1.52 +
    1.53 +void fbee_update(void *img)
    1.54 +{
    1.55 +	fbee_sys_update(img);
    1.56 +}
    1.57 +
    1.58 +
    1.59 +struct closure *fbee_get_callback(int ev)
    1.60 +{
    1.61 +	if(ev < 0 || ev >= NUM_FBEE_EVENTS) {
    1.62 +		return 0;
    1.63 +	}
    1.64 +
    1.65 +	return evfunc[ev].func ? evfunc + ev : 0;
    1.66 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/fbee.h	Tue Feb 05 13:40:36 2013 +0200
     2.3 @@ -0,0 +1,57 @@
     2.4 +#ifndef FBEE_H_
     2.5 +#define FBEE_H_
     2.6 +
     2.7 +enum {
     2.8 +	FBEE_EV_DRAW,
     2.9 +	FBEE_EV_RESIZE,
    2.10 +	FBEE_EV_KEY,
    2.11 +	FBEE_EV_BUTTON,
    2.12 +	FBEE_EV_MOTION,
    2.13 +	FBEE_EV_IDLE,
    2.14 +
    2.15 +	NUM_FBEE_EVENTS
    2.16 +};
    2.17 +
    2.18 +/* callback prototypes:
    2.19 + *
    2.20 + * void draw_callback(void *cls);
    2.21 + * void resize_callback(int x, int y, void *cls);
    2.22 + * void keyb_callback(int key, int state, void *cls);
    2.23 + * void button_callback(int bn, int state, void *cls);
    2.24 + * void motion_callback(int x, int y, void *cls);
    2.25 + * void idle_callback(void *cls);
    2.26 + */
    2.27 +
    2.28 +#ifdef __cplusplus
    2.29 +extern "C" {
    2.30 +#endif
    2.31 +
    2.32 +int fbee_init(void);
    2.33 +void fbee_destroy(void);
    2.34 +
    2.35 +int fbee_set_video_mode(int width, int height, int bpp, unsigned int flags);
    2.36 +int fbee_get_video_mode(int *width, int *height, int *bpp);
    2.37 +
    2.38 +/* register an event callback */
    2.39 +void fbee_event_func(int evtype, void (*func)(), void *cls);
    2.40 +
    2.41 +/* run a single iteration of the event loop and return */
    2.42 +int fbee_process_events(void);
    2.43 +
    2.44 +/* start event processing (never returns) */
    2.45 +void fbee_evloop(void);
    2.46 +
    2.47 +/* signal fbee to redraw the window */
    2.48 +void fbee_redisplay(void);
    2.49 +
    2.50 +/* get a pointer to the framebuffer */
    2.51 +void *fbee_framebuffer(void);
    2.52 +
    2.53 +/* copy an image to the framebuffer (size and format must match) */
    2.54 +void fbee_update(void *img);
    2.55 +
    2.56 +#ifdef __cplusplus
    2.57 +}
    2.58 +#endif
    2.59 +
    2.60 +#endif	/* FBEE_H_ */
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/fbeeimpl.h	Tue Feb 05 13:40:36 2013 +0200
     3.3 @@ -0,0 +1,21 @@
     3.4 +#ifndef FBEEIMPL_H_
     3.5 +#define FBEEIMPL_H_
     3.6 +
     3.7 +struct closure {
     3.8 +	void (*func)();
     3.9 +	void *cls;
    3.10 +};
    3.11 +
    3.12 +/* functions implemented by each graphics system module */
    3.13 +int fbee_sys_init(void);
    3.14 +void fbee_sys_destroy(void);
    3.15 +int fbee_sys_set_video(int width, int height, int bpp, unsigned int flags);
    3.16 +int fbee_sys_get_video(int *width, int *height, int *bpp);
    3.17 +int fbee_sys_process_events(void);
    3.18 +void fbee_sys_evloop(void);
    3.19 +void *fbee_sys_framebuffer(void);
    3.20 +void fbee_sys_update(void *img);
    3.21 +
    3.22 +struct closure *fbee_get_callback(int evtype);
    3.23 +
    3.24 +#endif	/* FBEEIMPL_H_ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/sys_sdl.c	Tue Feb 05 13:40:36 2013 +0200
     4.3 @@ -0,0 +1,134 @@
     4.4 +#include <SDL/SDL.h>
     4.5 +#include "fbee.h"
     4.6 +#include "fbeeimpl.h"
     4.7 +
     4.8 +static int quit, dirty;
     4.9 +static SDL_Surface *fbsurf;
    4.10 +
    4.11 +int fbee_sys_init(void)
    4.12 +{
    4.13 +	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
    4.14 +	quit = 0;
    4.15 +	dirty = 1;
    4.16 +	return 0;
    4.17 +}
    4.18 +
    4.19 +int fbee_sys_set_video(int width, int height, int bpp, unsigned int flags)
    4.20 +{
    4.21 +	unsigned int sdl_flags = SDL_HWSURFACE;
    4.22 +	if(!(fbsurf = SDL_SetVideoMode(width, height, bpp, sdl_flags))) {
    4.23 +		fprintf(stderr, "failed to set video mode\n");
    4.24 +		return -1;
    4.25 +	}
    4.26 +	SDL_WM_SetCaption("fbee", "fbee");
    4.27 +	return 0;
    4.28 +}
    4.29 +
    4.30 +int fbee_sys_get_video(int *width, int *height, int *bpp)
    4.31 +{
    4.32 +	if(fbsurf) {
    4.33 +		*width = fbsurf->w;
    4.34 +		*height = fbsurf->h;
    4.35 +		*bpp = fbsurf->format->BitsPerPixel;
    4.36 +		return 0;
    4.37 +	}
    4.38 +	return -1;
    4.39 +}
    4.40 +
    4.41 +void fbee_sys_destroy(void)
    4.42 +{
    4.43 +	SDL_Quit();
    4.44 +}
    4.45 +
    4.46 +int fbee_sys_process_events(void)
    4.47 +{
    4.48 +	SDL_Event ev;
    4.49 +
    4.50 +	if(dirty) {
    4.51 +		struct closure *cb = fbee_get_callback(FBEE_EV_DRAW);
    4.52 +		if(cb) {
    4.53 +			cb->func(cb->cls);
    4.54 +			dirty = 0;
    4.55 +		}
    4.56 +	}
    4.57 +
    4.58 +	if(!fbee_get_callback(FBEE_EV_IDLE)) {
    4.59 +		if(SDL_WaitEvent(&ev)) {
    4.60 +			SDL_PushEvent(&ev);
    4.61 +		}
    4.62 +	}
    4.63 +
    4.64 +	while(SDL_PollEvent(&ev)) {
    4.65 +		struct closure *cb;
    4.66 +
    4.67 +		switch(ev.type) {
    4.68 +		case SDL_KEYDOWN:
    4.69 +		case SDL_KEYUP:
    4.70 +			if((cb = fbee_get_callback(FBEE_EV_KEY))) {
    4.71 +				int pressed = ev.key.state == SDL_PRESSED ? 1 : 0;
    4.72 +				cb->func(ev.key.keysym.sym, pressed, cb->cls);
    4.73 +			}
    4.74 +			break;
    4.75 +
    4.76 +		case SDL_MOUSEBUTTONDOWN:
    4.77 +		case SDL_MOUSEBUTTONUP:
    4.78 +			if((cb = fbee_get_callback(FBEE_EV_BUTTON))) {
    4.79 +				int pressed = ev.button.state == SDL_PRESSED ? 1 : 0;
    4.80 +				int idx = ev.button.button - SDL_BUTTON_LEFT;
    4.81 +				cb->func(idx, pressed, cb->cls);
    4.82 +			}
    4.83 +			break;
    4.84 +
    4.85 +		case SDL_MOUSEMOTION:
    4.86 +			if((cb = fbee_get_callback(FBEE_EV_MOTION))) {
    4.87 +				cb->func(ev.motion.x, ev.motion.y, cb->cls);
    4.88 +			}
    4.89 +			break;
    4.90 +
    4.91 +		case SDL_QUIT:
    4.92 +			quit = 1;
    4.93 +			return 0;
    4.94 +
    4.95 +		default:
    4.96 +			break;
    4.97 +		}
    4.98 +	}
    4.99 +	return 1;
   4.100 +}
   4.101 +
   4.102 +void fbee_sys_evloop(void)
   4.103 +{
   4.104 +	while(!quit && fbee_sys_process_events()) {
   4.105 +		struct closure *cb = fbee_get_callback(FBEE_EV_IDLE);
   4.106 +		if(cb) {
   4.107 +			cb->func(cb->cls);
   4.108 +		}
   4.109 +	}
   4.110 +}
   4.111 +
   4.112 +void fbee_redisplay(void)
   4.113 +{
   4.114 +	dirty = 1;
   4.115 +}
   4.116 +
   4.117 +void *fbee_sys_framebuffer(void)
   4.118 +{
   4.119 +	return fbsurf->pixels;
   4.120 +}
   4.121 +
   4.122 +void fbee_sys_update(void *img)
   4.123 +{
   4.124 +	if(img && img != fbsurf->pixels) {
   4.125 +		if(SDL_MUSTLOCK(fbsurf)) {
   4.126 +			SDL_LockSurface(fbsurf);
   4.127 +		}
   4.128 +
   4.129 +		memcpy(fbsurf->pixels, img, fbsurf->pitch * fbsurf->h);
   4.130 +
   4.131 +		if(SDL_MUSTLOCK(fbsurf)) {
   4.132 +			SDL_UnlockSurface(fbsurf);
   4.133 +		}
   4.134 +	}
   4.135 +
   4.136 +	SDL_UpdateRect(fbsurf, 0, 0, 0, 0);
   4.137 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test.c	Tue Feb 05 13:40:36 2013 +0200
     5.3 @@ -0,0 +1,68 @@
     5.4 +#include <stdio.h>
     5.5 +#include <stdlib.h>
     5.6 +#include <string.h>
     5.7 +#include "fbee.h"
     5.8 +
     5.9 +void draw(void *cls);
    5.10 +void keyb(int key, int state, void *cls);
    5.11 +void mouse_button(int bn, int state, void *cls);
    5.12 +void mouse_motion(int x, int y, void *cls);
    5.13 +
    5.14 +int width = 640, height = 480, bpp = 32;
    5.15 +int mouse_x, mouse_y;
    5.16 +int bnstate[8];
    5.17 +
    5.18 +int main(void)
    5.19 +{
    5.20 +	if(fbee_init() == -1) {
    5.21 +		return 1;
    5.22 +	}
    5.23 +
    5.24 +	fbee_set_video_mode(width, height, bpp, 0);
    5.25 +	fbee_get_video_mode(&width, &height, &bpp);
    5.26 +
    5.27 +	printf("got video mode: %dx%d-%dbpp\n", width, height, bpp);
    5.28 +
    5.29 +	fbee_event_func(FBEE_EV_DRAW, draw, 0);
    5.30 +	fbee_event_func(FBEE_EV_KEY, keyb, 0);
    5.31 +	fbee_event_func(FBEE_EV_BUTTON, mouse_button, 0);
    5.32 +	fbee_event_func(FBEE_EV_MOTION, mouse_motion, 0);
    5.33 +
    5.34 +	{
    5.35 +		unsigned char *fb = fbee_framebuffer();
    5.36 +		memset(fb, 0x80, width * height * bpp / 8);
    5.37 +	}
    5.38 +
    5.39 +	fbee_evloop();
    5.40 +	return 0;
    5.41 +}
    5.42 +
    5.43 +void draw(void *cls)
    5.44 +{
    5.45 +	unsigned char *fb = fbee_framebuffer();
    5.46 +	if(bnstate[0]) {
    5.47 +		fb[(mouse_y * width + mouse_x) * 4 + 1] = 255;
    5.48 +	}
    5.49 +
    5.50 +	fbee_update(0);
    5.51 +}
    5.52 +
    5.53 +void keyb(int key, int state, void *cls)
    5.54 +{
    5.55 +	if(key == 27) {
    5.56 +		exit(0);
    5.57 +	}
    5.58 +}
    5.59 +
    5.60 +void mouse_button(int bn, int state, void *cls)
    5.61 +{
    5.62 +	bnstate[bn] = state;
    5.63 +	fbee_redisplay();
    5.64 +}
    5.65 +
    5.66 +void mouse_motion(int x, int y, void *cls)
    5.67 +{
    5.68 +	mouse_x = x;
    5.69 +	mouse_y = y;
    5.70 +	fbee_redisplay();
    5.71 +}