/* 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.
 */

//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 <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;
};
#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.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3;

	// map the device in memory
	G.addr = mmap(NULL,
			G.scr_var.xres * G.scr_var.yres * G.bytes_per_pixel,
			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
 */
static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b)
{
	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) {
		r = (r & 0xf8) << 8; // 5-bit red
		g = (g & 0xfc) << 3; // 6-bit green
		b =  b >> 3;         // 5-bit blue
		return r + g + b;
	}
	// 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_var.xres + G.nbar_posx) * G.bytes_per_pixel;
	ptr2 = G.addr + ((G.nbar_posy + G.nbar_height - 1) * G.scr_var.xres + 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_var.xres + G.nbar_posx) * G.bytes_per_pixel;
	ptr2 = G.addr + (G.nbar_posy * G.scr_var.xres + 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_var.xres * G.bytes_per_pixel;
		ptr2 += G.scr_var.xres * G.bytes_per_pixel;
	} 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_var.xres + 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 y;
		unsigned i;

		// 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 + 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);
		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
	read_ptr = concat_buf;
	while (1) {
		int w, h, max_color_val;
		int rem = concat_buf + sizeof(concat_buf) - 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 (strncmp(num_buf, "exit", 4) == 0) {
			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;
}
