Hello,
please, can you consider the bbsplash patch I sent on march 7.
I try to resend it.

Thanks.
Michele
diff -urP busybox/include/applets.h busybox_bbsplash/include/applets.h
--- busybox/include/applets.h	2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/include/applets.h	2008-03-07 10:55:00.000000000 +0100
@@ -86,6 +86,7 @@
 USE_BASENAME(APPLET_NOFORK(basename, basename, _BB_DIR_USR_BIN, _BB_SUID_NEVER, basename))
 USE_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_NEVER))
 //USE_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_NEVER))
+USE_BBSPLASH(APPLET(bbsplash, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_BRCTL(APPLET(brctl, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
 USE_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 USE_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat))
diff -urP busybox/include/usage.h busybox_bbsplash/include/usage.h
--- busybox/include/usage.h	2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/include/usage.h	2008-03-07 14:42:17.000000000 +0100
@@ -119,6 +119,19 @@
        "$ basename /foo/bar.txt .txt\n" \
        "bar"
 
+#define bbsplash_trivial_usage \
+       "[-c] [-d /dev/fbN] [-i /path_of_inifile] [-f /path_of_fifo]"
+#define bbsplash_full_usage \
+       "Options:\n" \
+       "	-c	Hide the cursor\n" \
+       "	-d	Select the framebuffer device (default /dev/fb0)\n" \
+       "	-i	Select the bbsplash .ini file (default /etc/bbsplash/bbsplash.ini)\n" \
+       "	-f	Select the bbsplash fifo (default /dev/bbsplash_fifo)\n"
+#define bbsplash_example_usage \
+       "$ setsid bbsplash [-cdif] (start the daemon)" \
+       "$ echo val > /dev/bbsplash_fifo (where val=0..100 - show a progress bar of value val)\n" \
+       "$ echo exit > /dev/bbsplash_fifo (kill the daemon)\n"
+
 #define brctl_trivial_usage \
        "COMMAND [BRIDGE [INTERFACE]]"
 #define brctl_full_usage \
diff -urP busybox/miscutils/bbsplash.c busybox_bbsplash/miscutils/bbsplash.c
--- busybox/miscutils/bbsplash.c	1970-01-01 01:00:00.000000000 +0100
+++ busybox_bbsplash/miscutils/bbsplash.c	2008-03-07 14:54:24.000000000 +0100
@@ -0,0 +1,427 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * boot splash implementation for busybox
+ *
+ * Copyright (C) 2008 Michele Sanges <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * If you want logging messages on /dev/bbsplash_log, change the DEBUG define to 1 in the source.
+ *
+ * Usage:
+ * - pass to the kernel the options 'vga=xxx' to enable the framebuffer with the correct resolution
+ * - put somewhere the bbsplash.ini file and the splash image in .ppm format.
+ * - configure the applet by editing the .ini file.
+ * - start the applet: $ setsid bbsplash <params>
+ * 	where <params> can be:
+ *	-c: to hide the cursor; -d /dev/fbN: to select another framebuffer device than /dev/fb0
+ * 	-i /path_of_inifile: to select another .ini file than /etc/bbsplash/bbsplash.ini; 
+ * 	-f /path_of_fifo: to select another fifo file than /dev/bbsplash_fifo.
+ * - if you want run the applet only in presence of a kernel parameter (for example bbsplash=on), type:
+ *	$ grep -q "bbsplash=on" < /proc/cmdline && setsid bbsplash <params>
+ * - send to the /dev/bbsplash_fifo the following messages:
+ *	(1) the percentage of the boot process.
+ *	(2) 'exit' in order to kill the applet.
+ */
+
+/**
+ * 	boot splash implementation for busybox
+ * \file: bbsplash.c
+ * \author Michele Sanges <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
+ * \version 1.0.0
+ * \date 07/03/2008
+ */
+
+#include "libbb.h"
+#include <linux/fb.h>
+
+#define DEBUG	0
+#define BYTES_PER_PIXEL 2
+
+struct globals {
+#if DEBUG
+	bool bdebug_messages;	///< flag for enable/disable writing messages in logfile
+	FILE *logfile_fd;	///< log file
+#endif
+	int fbfd;		///< descriptor of framebuffer device
+	FILE *theme_file;	///< splash file
+	unsigned char *addr;	///< pointer to framebuffer memory
+	unsigned nbar_width;	///< progress bar width
+	unsigned nbar_height;	///< progress bar height
+	unsigned nbar_posx;	///< progress bar orizzontal position
+	unsigned nbar_posy;	///< progress bar vertical position
+	unsigned char nbar_colr;	///< progress bar colour red component
+	unsigned char nbar_colg;	///< progress bar colour green component
+	unsigned char nbar_colb;	///< progress bar colour blue component
+	char *pstrsplash_theme;	///< pointer to the name of the splash file
+	struct fb_var_screeninfo screen_infovar;
+	struct fb_fix_screeninfo screen_infofix;
+};
+
+#define G	(*ptr_to_globals)
+#define DATA	unsigned short
+
+/// function used for debug purpose
+#if DEBUG
+#define DEBUG_MESSAGE(strMessage, args...) \
+	if (G.bdebug_messages) { \
+		fprintf(G.logfile_fd, "[%s][%s] - %s\n", \
+		__FILE__, __FUNCTION__, strMessage);	\
+	}
+#else
+#define DEBUG_MESSAGE(...) ((void)0)
+#endif
+
+
+/**
+ *	open and initialize the framebuffer device.
+ * \param *strfb_device pointer to framebuffer device
+ */
+static void fb_open(char *strfb_device)
+{
+	G.fbfd = xopen(strfb_device, O_RDWR);
+
+	G.theme_file = xfopen(G.pstrsplash_theme, "r");
+
+	// framebuffer properties
+	xioctl(G.fbfd, FBIOGET_VSCREENINFO, &G.screen_infovar);
+	xioctl(G.fbfd, FBIOGET_FSCREENINFO, &G.screen_infofix);
+
+	if (G.screen_infovar.bits_per_pixel != 16)
+		bb_error_msg_and_die("only 16 bpp is supported");
+
+	// map the device in memory
+	G.addr = mmap(NULL,
+		    G.screen_infovar.xres * G.screen_infovar.yres * (G.screen_infovar.bits_per_pixel / 8),
+		    PROT_WRITE, MAP_SHARED, G.fbfd, 0);
+
+	if (G.addr == (unsigned char *)-1) {
+#if DEBUG
+		char strMex[30];
+		sprintf(strMex, "can't mmap %s", strfb_device);
+		DEBUG_MESSAGE(strMex);
+#endif
+		exit(EXIT_FAILURE);
+	}
+}
+
+
+/**
+ *	draws a rectangle on framebuffer
+ * \param nx1pos,ny1pos upper left position
+ * \param nx2pos,ny2pos down right position
+ * \param nred24,ngreen24,nblue24 rgb colour
+ */
+static void fb_drawrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos,
+	unsigned char nred, unsigned char ngreen, unsigned char nblue)
+{
+	int cnt;
+	DATA thispix;
+	DATA *ptr1, *ptr2;
+
+	nred   >>= 3;  // 5-bit red
+	ngreen >>= 2;  // 6-bit green
+	nblue  >>= 3;  // 5-bit blue
+	thispix = nblue + (ngreen << 5) + (nred << (5+6));
+
+	// horizontal lines
+	ptr1 = (DATA*)(G.addr + (ny1pos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+	ptr2 = (DATA*)(G.addr + (ny2pos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+	cnt = nx2pos - nx1pos;
+	do {
+		*ptr1++ = thispix;
+		*ptr2++ = thispix;
+	} while (--cnt >= 0);
+
+	// vertical lines
+	ptr1 = (DATA*)(G.addr + (ny1pos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+	ptr2 = (DATA*)(G.addr + (ny1pos * G.screen_infovar.xres + nx2pos) * BYTES_PER_PIXEL);
+	cnt = ny2pos - ny1pos;
+	do {
+		*ptr1 = thispix; ptr1 += G.screen_infovar.xres;
+		*ptr2 = thispix; ptr2 += G.screen_infovar.xres;
+	} while (--cnt >= 0);
+}
+
+
+/**
+ *	draws a full rectangle on framebuffer
+ * \param nx1pos,ny1pos upper left position
+ * \param nx2pos,ny2pos down right position
+ * \param nred24,ngreen24,nblue24 rgb colour
+ */
+static void fb_drawfullrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos,
+	unsigned char nred, unsigned char ngreen, unsigned char nblue)
+{
+	int cnt1, cnt2, nypos;
+	DATA thispix;
+	DATA *ptr;
+
+	nred   >>= 3;  // 5-bit red
+	ngreen >>= 2;  // 6-bit green
+	nblue  >>= 3;  // 5-bit blue
+	thispix = nblue + (ngreen << 5) + (nred << (5+6));
+	
+	cnt1 = ny2pos - ny1pos;
+	nypos = ny1pos;
+	do {
+		ptr = (DATA*)(G.addr + (nypos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+		cnt2 = nx2pos - nx1pos;
+		do {
+			*ptr++ = thispix;
+		} while (--cnt2 >= 0);
+		
+		nypos++;
+	} while(--cnt1 >= 0);
+}
+
+
+/**
+ *	draws a progress bar on framebuffer
+ * \param nPercent percentage of loading
+ */
+static void fb_drawprogressbar(unsigned char nPercent)
+{
+	int i;
+
+	fb_drawrectangle(G.nbar_posx, G.nbar_posy,
+			G.nbar_posx + G.nbar_width, G.nbar_posy + G.nbar_height,
+			G.nbar_colr/2, G.nbar_colg/2, G.nbar_colb/2);
+
+	fb_drawfullrectangle(G.nbar_posx + 1, G.nbar_posy + 1,
+			G.nbar_posx + G.nbar_width - 1, G.nbar_posy + G.nbar_height - 1,
+			G.nbar_colr, G.nbar_colg, G.nbar_colb);
+
+	if (nPercent > 0) {
+		for (i = 1; i < (G.nbar_height - 1); i++)
+			fb_drawfullrectangle(G.nbar_posx + 1, G.nbar_posy + i,
+					G.nbar_posx + 1 + (G.nbar_width - 2)*nPercent/100,
+					G.nbar_posy + (i+1), 200-(100*(i-1))/(G.nbar_height - 2),
+					200-(100*(i-1))/(G.nbar_height - 2),
+					200-(100*(i-1))/(G.nbar_height - 2));
+	}
+}
+
+
+/**
+ *	draws the theme image
+ */
+static void fb_drawimage(void)
+{
+	uint i, j, x, y, z;
+	char head[256];
+	char s[80];
+	unsigned char pix[3];
+
+	memset(head, 0, sizeof(head));
+
+	rewind(G.theme_file);
+	while (1) {
+		// parse ppm header
+		fgets(s, 80, G.theme_file);
+
+		if (s[0] == '#')
+			continue;
+
+		if (strlen(head) + strlen(s) > 255)
+			exit(3);
+
+		strcat(head, s);
+		if (head[0]!='P' || head[1]!='6')
+			exit(4);
+
+		if (sscanf(head, "P6 %i %i %i", &x, &y, &z) == 3)
+			break;
+// BUG: can go into infinite loop.
+// Imagine a file with the following contents: "P6 123"
+	}
+
+	for (j=0; j<y; j++) {
+		unsigned thispix;
+		for (i = 0; i < x; i++) {
+			int idx;
+			fread(pix, 1, 3, G.theme_file);
+			if (i >= G.screen_infovar.xres)
+				continue;
+			if (j >= G.screen_infovar.yres)
+				continue;
+
+			idx = j * G.screen_infofix.line_length + i*2;
+			thispix = (((short)pix[0] << 8) & 0xf800)
+				| (((short)pix[1] << 3) & 0x07e0)
+				| ((short)pix[2] >> 3);
+
+			*(DATA *)(G.addr + idx) = thispix;
+		}
+	}
+}
+
+
+/**
+ * initializes the application with the data taken from the configuration file.
+ */
+static void init(char *strini_file)
+{
+	FILE *pinifile;
+	char *buf;
+	static const char const param_value[] ALIGN1 =
+		"DEBUG_MESSAGES\0""SPLASH_THEME\0""BAR_WIDTH\0""BAR_HEIGHT\0"
+		"BAR_POS_X\0""BAR_POS_Y\0""BAR_R_COL\0""BAR_G_COL\0""BAR_B_COL\0";
+
+	pinifile = xfopen(strini_file, "r");
+
+	while ((buf = xmalloc_getline(pinifile)) != NULL) {
+		char *pvalue;
+		int nindex;
+
+		if (*buf == '#') {  // it's a comment
+			free(buf);
+			continue;
+		}
+
+		pvalue = strchrnul(buf, '=');
+		if (*pvalue) *pvalue++ = '\0';
+
+		nindex = index_in_strings(param_value, buf);
+
+		switch(nindex) {
+		case 0:
+#if DEBUG
+			G.bdebug_messages = (strcmp(pvalue, "ON") == 0);
+			if (G.bdebug_messages)
+ 				G.logfile_fd = xfopen("/dev/bbsplash_log", "w");
+#endif
+			break;
+		case 1:
+			// name of the splash theme
+			G.pstrsplash_theme = pvalue;
+			break;
+		case 2:
+			// progress bar width
+			G.nbar_width = atoi(pvalue);
+			break;
+		case 3:
+			// progress bar height
+			G.nbar_height = atoi(pvalue);
+			break;
+		case 4:
+			// progress bar orizzontal position
+			G.nbar_posx = atoi(pvalue);
+			break;
+		case 5:
+			// progress bar vertical position
+			G.nbar_posy = atoi(pvalue);
+			break;
+		case 6:
+			// progress bar colour - red component
+			G.nbar_colr = atoi(pvalue);
+			break;
+		case 7:
+			// progress bar colour - green component
+			G.nbar_colg = atoi(pvalue);
+			break;
+		case 8:
+			// progress bar colour - blue component
+			G.nbar_colb = atoi(pvalue);
+			break;
+		}
+
+		free(buf);
+	}
+
+	fclose(pinifile);
+}
+
+
+int bbsplash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int bbsplash_main(int argc, char **argv)
+{
+	int i, fd, len;
+	char buf[255];
+	char *pstrfb_device, *pstrini_file, *pstrfifo_file;
+	bool bCursorOff = false;
+
+	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G)));
+
+	// command line option
+	opterr = 0; // disables writing on stderr
+	i = getopt32(argv, "cd:i:f:", &pstrfb_device, &pstrini_file, &pstrfifo_file);
+
+	bCursorOff = (i & 0x01);
+
+	if ((i & 0x02) == 0)
+		pstrfb_device = (char *)"/dev/fb0";
+	
+	if ((i & 0x04) == 0)
+		pstrini_file = (char *)"/etc/bbsplash/bbsplash.ini";
+
+	if ((i & 0x08) == 0)
+		pstrfifo_file = (char *)"/dev/bbsplash_fifo";
+
+	// initializes the application with the data taken from the configuration file.
+	init(pstrini_file);
+
+	// hide the cursor
+	if (bCursorOff)	{
+		printf("\E[?25l\n");
+	}
+
+	// change the file mode mask
+	umask(0);
+
+	// open the fifo used for receiving commands
+	mkfifo(pstrfifo_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+	// open the command fifo
+	fd = xopen(pstrfifo_file, O_RDWR | O_NOCTTY/* | O_NONBLOCK*/);
+
+	fb_open(pstrfb_device);
+	fb_drawimage();
+	fb_drawprogressbar(0);
+
+	while(1) {
+		int nVal;
+
+		len = read(fd, buf, 255);
+		if (len == -1) {
+			DEBUG_MESSAGE("error reading the fifo");
+			break;
+		}
+
+		buf[len] = '\0';
+
+		// parse the commands
+		if (strcmp(buf, "exit\n") == 0) {
+			DEBUG_MESSAGE("exit");
+			break;
+		}
+		nVal = atoi(buf);
+		if ((nVal >= 0) && (nVal <= 100)) {
+#if DEBUG
+			char strVal[10];
+			sprintf(strVal, "%d", nVal);
+			DEBUG_MESSAGE(strVal);
+#endif
+			fb_drawprogressbar(nVal);
+		}
+	}
+
+#if DEBUG
+	// closing log file
+  	if (G.bdebug_messages)
+   		fclose(G.logfile_fd);
+#endif
+
+	// restoring the cursor
+	if (bCursorOff) {
+		printf("\E[?25h\n");
+	}
+
+	// close the fifo
+	close(fd);
+
+ 	// remove the fifo
+	unlink(pstrfifo_file);
+
+	return EXIT_SUCCESS;
+}
diff -urP busybox/miscutils/bbsplash.ini busybox_bbsplash/miscutils/bbsplash.ini
--- busybox/miscutils/bbsplash.ini	1970-01-01 01:00:00.000000000 +0100
+++ busybox_bbsplash/miscutils/bbsplash.ini	2008-03-07 15:02:53.000000000 +0100
@@ -0,0 +1,18 @@
+# debug messages: ON or OFF
+DEBUG_MESSAGES=OFF
+# splash theme
+SPLASH_THEME=/etc/bbsplash/splash.ppm
+# progress bar width
+BAR_WIDTH=300
+# progress bar height
+BAR_HEIGHT=20
+# progress bar orizzontal position
+BAR_POS_X=170
+# progress bar vertical position 
+BAR_POS_Y=300
+# progress bar colour red component
+BAR_R_COL=80
+# progress bar colour green component
+BAR_G_COL=80
+# progress bar colour blue component
+BAR_B_COL=130
diff -urP busybox/miscutils/Config.in busybox_bbsplash/miscutils/Config.in
--- busybox/miscutils/Config.in	2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/miscutils/Config.in	2008-03-07 14:51:28.000000000 +0100
@@ -19,6 +19,29 @@
 	  The bbconfig applet will print the config file with which
 	  busybox was built.
 
+config BBSPLASH
+	bool "bbsplash"
+	default n
+	help
+	  Shows a splash image and a progress bar on framebuffer device.
+	  Can be used during the boot phase of a embedded device.
+	  If you want logging messages on /dev/bbsplash_log, change the DEBUG define to 1 in the source.
+	  Adds 1742 bytes.
+
+	  Usage:
+	  - pass to the kernel the options 'vga=xxx' to enable the framebuffer with the correct resolution
+	  - put somewhere the bbsplash.ini file and the splash image in .ppm format.
+	  - configure the applet by editing the .ini file.
+	  - start the applet: $ setsid bbsplash <params>
+	  where <params> can be: -c: to hide the cursor; -d /dev/fbN: to select another framebuffer device than /dev/fb0;
+	  -i /path_of_inifile: to select another .ini file than /etc/bbsplash/bbsplash.ini; 
+	  -f /path_of_fifo: to select another fifo file than /dev/bbsplash_fifo.
+	  - if you want run the applet only in presence of a kernel parameter (for example bbsplash=on), type:
+	  $ grep -q "bbsplash=on" < /proc/cmdline && setsid bbsplash <params>
+	  - send to the bbsplash fifo the following messages:
+	  (1) the percentage of the boot process.
+	  (2) 'exit' in order to kill the applet.
+
 config CHAT
 	bool "chat"
 	default n
diff -urP busybox/miscutils/Kbuild busybox_bbsplash/miscutils/Kbuild
--- busybox/miscutils/Kbuild	2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/miscutils/Kbuild	2008-03-07 10:55:00.000000000 +0100
@@ -7,6 +7,7 @@
 lib-y:=
 lib-$(CONFIG_ADJTIMEX)    += adjtimex.o
 lib-$(CONFIG_BBCONFIG)    += bbconfig.o
+lib-$(CONFIG_BBSPLASH)    += bbsplash.o
 lib-$(CONFIG_CHAT)        += chat.o
 lib-$(CONFIG_CHRT)        += chrt.o
 lib-$(CONFIG_CROND)       += crond.o
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to