* [PATCH 2/6] gui: move gui file to include/gui and lib/gui
  2012-09-26  9:58 ` [PATCH 1/6] image_renderer: fix size type Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-26  9:59   ` Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 3/6] graphic_utils: pass image so we can draw only the visible part of the image Jean-Christophe PLAGNIOL-VILLARD
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-26  9:59 UTC (permalink / raw)
  To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 commands/Kconfig                   |   23 +++++++++++++--------
 commands/splash.c                  |    4 ++--
 drivers/video/sdl.c                |    2 +-
 include/{ => gui}/graphic_utils.h  |    0
 include/gui/image.h                |   20 ++++++++++++++++++
 include/{ => gui}/image_renderer.h |    9 +--------
 lib/Kconfig                        |   36 +--------------------------------
 lib/Makefile                       |    6 +-----
 lib/gui/Kconfig                    |   39 ++++++++++++++++++++++++++++++++++++
 lib/gui/Makefile                   |    5 +++++
 lib/{ => gui}/bmp.c                |    4 ++--
 lib/{ => gui}/bmp_layout.h         |    0
 lib/{ => gui}/graphic_utils.c      |    2 +-
 lib/{ => gui}/image_renderer.c     |    2 +-
 lib/{ => gui}/lodepng.c            |    0
 lib/{ => gui}/lodepng.h            |    0
 lib/{ => gui}/picopng.c            |    0
 lib/{ => gui}/picopng.h            |    0
 lib/{ => gui}/png.c                |    4 ++--
 lib/{ => gui}/png.h                |    0
 lib/{ => gui}/png_lode.c           |    4 ++--
 lib/{ => gui}/png_pico.c           |    4 ++--
 22 files changed, 95 insertions(+), 69 deletions(-)
 rename include/{ => gui}/graphic_utils.h (100%)
 create mode 100644 include/gui/image.h
 rename include/{ => gui}/image_renderer.h (94%)
 create mode 100644 lib/gui/Kconfig
 create mode 100644 lib/gui/Makefile
 rename lib/{ => gui}/bmp.c (97%)
 rename lib/{ => gui}/bmp_layout.h (100%)
 rename lib/{ => gui}/graphic_utils.c (99%)
 rename lib/{ => gui}/image_renderer.c (98%)
 rename lib/{ => gui}/lodepng.c (100%)
 rename lib/{ => gui}/lodepng.h (100%)
 rename lib/{ => gui}/picopng.c (100%)
 rename lib/{ => gui}/picopng.h (100%)
 rename lib/{ => gui}/png.c (96%)
 rename lib/{ => gui}/png.h (100%)
 rename lib/{ => gui}/png_lode.c (96%)
 rename lib/{ => gui}/png_pico.c (96%)
diff --git a/commands/Kconfig b/commands/Kconfig
index 930a9b1..17fa6c9 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -486,6 +486,21 @@ config CMD_MTEST_ALTERNATIVE
 
 endmenu
 
+menu "video command                  "
+
+if VIDEO
+
+config CMD_SPLASH
+	bool
+	select IMAGE_RENDERER
+	prompt "splash"
+	help
+	  show bmp files on framebuffer devices
+
+endif
+
+endmenu
+
 config CMD_TIMEOUT
 	tristate
 	prompt "timeout"
@@ -549,14 +564,6 @@ config CMD_LSMOD
 	depends on MODULES
 	prompt "lsmod"
 
-config CMD_SPLASH
-	bool
-	depends on VIDEO
-	select IMAGE_RENDERER
-	prompt "splash"
-	help
-	  show bmp files on framebuffer devices
-
 config CMD_GPIO
 	bool
 	depends on GENERIC_GPIO
diff --git a/commands/splash.c b/commands/splash.c
index f40e3e1..615b1cb 100644
--- a/commands/splash.c
+++ b/commands/splash.c
@@ -7,8 +7,8 @@
 #include <getopt.h>
 #include <fcntl.h>
 #include <fb.h>
-#include <image_renderer.h>
-#include <graphic_utils.h>
+#include <gui/image_renderer.h>
+#include <gui/graphic_utils.h>
 
 static int do_splash(int argc, char *argv[])
 {
diff --git a/drivers/video/sdl.c b/drivers/video/sdl.c
index ed083d7..d50aed9 100644
--- a/drivers/video/sdl.c
+++ b/drivers/video/sdl.c
@@ -11,7 +11,7 @@
 #include <mach/linux.h>
 #include <fb.h>
 #include <errno.h>
-#include <graphic_utils.h>
+#include <gui/graphic_utils.h>
 
 static void sdlfb_enable(struct fb_info *info)
 {
diff --git a/include/graphic_utils.h b/include/gui/graphic_utils.h
similarity index 100%
rename from include/graphic_utils.h
rename to include/gui/graphic_utils.h
diff --git a/include/gui/image.h b/include/gui/image.h
new file mode 100644
index 0000000..ea423b2
--- /dev/null
+++ b/include/gui/image.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * GPL v2
+ */
+
+#ifndef __GUI_IMAGE_H__
+#define __GUI_IMAGE_H__
+
+struct image_renderer;
+
+struct image {
+	void *data;
+	struct image_renderer *ir;
+	int height;
+	int width;
+	int bits_per_pixel;
+};
+
+#endif /* __IMAGE_RENDERER_H__ */
diff --git a/include/image_renderer.h b/include/gui/image_renderer.h
similarity index 94%
rename from include/image_renderer.h
rename to include/gui/image_renderer.h
index 0b686e1..5ee9969 100644
--- a/include/image_renderer.h
+++ b/include/gui/image_renderer.h
@@ -12,14 +12,7 @@
 #include <errno.h>
 #include <linux/err.h>
 #include <fb.h>
-
-struct image {
-	void *data;
-	struct image_renderer *ir;
-	int height;
-	int width;
-	int bits_per_pixel;
-};
+#include <gui/image.h>
 
 struct image_renderer {
 	enum filetype type;
diff --git a/lib/Kconfig b/lib/Kconfig
index 8b73733..9882d2d 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -38,40 +38,6 @@ config BITREV
 config QSORT
 	bool
 
-config IMAGE_RENDERER
-	bool
-	depends on VIDEO
-	select FILETYPE
-
-if IMAGE_RENDERER
-
-config BMP
-	bool "bmp"
-
-config PNG
-	bool "png"
-	select ZLIB
-
-if PNG
-
-choice
-	prompt "PNG Lib"
-
-config LODEPNG
-	bool "lodePNG"
-	help
-	  This PNG library supports most PNG formats.
-
-config PICOPNG
-	bool "picoPNG"
-	help
-	  This PNG library only supports RGBA PNG8 but is much smaller
-	  in binary size than lodepng.
-
-endchoice
-
-endif
-
-endif
+source lib/gui/Kconfig
 
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 7bce0e5..41e6a0f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,8 +34,4 @@ obj-$(CONFIG_UNCOMPRESS)	+= uncompress.o
 obj-$(CONFIG_BCH)	+= bch.o
 obj-$(CONFIG_BITREV)	+= bitrev.o
 obj-$(CONFIG_QSORT)	+= qsort.o
-obj-$(CONFIG_BMP)	+= bmp.o
-obj-$(CONFIG_IMAGE_RENDERER)	+= image_renderer.o graphic_utils.o
-obj-$(CONFIG_PNG)	+= png.o
-obj-$(CONFIG_LODEPNG)	+= png_lode.o lodepng.o
-obj-$(CONFIG_PICOPNG)	+= png_pico.o picopng.o
+obj-y			+= gui/
diff --git a/lib/gui/Kconfig b/lib/gui/Kconfig
new file mode 100644
index 0000000..8fd12fb
--- /dev/null
+++ b/lib/gui/Kconfig
@@ -0,0 +1,39 @@
+menu "Library gui routines           "
+
+config IMAGE_RENDERER
+	bool
+	depends on VIDEO
+	select FILETYPE
+
+if IMAGE_RENDERER
+
+config BMP
+	bool "bmp"
+
+config PNG
+	bool "png"
+	select ZLIB
+
+if PNG
+
+choice
+	prompt "PNG Lib"
+
+config LODEPNG
+	bool "lodePNG"
+	help
+	  This PNG library supports most PNG formats.
+
+config PICOPNG
+	bool "picoPNG"
+	help
+	  This PNG library only supports RGBA PNG8 but is much smaller
+	  in binary size than lodepng.
+
+endchoice
+
+endif
+
+endif
+
+endmenu
diff --git a/lib/gui/Makefile b/lib/gui/Makefile
new file mode 100644
index 0000000..d4b26c4
--- /dev/null
+++ b/lib/gui/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_BMP)	+= bmp.o
+obj-$(CONFIG_IMAGE_RENDERER)	+= image_renderer.o graphic_utils.o
+obj-$(CONFIG_PNG)	+= png.o
+obj-$(CONFIG_LODEPNG)	+= png_lode.o lodepng.o
+obj-$(CONFIG_PICOPNG)	+= png_pico.o picopng.o
diff --git a/lib/bmp.c b/lib/gui/bmp.c
similarity index 97%
rename from lib/bmp.c
rename to lib/gui/bmp.c
index f5c1961..86591ed 100644
--- a/lib/bmp.c
+++ b/lib/gui/bmp.c
@@ -4,9 +4,9 @@
 #include <fb.h>
 #include "bmp_layout.h"
 #include <asm/byteorder.h>
-#include <graphic_utils.h>
+#include <gui/graphic_utils.h>
 #include <init.h>
-#include <image_renderer.h>
+#include <gui/image_renderer.h>
 
 struct image *bmp_open(char *inbuf, int insize)
 {
diff --git a/lib/bmp_layout.h b/lib/gui/bmp_layout.h
similarity index 100%
rename from lib/bmp_layout.h
rename to lib/gui/bmp_layout.h
diff --git a/lib/graphic_utils.c b/lib/gui/graphic_utils.c
similarity index 99%
rename from lib/graphic_utils.c
rename to lib/gui/graphic_utils.c
index a435bdd..bf42103 100644
--- a/lib/graphic_utils.c
+++ b/lib/gui/graphic_utils.c
@@ -1,6 +1,6 @@
 #include <common.h>
 #include <fb.h>
-#include <graphic_utils.h>
+#include <gui/graphic_utils.h>
 
 static u32 get_pixel(struct fb_info *info, u32 color)
 {
diff --git a/lib/image_renderer.c b/lib/gui/image_renderer.c
similarity index 98%
rename from lib/image_renderer.c
rename to lib/gui/image_renderer.c
index fff35bd..99e4335 100644
--- a/lib/image_renderer.c
+++ b/lib/gui/image_renderer.c
@@ -6,7 +6,7 @@
 
 #include <common.h>
 #include <fb.h>
-#include <image_renderer.h>
+#include <gui/image_renderer.h>
 #include <errno.h>
 #include <fs.h>
 #include <malloc.h>
diff --git a/lib/lodepng.c b/lib/gui/lodepng.c
similarity index 100%
rename from lib/lodepng.c
rename to lib/gui/lodepng.c
diff --git a/lib/lodepng.h b/lib/gui/lodepng.h
similarity index 100%
rename from lib/lodepng.h
rename to lib/gui/lodepng.h
diff --git a/lib/picopng.c b/lib/gui/picopng.c
similarity index 100%
rename from lib/picopng.c
rename to lib/gui/picopng.c
diff --git a/lib/picopng.h b/lib/gui/picopng.h
similarity index 100%
rename from lib/picopng.h
rename to lib/gui/picopng.h
diff --git a/lib/png.c b/lib/gui/png.c
similarity index 96%
rename from lib/png.c
rename to lib/gui/png.c
index f71fc6a..5d77c8c 100644
--- a/lib/png.c
+++ b/lib/gui/png.c
@@ -4,8 +4,8 @@
 #include <fb.h>
 #include <asm/byteorder.h>
 #include <init.h>
-#include <image_renderer.h>
-#include <graphic_utils.h>
+#include <gui/image_renderer.h>
+#include <gui/graphic_utils.h>
 #include <linux/zlib.h>
 
 #include "png.h"
diff --git a/lib/png.h b/lib/gui/png.h
similarity index 100%
rename from lib/png.h
rename to lib/gui/png.h
diff --git a/lib/png_lode.c b/lib/gui/png_lode.c
similarity index 96%
rename from lib/png_lode.c
rename to lib/gui/png_lode.c
index 4b57f6a..477704d 100644
--- a/lib/png_lode.c
+++ b/lib/gui/png_lode.c
@@ -4,8 +4,8 @@
 #include <fb.h>
 #include <asm/byteorder.h>
 #include <init.h>
-#include <image_renderer.h>
-#include <graphic_utils.h>
+#include <gui/image_renderer.h>
+#include <gui/graphic_utils.h>
 #include <linux/zlib.h>
 
 #include "lodepng.h"
diff --git a/lib/png_pico.c b/lib/gui/png_pico.c
similarity index 96%
rename from lib/png_pico.c
rename to lib/gui/png_pico.c
index a0127f7..393a732 100644
--- a/lib/png_pico.c
+++ b/lib/gui/png_pico.c
@@ -4,8 +4,8 @@
 #include <fb.h>
 #include <asm/byteorder.h>
 #include <init.h>
-#include <image_renderer.h>
-#include <graphic_utils.h>
+#include <gui/image_renderer.h>
+#include <gui/graphic_utils.h>
 #include <linux/zlib.h>
 
 #include "picopng.h"
-- 
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply	[flat|nested] 13+ messages in thread* [PATCH 3/6] graphic_utils: pass image so we can draw only the visible part of the image
  2012-09-26  9:58 ` [PATCH 1/6] image_renderer: fix size type Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 2/6] gui: move gui file to include/gui and lib/gui Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-26  9:59   ` Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 4/6] gui: introduce screen and surface to factorize and simplify code Jean-Christophe PLAGNIOL-VILLARD
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-26  9:59 UTC (permalink / raw)
  To: barebox
This is needed if the image is bigger than the screen.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 include/gui/graphic_utils.h |    5 ++++-
 lib/gui/graphic_utils.c     |    7 ++++---
 lib/gui/png.c               |    2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/include/gui/graphic_utils.h b/include/gui/graphic_utils.h
index 9909b6c..4690e51 100644
--- a/include/gui/graphic_utils.h
+++ b/include/gui/graphic_utils.h
@@ -7,7 +7,10 @@
 #ifndef __GRAPHIC_UTILS_H__
 #define __GRAPHIC_UTILS_H__
 
-void rgba_blend(struct fb_info *info, void *image, void* dest, int height,
+#include <fb.h>
+#include <gui/image.h>
+
+void rgba_blend(struct fb_info *info, struct image *img, void* dest, int height,
 	int width, int startx, int starty, bool is_rgba);
 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);
diff --git a/lib/gui/graphic_utils.c b/lib/gui/graphic_utils.c
index bf42103..06f811c 100644
--- a/lib/gui/graphic_utils.c
+++ b/lib/gui/graphic_utils.c
@@ -157,13 +157,14 @@ void set_rgba_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b, u8 a)
 	set_pixel(info, adr, px);
 }
 
-void rgba_blend(struct fb_info *info, void *image, void* buf, int height,
+void rgba_blend(struct fb_info *info, struct image *img, void* buf, int height,
 	int width, int startx, int starty, bool is_rgba)
 {
 	unsigned char *adr;
 	int x, y;
 	int xres;
 	int img_byte_per_pixel = 3;
+	void *image;
 
 	if (is_rgba)
 		img_byte_per_pixel++;
@@ -173,11 +174,11 @@ void rgba_blend(struct fb_info *info, void *image, void* buf, int height,
 	for (y = 0; y < height; y++) {
 		adr = buf + ((y + starty) * xres + startx) *
 				(info->bits_per_pixel >> 3);
+		image = img->data + (y * img->width *img_byte_per_pixel);
 
 		for (x = 0; x < width; x++) {
-			char *pixel;
+			uint8_t *pixel = image;
 
-			pixel = image;
 			if (is_rgba)
 				set_rgba_pixel(info, adr, pixel[0], pixel[1],
 						pixel[2], pixel[3]);
diff --git a/lib/gui/png.c b/lib/gui/png.c
index 5d77c8c..1e9efd5 100644
--- a/lib/gui/png.c
+++ b/lib/gui/png.c
@@ -63,7 +63,7 @@ static int png_renderer(struct fb_info *info, struct image *img, void* fb,
 
 	buf = offscreenbuf ? offscreenbuf : fb;
 
-	rgba_blend(info, img->data, buf, height, width, startx, starty, true);
+	rgba_blend(info, img, buf, height, width, startx, starty, true);
 
 	if (offscreenbuf) {
 		int fbsize;
-- 
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply	[flat|nested] 13+ messages in thread* [PATCH 4/6] gui: introduce screen and surface to factorize and simplify code
  2012-09-26  9:58 ` [PATCH 1/6] image_renderer: fix size type Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 2/6] gui: move gui file to include/gui and lib/gui Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 3/6] graphic_utils: pass image so we can draw only the visible part of the image Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-26  9:59   ` Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 5/6] graphic_utils: introduce common fb_open/close Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 6/6] gui: blit the surface on demand Jean-Christophe PLAGNIOL-VILLARD
  4 siblings, 0 replies; 13+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-26  9:59 UTC (permalink / raw)
  To: barebox
Instead of passing hundreds of parameter, just pass the right structure.
struct screen represent the screen with a without double buffering.
struct surface represent the part of the screen we want to render.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 commands/splash.c            |   42 +++++++++++++++++------------------
 include/gui/graphic_utils.h  |    2 ++
 include/gui/gui.h            |   36 ++++++++++++++++++++++++++++++
 include/gui/image_renderer.h |   16 +++++---------
 lib/gui/bmp.c                |   50 +++++++++++++++++++++++-------------------
 lib/gui/image_renderer.c     |    5 ++---
 lib/gui/png.c                |   34 +++++++++++++++-------------
 7 files changed, 113 insertions(+), 72 deletions(-)
 create mode 100644 include/gui/gui.h
diff --git a/commands/splash.c b/commands/splash.c
index 615b1cb..009c5a0 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 4690e51..4cfb8e8 100644
--- a/include/gui/graphic_utils.h
+++ b/include/gui/graphic_utils.h
@@ -9,6 +9,7 @@
 
 #include <fb.h>
 #include <gui/image.h>
+#include <gui/gui.h>
 
 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 0000000..2f792f1
--- /dev/null
+++ b/include/gui/gui.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * GPL v2
+ */
+
+#ifndef __GUI_H__
+#define __GUI_H__
+
+#include <fb.h>
+
+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 5ee9969..e0b1eae 100644
--- a/include/gui/image_renderer.h
+++ b/include/gui/image_renderer.h
@@ -13,13 +13,13 @@
 #include <linux/err.h>
 #include <fb.h>
 #include <gui/image.h>
+#include <gui/gui.h>
 
 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 86591ed..63902ef 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);
 
-	bits_per_pixel = img->bits_per_pixel;
-	fbsize = xres * yres * (info->bits_per_pixel >> 3);
+	buf = gui_screen_redering_buffer(sc);
 
-	buf = offscreenbuf ? offscreenbuf : fb;
+	bits_per_pixel = img->bits_per_pixel;
+	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 99e4335..41dc43b 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 1e9efd5..3845d7e 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;
-- 
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply	[flat|nested] 13+ messages in thread* [PATCH 5/6] graphic_utils: introduce common fb_open/close
  2012-09-26  9:58 ` [PATCH 1/6] image_renderer: fix size type Jean-Christophe PLAGNIOL-VILLARD
                     ` (2 preceding siblings ...)
  2012-09-26  9:59   ` [PATCH 4/6] gui: introduce screen and surface to factorize and simplify code Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-26  9:59   ` Jean-Christophe PLAGNIOL-VILLARD
  2012-09-26  9:59   ` [PATCH 6/6] gui: blit the surface on demand Jean-Christophe PLAGNIOL-VILLARD
  4 siblings, 0 replies; 13+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-26  9:59 UTC (permalink / raw)
  To: barebox
To open, memmap, get the fb_info and if needed allocate the offscreen buffer
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 commands/splash.c           |   50 ++++++++---------------------------------
 include/gui/graphic_utils.h |    3 ++-
 include/gui/gui.h           |    2 ++
 lib/gui/bmp.c               |    5 ++---
 lib/gui/graphic_utils.c     |   52 +++++++++++++++++++++++++++++++++++++++++++
 lib/gui/png.c               |    8 ++-----
 6 files changed, 69 insertions(+), 51 deletions(-)
diff --git a/commands/splash.c b/commands/splash.c
index 009c5a0..0292809 100644
--- a/commands/splash.c
+++ b/commands/splash.c
@@ -1,11 +1,8 @@
 #include <common.h>
 #include <command.h>
-#include <fs.h>
-#include <linux/stat.h>
 #include <errno.h>
 #include <malloc.h>
 #include <getopt.h>
-#include <fcntl.h>
 #include <fb.h>
 #include <gui/image_renderer.h>
 #include <gui/graphic_utils.h>
@@ -52,39 +49,18 @@ static int do_splash(int argc, char *argv[])
 	}
 	image_file = argv[optind];
 
-	fd = open(fbdev, O_RDWR);
+	fd = fb_open(fbdev, &sc, offscreen);
 	if (fd < 0) {
-		perror("open");
+		perror("fd_open");
 		return 1;
 	}
 
-	sc.fb = memmap(fd, PROT_READ | PROT_WRITE);
-	if (sc.fb == (void *)-1) {
-		perror("memmap");
-		goto failed_memmap;
-	}
-
-	ret = ioctl(fd, FBIOGET_SCREENINFO, &info);
-	if (ret) {
-		perror("ioctl");
-		goto failed_memmap;
-	}
-
-	if (offscreen) {
-		int fbsize;
-		/* Don't fail if malloc fails, just continue rendering directly
-		 * on the framebuffer
-		 */
-
-		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, sc.offscreenbuf, bg_color,
-						sc.s.width * sc.s.height);
-			else
-				memcpy(sc.offscreenbuf, sc.fb, fbsize);
-		}
+	if (sc.offscreenbuf) {
+		if (do_bg)
+			memset_pixel(&info, sc.offscreenbuf, bg_color,
+					sc.s.width * sc.s.height);
+		else
+			memcpy(sc.offscreenbuf, sc.fb, sc.fbsize);
 	} else if (do_bg) {
 		memset_pixel(&info, sc.fb, bg_color, sc.s.width * sc.s.height);
 	}
@@ -92,17 +68,9 @@ static int do_splash(int argc, char *argv[])
 	if (image_renderer_file(&sc, &s, image_file) < 0)
 		ret = 1;
 
-	if (sc.offscreenbuf)
-		free(sc.offscreenbuf);
-
-	close(fd);
+	fb_close(&sc);
 
 	return ret;
-
-failed_memmap:
-	close(fd);
-
-	return 1;
 }
 
 BAREBOX_CMD_HELP_START(splash)
diff --git a/include/gui/graphic_utils.h b/include/gui/graphic_utils.h
index 4cfb8e8..1a17790 100644
--- a/include/gui/graphic_utils.h
+++ b/include/gui/graphic_utils.h
@@ -17,6 +17,7 @@ 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);
+int fb_open(const char * fbdev, struct screen *sc, bool offscreen);
+void fb_close(struct screen *sc);
 
 #endif /* __GRAPHIC_UTILS_H__ */
diff --git a/include/gui/gui.h b/include/gui/gui.h
index 2f792f1..829d156 100644
--- a/include/gui/gui.h
+++ b/include/gui/gui.h
@@ -17,12 +17,14 @@ struct surface {
 };
 
 struct screen {
+	int fd;
 	struct fb_info info;
 
 	struct surface s;
 
 	void *fb;
 	void *offscreenbuf;
+	int fbsize;
 };
 
 static inline void* gui_screen_redering_buffer(struct screen *sc)
diff --git a/lib/gui/bmp.c b/lib/gui/bmp.c
index 63902ef..c880375 100644
--- a/lib/gui/bmp.c
+++ b/lib/gui/bmp.c
@@ -37,7 +37,7 @@ void bmp_close(struct image *img)
 static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
 {
 	struct bmp_image *bmp = img->data;
-	int bits_per_pixel, fbsize;
+	int bits_per_pixel;
 	void *adr, *buf;
 	char *image;
 	int width = s->width;
@@ -69,7 +69,6 @@ static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
 	buf = gui_screen_redering_buffer(sc);
 
 	bits_per_pixel = img->bits_per_pixel;
-	fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3);
 
 	if (bits_per_pixel == 8) {
 		int x, y;
@@ -119,7 +118,7 @@ static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
 		printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel);
 
 	if (sc->offscreenbuf)
-		memcpy(sc->fb, sc->offscreenbuf, fbsize);
+		memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
 
 	return img->height;
 }
diff --git a/lib/gui/graphic_utils.c b/lib/gui/graphic_utils.c
index 06f811c..15a4109 100644
--- a/lib/gui/graphic_utils.c
+++ b/lib/gui/graphic_utils.c
@@ -1,6 +1,11 @@
 #include <common.h>
 #include <fb.h>
 #include <gui/graphic_utils.h>
+#include <linux/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <fs.h>
+#include <malloc.h>
 
 static u32 get_pixel(struct fb_info *info, u32 color)
 {
@@ -190,3 +195,50 @@ void rgba_blend(struct fb_info *info, struct image *img, void* buf, int height,
 		}
 	}
 }
+
+int fb_open(const char * fbdev, struct screen *sc, bool offscreen)
+{
+	int ret;
+
+	sc->fd = open(fbdev, O_RDWR);
+	if (sc->fd < 0)
+		return sc->fd;
+
+	sc->fb = memmap(sc->fd, PROT_READ | PROT_WRITE);
+	if (sc->fb == (void *)-1) {
+		ret = -ENOMEM;
+		goto failed_memmap;
+	}
+
+	ret = ioctl(sc->fd, FBIOGET_SCREENINFO, &sc->info);
+	if (ret) {
+		goto failed_memmap;
+	}
+
+	sc->s.x = 0;
+	sc->s.y = 0;
+	sc->s.width = sc->info.xres;
+	sc->s.height = sc->info.yres;
+	sc->fbsize = sc->s.x * sc->s.x * (sc->info.bits_per_pixel >> 3);
+
+	if (offscreen) {
+		/* Don't fail if malloc fails, just continue rendering directly
+		 * on the framebuffer
+		 */
+		sc->offscreenbuf = malloc(sc->fbsize);
+	}
+
+	return sc->fd;
+
+failed_memmap:
+	sc->fb = NULL;
+	close(sc->fd);
+
+	return ret;
+}
+
+void fb_close(struct screen *sc)
+{
+	free(sc->offscreenbuf);
+	close(sc->fd);
+}
diff --git a/lib/gui/png.c b/lib/gui/png.c
index 3845d7e..36b95f6 100644
--- a/lib/gui/png.c
+++ b/lib/gui/png.c
@@ -69,12 +69,8 @@ static int png_renderer(struct screen *sc, struct surface *s, struct image *img)
 
 	rgba_blend(&sc->info, img, buf, height, width, startx, starty, true);
 
-	if (sc->offscreenbuf) {
-		int fbsize;
-
-		fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3);
-		memcpy(sc->fb, sc->offscreenbuf, fbsize);
-	}
+	if (sc->offscreenbuf)
+		memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
 
 	return img->height;
 }
-- 
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply	[flat|nested] 13+ messages in thread* [PATCH 6/6] gui: blit the surface on demand
  2012-09-26  9:58 ` [PATCH 1/6] image_renderer: fix size type Jean-Christophe PLAGNIOL-VILLARD
                     ` (3 preceding siblings ...)
  2012-09-26  9:59   ` [PATCH 5/6] graphic_utils: introduce common fb_open/close Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-26  9:59   ` Jean-Christophe PLAGNIOL-VILLARD
  4 siblings, 0 replies; 13+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-26  9:59 UTC (permalink / raw)
  To: barebox
Do not blit the surface everytime we write an image
As we want to able to render multiple image this will cause 1 blit per image;
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 commands/splash.c           |    2 ++
 include/gui/graphic_utils.h |    1 +
 lib/gui/bmp.c               |    3 ---
 lib/gui/graphic_utils.c     |    8 ++++++++
 lib/gui/png.c               |    3 ---
 5 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/commands/splash.c b/commands/splash.c
index 0292809..65dd530 100644
--- a/commands/splash.c
+++ b/commands/splash.c
@@ -68,6 +68,8 @@ static int do_splash(int argc, char *argv[])
 	if (image_renderer_file(&sc, &s, image_file) < 0)
 		ret = 1;
 
+	screen_blit(&sc);
+
 	fb_close(&sc);
 
 	return ret;
diff --git a/include/gui/graphic_utils.h b/include/gui/graphic_utils.h
index 1a17790..33e0cbf 100644
--- a/include/gui/graphic_utils.h
+++ b/include/gui/graphic_utils.h
@@ -19,5 +19,6 @@ 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, bool offscreen);
 void fb_close(struct screen *sc);
+void screen_blit(struct screen *sc);
 
 #endif /* __GRAPHIC_UTILS_H__ */
diff --git a/lib/gui/bmp.c b/lib/gui/bmp.c
index c880375..d576121 100644
--- a/lib/gui/bmp.c
+++ b/lib/gui/bmp.c
@@ -117,9 +117,6 @@ static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
 	} else
 		printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel);
 
-	if (sc->offscreenbuf)
-		memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
-
 	return img->height;
 }
 
diff --git a/lib/gui/graphic_utils.c b/lib/gui/graphic_utils.c
index 15a4109..3800ee2 100644
--- a/lib/gui/graphic_utils.c
+++ b/lib/gui/graphic_utils.c
@@ -242,3 +242,11 @@ void fb_close(struct screen *sc)
 	free(sc->offscreenbuf);
 	close(sc->fd);
 }
+
+void screen_blit(struct screen *sc)
+{
+	if (!sc->offscreenbuf)
+		return;
+
+	memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
+}
diff --git a/lib/gui/png.c b/lib/gui/png.c
index 36b95f6..2921ab3 100644
--- a/lib/gui/png.c
+++ b/lib/gui/png.c
@@ -69,9 +69,6 @@ static int png_renderer(struct screen *sc, struct surface *s, struct image *img)
 
 	rgba_blend(&sc->info, img, buf, height, width, startx, starty, true);
 
-	if (sc->offscreenbuf)
-		memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
-
 	return img->height;
 }
 
-- 
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply	[flat|nested] 13+ messages in thread