/* vi: set sw=4 ts=4: */
/*
 * Copyright (C) 2008 Michele Sanges <michele.sanges@gmail.com>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 *
 * Usage:
 * - use kernel option 'vga=xxx' or otherwise enable framebuffer device.
 * - put somewhere fbsplash.cfg file and an image in .ppm format.
 * - run applet: $ setsid fbsplash [params] &
 *      -c: hide cursor
 *      -d /dev/fbN: framebuffer device (if not /dev/fb0)
 *      -s path_to_image_file (can be "-" for stdin)
 *      -i path_to_cfg_file
 *      -f path_to_fifo (can be "-" for stdin)
 * - if you want to run it only in presence of a kernel parameter
 *   (for example fbsplash=on), use:
 *   grep -q "fbsplash=on" </proc/cmdline && setsid fbsplash [params]
 * - commands for fifo:
 *   "NN" (ASCII decimal number) - percentage to show on progress bar.
 *   "exit" (or just close fifo) - well you guessed it.
 */
//config:config FBSPLASH
//config:	bool "fbsplash"
//config:	default y
//config:	select PLATFORM_LINUX
//config:	help
//config:	  Shows splash image and progress bar on framebuffer device.
//config:	  Can be used during boot phase of an embedded device. ~2kb.
//config:	  Usage:
//config:	  - use kernel option 'vga=xxx' or otherwise enable fb device.
//config:	  - put somewhere fbsplash.cfg file and an image in .ppm format.
//config:	  - $ setsid fbsplash [params] &
//config:	    -c: hide cursor
//config:	    -d /dev/fbN: framebuffer device (if not /dev/fb0)
//config:	    -s path_to_image_file (can be "-" for stdin)
//config:	    -i path_to_cfg_file (can be "-" for stdin)
//config:	    -f path_to_fifo (can be "-" for stdin)
//config:	  - if you want to run it only in presence of kernel parameter:
//config:	    grep -q "fbsplash=on" </proc/cmdline && setsid fbsplash [params] &
//config:	  - commands for fifo:
//config:	    "NN" (ASCII decimal number) - percentage to show on progress bar
//config:	    "exit" - well you guessed it

//applet:IF_FBSPLASH(APPLET(fbsplash, BB_DIR_SBIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_FBSPLASH) += fbsplash.o

//usage:#define fbsplash_trivial_usage
//usage:       "-s IMGFILE [-c] [-d DEV] [-i INIFILE] [-f CMD]"
//usage:#define fbsplash_full_usage "\n\n"
//usage:       "	-s	Image"
//usage:     "\n	-c	Hide cursor"
//usage:     "\n	-d	Framebuffer device (default /dev/fb0)"
//usage:     "\n	-i	Config file (var=value):"
//usage:     "\n			BAR_LEFT,BAR_TOP,BAR_WIDTH,BAR_HEIGHT"
//usage:     "\n			BAR_R,BAR_G,BAR_B"
//usage:     "\n	-f	Control pipe (else exit after drawing image)"
//usage:     "\n			commands: 'NN' (% for progress bar) or 'exit'"

#include "libbb.h"
#include "common_bufsiz.h"
#include <linux/fb.h>

/* If you want logging messages on /tmp/fbsplash.log... */
#define DEBUG 0

struct globals {
#if DEBUG
	bool bdebug_messages;	// enable/disable logging
	FILE *logfile_fd;	// log file
#endif
	unsigned char *addr;	// pointer to framebuffer memory
	unsigned ns[7];		// n-parameters
	const char *image_filename;
	struct fb_var_screeninfo scr_var;
	struct fb_fix_screeninfo scr_fix;
	unsigned bytes_per_pixel;
	// cached (8 - scr_var.COLOR.length):
	unsigned red_shift;
	unsigned green_shift;
	unsigned blue_shift;
};
#define G (*ptr_to_globals)
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)

#define nbar_width	ns[0]	// progress bar width
#define nbar_height	ns[1]	// progress bar height
#define nbar_posx	ns[2]	// progress bar horizontal position
#define nbar_posy	ns[3]	// progress bar vertical position
#define nbar_colr	ns[4]	// progress bar color red component
#define nbar_colg	ns[5]	// progress bar color green component
#define nbar_colb	ns[6]	// progress bar color blue component

#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

/**
 * Configure palette for RGB:332
 */
static void fb_setpal(int fd)
{
	struct fb_cmap cmap;
	/* fb colors are 16 bit */
	unsigned short red[256], green[256], blue[256];
	unsigned i;

	/* RGB:332 */
	for (i = 0; i < 256; i++) {
		/* Color is encoded in pixel value as rrrgggbb.
		 * 3-bit color is mapped to 16-bit one as:
		 * 000 -> 00000000 00000000
		 * 001 -> 00100100 10010010
		 * ...
		 * 011 -> 01101101 10110110
		 * 100 -> 10010010 01001001
		 * ...
		 * 111 -> 11111111 11111111
		 */
		red[i]   = (( i >> 5       ) * 0x9249) >> 2; // rrr * 00 10010010 01001001 >> 2
		green[i] = (((i >> 2) & 0x7) * 0x9249) >> 2; // ggg * 00 10010010 01001001 >> 2
		/* 2-bit color is easier: */
		blue[i]  =  ( i       & 0x3) * 0x5555; // bb * 01010101 01010101
	}

	cmap.start = 0;
	cmap.len   = 256;
	cmap.red   = red;
	cmap.green = green;
	cmap.blue  = blue;
	cmap.transp = 0;

	xioctl(fd, FBIOPUTCMAP, &cmap);
}

/**
 * Open and initialize the framebuffer device
 * \param *strfb_device pointer to framebuffer device
 */
static void fb_open(const char *strfb_device)
{
	int fbfd = xopen(strfb_device, O_RDWR);

	// framebuffer properties
	xioctl(fbfd, FBIOGET_VSCREENINFO, &G.scr_var);
	xioctl(fbfd, FBIOGET_FSCREENINFO, &G.scr_fix);

	switch (G.scr_var.bits_per_pixel) {
	case 8:
		fb_setpal(fbfd);
		break;

	case 16:
	case 24:
	case 32:
		break;

	default:
		bb_error_msg_and_die("unsupported %u bpp", (int)G.scr_var.bits_per_pixel);
		break;
	}

	G.red_shift   = 8 - G.scr_var.red.length;
	G.green_shift = 8 - G.scr_var.green.length;
	G.blue_shift  = 8 - G.scr_var.blue.length;
	G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3;

	// map the device in memory
	G.addr = mmap(NULL,
			(G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length,
			PROT_WRITE, MAP_SHARED, fbfd, 0);
	if (G.addr == MAP_FAILED)
		bb_perror_msg_and_die("mmap");

	// point to the start of the visible screen
	G.addr += G.scr_var.yoffset * G.scr_fix.line_length + G.scr_var.xoffset * G.bytes_per_pixel;
	close(fbfd);
}


/**
 * Return pixel value of the passed RGB color.
 * This is performance critical fn.
 */
static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b)
{
	/* We assume that the r,g,b values are <= 255 */

	if (G.bytes_per_pixel == 1) {
		r = r        & 0xe0; // 3-bit red
		g = (g >> 3) & 0x1c; // 3-bit green
		b =  b >> 6;         // 2-bit blue
		return r + g + b;
	}
	if (G.bytes_per_pixel == 2) {
		// ARM PL110 on Integrator/CP has RGBA5551 bit arrangement.
		// We want to support bit locations like that.
		//
		// First shift out unused bits
		r = r >> G.red_shift;
		g = g >> G.green_shift;
		b = b >> G.blue_shift;
		// Then shift the remaining bits to their offset
		return (r << G.scr_var.red.offset) +
			(g << G.scr_var.green.offset) +
			(b << G.scr_var.blue.offset);
	}
	// RGB 888
	return b + (g << 8) + (r << 16);
}

/**
 * Draw pixel on framebuffer
 */
static void fb_write_pixel(unsigned char *addr, unsigned pixel)
{
	switch (G.bytes_per_pixel) {
	case 1:
		*addr = pixel;
		break;
	case 2:
		*(uint16_t *)addr = pixel;
		break;
	case 4:
		*(uint32_t *)addr = pixel;
		break;
	default: // 24 bits per pixel
		addr[0] = pixel;
		addr[1] = pixel >> 8;
		addr[2] = pixel >> 16;
	}
}


/**
 * Draw hollow rectangle on framebuffer
 */
static void fb_drawrectangle(void)
{
	int cnt;
	unsigned thispix;
	unsigned char *ptr1, *ptr2;
	unsigned char nred = G.nbar_colr/2;
	unsigned char ngreen =  G.nbar_colg/2;
	unsigned char nblue = G.nbar_colb/2;

	thispix = fb_pixel_value(nred, ngreen, nblue);

	// horizontal lines
	ptr1 = G.addr + G.nbar_posy * G.scr_fix.line_length + G.nbar_posx * G.bytes_per_pixel;
	ptr2 = G.addr + (G.nbar_posy + G.nbar_height - 1) * G.scr_fix.line_length + G.nbar_posx * G.bytes_per_pixel;
	cnt = G.nbar_width - 1;
	do {
		fb_write_pixel(ptr1, thispix);
		fb_write_pixel(ptr2, thispix);
		ptr1 += G.bytes_per_pixel;
		ptr2 += G.bytes_per_pixel;
	} while (--cnt >= 0);

	// vertical lines
	ptr1 = G.addr + G.nbar_posy * G.scr_fix.line_length + G.nbar_posx * G.bytes_per_pixel;
	ptr2 = G.addr + G.nbar_posy * G.scr_fix.line_length + (G.nbar_posx + G.nbar_width - 1) * G.bytes_per_pixel;
	cnt = G.nbar_height - 1;
	do {
		fb_write_pixel(ptr1, thispix);
		fb_write_pixel(ptr2, thispix);
		ptr1 += G.scr_fix.line_length;
		ptr2 += G.scr_fix.line_length;
	} while (--cnt >= 0);
}


/**
 * Draw filled rectangle on framebuffer
 * \param nx1pos,ny1pos upper left position
 * \param nx2pos,ny2pos down right position
 * \param nred,ngreen,nblue rgb color
 */
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;
	unsigned thispix;
	unsigned char *ptr;

	thispix = fb_pixel_value(nred, ngreen, nblue);

	cnt1 = ny2pos - ny1pos;
	nypos = ny1pos;
	do {
		ptr = G.addr + nypos * G.scr_fix.line_length + nx1pos * G.bytes_per_pixel;
		cnt2 = nx2pos - nx1pos;
		do {
			fb_write_pixel(ptr, thispix);
			ptr += G.bytes_per_pixel;
		} while (--cnt2 >= 0);

		nypos++;
	} while (--cnt1 >= 0);
}


/**
 * Draw a progress bar on framebuffer
 * \param percent percentage of loading
 */
static void fb_drawprogressbar(unsigned percent)
{
	int left_x, top_y, pos_x;
	unsigned width, height;

	// outer box
	left_x = G.nbar_posx;
	top_y = G.nbar_posy;
	width = G.nbar_width - 1;
	height = G.nbar_height - 1;
	if ((int)(height | width) < 0)
		return;
	// NB: "width" of 1 actually makes rect with width of 2!
	fb_drawrectangle();

	// inner "empty" rectangle
	left_x++;
	top_y++;
	width -= 2;
	height -= 2;
	if ((int)(height | width) < 0)
		return;

	pos_x = left_x;
	if (percent > 0) {
		int i, y;

		// actual progress bar
		pos_x += (unsigned)(width * percent) / 100;

		y = top_y;
		i = height;
		if (height == 0)
			height++; // divide by 0 is bad
		while (i >= 0) {
			// draw one-line thick "rectangle"
			// top line will have gray lvl 200, bottom one 100
			unsigned gray_level = 100 + (unsigned)i*100 / height;
			fb_drawfullrectangle(
					left_x, y, pos_x, y,
					gray_level, gray_level, gray_level);
			y++;
			i--;
		}
	}

	fb_drawfullrectangle(
			pos_x, top_y,
			left_x + width, top_y + height,
			G.nbar_colr, G.nbar_colg, G.nbar_colb);
}


/**
 * Draw image from PPM file
 */
static void fb_drawimage(void)
{
	FILE *theme_file;
	char *read_ptr;
	unsigned char *pixline;
	unsigned i, j, width, height, line_size;

	if (LONE_DASH(G.image_filename)) {
		theme_file = stdin;
	} else {
		int fd = open_zipped(G.image_filename, /*fail_if_not_compressed:*/ 0);
		if (fd < 0)
			bb_simple_perror_msg_and_die(G.image_filename);
		theme_file = xfdopen_for_read(fd);
	}

	/* Parse ppm header:
	 * - Magic: two characters "P6".
	 * - Whitespace (blanks, TABs, CRs, LFs).
	 * - A width, formatted as ASCII characters in decimal.
	 * - Whitespace.
	 * - A height, ASCII decimal.
	 * - Whitespace.
	 * - The maximum color value, ASCII decimal, in 0..65535
	 * - Newline or other single whitespace character.
	 *   (we support newline only)
	 * - A raster of Width * Height pixels in triplets of rgb
	 *   in pure binary by 1 or 2 bytes. (we support only 1 byte)
	 */
#define concat_buf bb_common_bufsiz1
	setup_common_bufsiz();

	read_ptr = concat_buf;
	while (1) {
		int w, h, max_color_val;
		int rem = concat_buf + COMMON_BUFSIZE - read_ptr;
		if (rem < 2
		 || fgets(read_ptr, rem, theme_file) == NULL
		) {
			bb_error_msg_and_die("bad PPM file '%s'", G.image_filename);
		}
		read_ptr = strchrnul(read_ptr, '#');
		*read_ptr = '\0'; /* ignore #comments */
		if (sscanf(concat_buf, "P6 %u %u %u", &w, &h, &max_color_val) == 3
		 && max_color_val <= 255
		) {
			width = w; /* w is on stack, width may be in register */
			height = h;
			break;
		}
	}

	line_size = width*3;
	pixline = xmalloc(line_size);

	if (width > G.scr_var.xres)
		width = G.scr_var.xres;
	if (height > G.scr_var.yres)
		height = G.scr_var.yres;
	for (j = 0; j < height; j++) {
		unsigned char *pixel;
		unsigned char *src;

		if (fread(pixline, 1, line_size, theme_file) != line_size)
			bb_error_msg_and_die("bad PPM file '%s'", G.image_filename);
		pixel = pixline;
		src = G.addr + j * G.scr_fix.line_length;
		for (i = 0; i < width; i++) {
			unsigned thispix = fb_pixel_value(pixel[0], pixel[1], pixel[2]);
			fb_write_pixel(src, thispix);
			src += G.bytes_per_pixel;
			pixel += 3;
		}
	}
	free(pixline);
	fclose(theme_file);
}


/**
 * Parse configuration file
 * \param *cfg_filename name of the configuration file
 */
static void init(const char *cfg_filename)
{
	static const char param_names[] ALIGN1 =
		"BAR_WIDTH\0" "BAR_HEIGHT\0"
		"BAR_LEFT\0" "BAR_TOP\0"
		"BAR_R\0" "BAR_G\0" "BAR_B\0"
#if DEBUG
		"DEBUG\0"
#endif
		;
	char *token[2];
	parser_t *parser = config_open2(cfg_filename, xfopen_stdin);
	while (config_read(parser, token, 2, 2, "#=",
				(PARSE_NORMAL | PARSE_MIN_DIE) & ~(PARSE_TRIM | PARSE_COLLAPSE))) {
		unsigned val = xatoi_positive(token[1]);
		int i = index_in_strings(param_names, token[0]);
		if (i < 0)
			bb_error_msg_and_die("syntax error: %s", token[0]);
		if (i >= 0 && i < 7)
			G.ns[i] = val;
#if DEBUG
		if (i == 7) {
			G.bdebug_messages = val;
			if (G.bdebug_messages)
				G.logfile_fd = xfopen_for_write("/tmp/fbsplash.log");
		}
#endif
	}
	config_close(parser);
}


int fbsplash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int fbsplash_main(int argc UNUSED_PARAM, char **argv)
{
	const char *fb_device, *cfg_filename, *fifo_filename;
	FILE *fp = fp; // for compiler
	char *num_buf;
	unsigned num;
	bool bCursorOff;

	INIT_G();

	// parse command line options
	fb_device = "/dev/fb0";
	cfg_filename = NULL;
	fifo_filename = NULL;
	bCursorOff = 1 & getopt32(argv, "cs:d:i:f:",
			&G.image_filename, &fb_device, &cfg_filename, &fifo_filename);

	// parse configuration file
	if (cfg_filename)
		init(cfg_filename);

	// We must have -s IMG
	if (!G.image_filename)
		bb_show_usage();

	fb_open(fb_device);

	if (fifo_filename && bCursorOff) {
		// hide cursor (BEFORE any fb ops)
		full_write(STDOUT_FILENO, "\033[?25l", 6);
	}

	fb_drawimage();

	if (!fifo_filename)
		return EXIT_SUCCESS;

	fp = xfopen_stdin(fifo_filename);
	if (fp != stdin) {
		// For named pipes, we want to support this:
		//  mkfifo cmd_pipe
		//  fbsplash -f cmd_pipe .... &
		//  ...
		//  echo 33 >cmd_pipe
		//  ...
		//  echo 66 >cmd_pipe
		// This means that we don't want fbsplash to get EOF
		// when last writer closes input end.
		// The simplest way is to open fifo for writing too
		// and become an additional writer :)
		open(fifo_filename, O_WRONLY); // errors are ignored
	}

	fb_drawprogressbar(0);
	// Block on read, waiting for some input.
	// Use of <stdio.h> style I/O allows to correctly
	// handle a case when we have many buffered lines
	// already in the pipe
	while ((num_buf = xmalloc_fgetline(fp)) != NULL) {
		if (is_prefixed_with(num_buf, "exit")) {
			DEBUG_MESSAGE("exit");
			break;
		}
		num = atoi(num_buf);
		if (isdigit(num_buf[0]) && (num <= 100)) {
#if DEBUG
			DEBUG_MESSAGE(itoa(num));
#endif
			fb_drawprogressbar(num);
		}
		free(num_buf);
	}

	if (bCursorOff) // restore cursor
		full_write(STDOUT_FILENO, "\033[?25h", 6);

	return EXIT_SUCCESS;
}
