diff --git a/commands/splash.c b/commands/splash.c index 615b1cbc0..009c5a0a3 100644 --- a/commands/splash.c +++ b/commands/splash.c @@ -12,17 +12,20 @@ static int do_splash(int argc, char *argv[]) { + struct surface s; + struct screen sc; int ret, opt, fd; char *fbdev = "/dev/fb0"; - void *fb; struct fb_info info; char *image_file; - int startx = -1, starty = -1; - int xres, yres; int offscreen = 0; u32 bg_color = 0x00000000; bool do_bg = false; - void *offscreenbuf = NULL; + + s.x = -1; + s.y = -1; + s.width = -1; + s.height = -1; while((opt = getopt(argc, argv, "f:x:y:ob:")) > 0) { switch(opt) { @@ -34,10 +37,10 @@ static int do_splash(int argc, char *argv[]) do_bg = true; break; case 'x': - startx = simple_strtoul(optarg, NULL, 0); + s.x = simple_strtoul(optarg, NULL, 0); break; case 'y': - starty = simple_strtoul(optarg, NULL, 0); + s.y = simple_strtoul(optarg, NULL, 0); case 'o': offscreen = 1; } @@ -55,8 +58,8 @@ static int do_splash(int argc, char *argv[]) return 1; } - fb = memmap(fd, PROT_READ | PROT_WRITE); - if (fb == (void *)-1) { + sc.fb = memmap(fd, PROT_READ | PROT_WRITE); + if (sc.fb == (void *)-1) { perror("memmap"); goto failed_memmap; } @@ -67,33 +70,30 @@ static int do_splash(int argc, char *argv[]) goto failed_memmap; } - xres = info.xres; - yres = info.yres; - if (offscreen) { int fbsize; /* Don't fail if malloc fails, just continue rendering directly * on the framebuffer */ - fbsize = xres * yres * (info.bits_per_pixel >> 3); - offscreenbuf = malloc(fbsize); - if (offscreenbuf) { + fbsize = sc.s.x * sc.s.x * (sc.info.bits_per_pixel >> 3); + sc.offscreenbuf = malloc(fbsize); + if (sc.offscreenbuf) { if (do_bg) - memset_pixel(&info, offscreenbuf, bg_color, xres * yres); + memset_pixel(&info, sc.offscreenbuf, bg_color, + sc.s.width * sc.s.height); else - memcpy(offscreenbuf, fb, fbsize); + memcpy(sc.offscreenbuf, sc.fb, fbsize); } } else if (do_bg) { - memset_pixel(&info, fb, bg_color, xres * yres); + memset_pixel(&info, sc.fb, bg_color, sc.s.width * sc.s.height); } - if (image_renderer_file(&info, image_file, fb, startx, starty, - offscreenbuf) < 0) + if (image_renderer_file(&sc, &s, image_file) < 0) ret = 1; - if (offscreenbuf) - free(offscreenbuf); + if (sc.offscreenbuf) + free(sc.offscreenbuf); close(fd); diff --git a/include/gui/graphic_utils.h b/include/gui/graphic_utils.h index 4690e51e6..4cfb8e8d4 100644 --- a/include/gui/graphic_utils.h +++ b/include/gui/graphic_utils.h @@ -9,6 +9,7 @@ #include #include +#include void rgba_blend(struct fb_info *info, struct image *img, void* dest, int height, int width, int startx, int starty, bool is_rgba); @@ -16,5 +17,6 @@ void set_pixel(struct fb_info *info, void *adr, u32 px); void set_rgb_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b); void set_rgba_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b, u8 a); void memset_pixel(struct fb_info *info, void* buf, u32 color, size_t size); +int fb_open(const char * fbdev, struct screen *sc); #endif /* __GRAPHIC_UTILS_H__ */ diff --git a/include/gui/gui.h b/include/gui/gui.h new file mode 100644 index 000000000..2f792f101 --- /dev/null +++ b/include/gui/gui.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * GPL v2 + */ + +#ifndef __GUI_H__ +#define __GUI_H__ + +#include + +struct surface { + int x; + int y; + int width; + int height; +}; + +struct screen { + struct fb_info info; + + struct surface s; + + void *fb; + void *offscreenbuf; +}; + +static inline void* gui_screen_redering_buffer(struct screen *sc) +{ + if (sc->offscreenbuf) + return sc->offscreenbuf; + return sc->fb; +} + + +#endif /* __GUI_H__ */ diff --git a/include/gui/image_renderer.h b/include/gui/image_renderer.h index 5ee996944..e0b1eae25 100644 --- a/include/gui/image_renderer.h +++ b/include/gui/image_renderer.h @@ -13,13 +13,13 @@ #include #include #include +#include struct image_renderer { enum filetype type; struct image *(*open)(char *data, int size); void (*close)(struct image *img); - int (*renderer)(struct fb_info *info, struct image *img, void* fb, - int startx, int starty, void* offscreenbuf); + int (*renderer)(struct screen *sc, struct surface *s, struct image *img); /* * do not free the data read from the file @@ -34,8 +34,7 @@ struct image_renderer { int image_renderer_register(struct image_renderer *ir); void image_render_unregister(struct image_renderer *ir); -int image_renderer_image(struct fb_info *info, struct image *img, void* fb, - int startx, int starty, void* offscreenbuf); +int image_renderer_image(struct screen *sc, struct surface *s, struct image *img); struct image *image_renderer_open(const char* file); void image_renderer_close(struct image *img); @@ -54,12 +53,10 @@ static inline struct image *image_renderer_open(const char* file) static inline void image_renderer_close(struct image *img) {} -int image_renderer_image(struct fb_info *info, struct image *img, void* fb, - int startx, int starty, void* offscreenbuf); +int image_renderer_image(struct surface *s, struct image *img); #endif -static inline int image_renderer_file(struct fb_info *info, const char* file, void* fb, - int startx, int starty, void* offscreenbuf) +static inline int image_renderer_file(struct screen *sc, struct surface *s, const char* file) { struct image* img = image_renderer_open(file); int ret; @@ -67,8 +64,7 @@ static inline int image_renderer_file(struct fb_info *info, const char* file, vo if (IS_ERR(img)) return PTR_ERR(img); - ret = image_renderer_image(info, img, fb, startx, starty, - offscreenbuf); + ret = image_renderer_image(sc, s, img); image_renderer_close(img); diff --git a/lib/gui/bmp.c b/lib/gui/bmp.c index 86591edfd..63902ef73 100644 --- a/lib/gui/bmp.c +++ b/lib/gui/bmp.c @@ -34,38 +34,42 @@ void bmp_close(struct image *img) free(img->data); } -static int bmp_renderer(struct fb_info *info, struct image *img, void* fb, - int startx, int starty, void* offscreenbuf) +static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img) { struct bmp_image *bmp = img->data; - int width, height; int bits_per_pixel, fbsize; void *adr, *buf; char *image; - int xres, yres; + int width = s->width; + int height = s->height; + int startx = s->x; + int starty = s->y; - xres = info->xres; - yres = info->yres; + if (s->width < 0) + width = img->width; + + if (s->height < 0) + height = img->height; if (startx < 0) { - startx = (xres - img->width) / 2; + startx = (sc->s.width - width) / 2; if (startx < 0) startx = 0; } if (starty < 0) { - starty = (yres - img->height) / 2; + starty = (sc->s.height - height) / 2; if (starty < 0) starty = 0; } - width = min(img->width, xres - startx); - height = min(img->height, yres - starty); + width = min(width, sc->s.width - startx); + height = min(height, sc->s.height - starty); + + buf = gui_screen_redering_buffer(sc); bits_per_pixel = img->bits_per_pixel; - fbsize = xres * yres * (info->bits_per_pixel >> 3); - - buf = offscreenbuf ? offscreenbuf : fb; + fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3); if (bits_per_pixel == 8) { int x, y; @@ -75,17 +79,17 @@ static int bmp_renderer(struct fb_info *info, struct image *img, void* fb, image = (char *)bmp + le32_to_cpu(bmp->header.data_offset); image += (img->height - y - 1) * img->width * (bits_per_pixel >> 3); - adr = buf + ((y + starty) * xres + startx) * - (info->bits_per_pixel >> 3); + adr = buf + ((y + starty) * sc->s.width + startx) * + (sc->info.bits_per_pixel >> 3); for (x = 0; x < width; x++) { int pixel; pixel = *image; - set_rgb_pixel(info, adr, color_table[pixel].red, + set_rgb_pixel(&sc->info, adr, color_table[pixel].red, color_table[pixel].green, color_table[pixel].blue); - adr += info->bits_per_pixel >> 3; + adr += sc->info.bits_per_pixel >> 3; image += bits_per_pixel >> 3; } @@ -97,16 +101,16 @@ static int bmp_renderer(struct fb_info *info, struct image *img, void* fb, image = (char *)bmp + le32_to_cpu(bmp->header.data_offset); image += (img->height - y - 1) * img->width * (bits_per_pixel >> 3); - adr = buf + ((y + starty) * xres + startx) * - (info->bits_per_pixel >> 3); + adr = buf + ((y + starty) * sc->s.width + startx) * + (sc->info.bits_per_pixel >> 3); for (x = 0; x < width; x++) { char *pixel; pixel = image; - set_rgb_pixel(info, adr, pixel[2], pixel[1], + set_rgb_pixel(&sc->info, adr, pixel[2], pixel[1], pixel[0]); - adr += info->bits_per_pixel >> 3; + adr += sc->info.bits_per_pixel >> 3; image += bits_per_pixel >> 3; } @@ -114,8 +118,8 @@ static int bmp_renderer(struct fb_info *info, struct image *img, void* fb, } else printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel); - if (offscreenbuf) - memcpy(fb, offscreenbuf, fbsize); + if (sc->offscreenbuf) + memcpy(sc->fb, sc->offscreenbuf, fbsize); return img->height; } diff --git a/lib/gui/image_renderer.c b/lib/gui/image_renderer.c index 99e4335d0..41dc43b3c 100644 --- a/lib/gui/image_renderer.c +++ b/lib/gui/image_renderer.c @@ -71,10 +71,9 @@ void image_renderer_close(struct image *img) free(img); } -int image_renderer_image(struct fb_info *info, struct image *img, void* fb, - int startx, int starty, void* offscreenbuf) +int image_renderer_image(struct screen *sc, struct surface *s, struct image *img) { - return img->ir->renderer(info, img, fb, startx, starty, offscreenbuf); + return img->ir->renderer(sc, s, img); } int image_renderer_register(struct image_renderer *ir) diff --git a/lib/gui/png.c b/lib/gui/png.c index 1e9efd529..3845d7e4b 100644 --- a/lib/gui/png.c +++ b/lib/gui/png.c @@ -36,40 +36,44 @@ void png_uncompress_exit(void) } } -static int png_renderer(struct fb_info *info, struct image *img, void* fb, - int startx, int starty, void* offscreenbuf) +static int png_renderer(struct screen *sc, struct surface *s, struct image *img) { - int width, height; void *buf; - int xres, yres; + int width = s->width; + int height = s->height; + int startx = s->x; + int starty = s->y; - xres = info->xres; - yres = info->yres; + if (s->width < 0) + width = img->width; + + if (s->height < 0) + height = img->height; if (startx < 0) { - startx = (xres - img->width) / 2; + startx = (sc->s.width - width) / 2; if (startx < 0) startx = 0; } if (starty < 0) { - starty = (yres - img->height) / 2; + starty = (sc->s.height - height) / 2; if (starty < 0) starty = 0; } - width = min(img->width, xres - startx); - height = min(img->height, yres - starty); + width = min(width, sc->s.width - startx); + height = min(height, sc->s.height - starty); - buf = offscreenbuf ? offscreenbuf : fb; + buf = gui_screen_redering_buffer(sc); - rgba_blend(info, img, buf, height, width, startx, starty, true); + rgba_blend(&sc->info, img, buf, height, width, startx, starty, true); - if (offscreenbuf) { + if (sc->offscreenbuf) { int fbsize; - fbsize = xres * yres * (info->bits_per_pixel >> 3); - memcpy(fb, offscreenbuf, fbsize); + fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3); + memcpy(sc->fb, sc->offscreenbuf, fbsize); } return img->height;