summaryrefslogtreecommitdiffstats
path: root/commands/splash.c
blob: 009c5a0a3604578f5111b296bd75395c8e71fa36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#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>

static int do_splash(int argc, char *argv[])
{
	struct surface s;
	struct screen sc;
	int ret, opt, fd;
	char *fbdev = "/dev/fb0";
	struct fb_info info;
	char *image_file;
	int offscreen = 0;
	u32 bg_color = 0x00000000;
	bool do_bg = false;

	s.x = -1;
	s.y = -1;
	s.width = -1;
	s.height = -1;

	while((opt = getopt(argc, argv, "f:x:y:ob:")) > 0) {
		switch(opt) {
		case 'f':
			fbdev = optarg;
			break;
		case 'b':
			bg_color = simple_strtoul(optarg, NULL, 0);
			do_bg = true;
			break;
		case 'x':
			s.x = simple_strtoul(optarg, NULL, 0);
			break;
		case 'y':
			s.y = simple_strtoul(optarg, NULL, 0);
		case 'o':
			offscreen = 1;
		}
	}

	if (optind == argc) {
		printf("no filename given\n");
		return 1;
	}
	image_file = argv[optind];

	fd = open(fbdev, O_RDWR);
	if (fd < 0) {
		perror("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);
		}
	} else if (do_bg) {
		memset_pixel(&info, sc.fb, bg_color, sc.s.width * sc.s.height);
	}

	if (image_renderer_file(&sc, &s, image_file) < 0)
		ret = 1;

	if (sc.offscreenbuf)
		free(sc.offscreenbuf);

	close(fd);

	return ret;

failed_memmap:
	close(fd);

	return 1;
}

BAREBOX_CMD_HELP_START(splash)
BAREBOX_CMD_HELP_USAGE("splash [OPTIONS] FILE\n")
BAREBOX_CMD_HELP_SHORT("Show the bitmap FILE on the framebuffer.\n")
BAREBOX_CMD_HELP_OPT  ("-f <fb>",   "framebuffer device (/dev/fb0)\n")
BAREBOX_CMD_HELP_OPT  ("-x <xofs>", "x offset (default center)\n")
BAREBOX_CMD_HELP_OPT  ("-y <yofs>", "y offset (default center)\n")
BAREBOX_CMD_HELP_OPT  ("-b <color>", "background color in 0xttrrggbb\n")
BAREBOX_CMD_HELP_OPT  ("-o",        "render offscreen\n")
BAREBOX_CMD_HELP_END

/**
 * @page bmp_command

This command displays a graphics in the bitmap (.bmp) format on the
framebuffer. Currently the bmp command supports images with 8 and 24 bit
color depth.

\todo What does the -o (offscreen) option do?

 */

BAREBOX_CMD_START(splash)
	.cmd		= do_splash,
	.usage		= "show a bmp image",
	BAREBOX_CMD_HELP(cmd_splash_help)
BAREBOX_CMD_END