From 5cc0a5fd73d854c7fa528fd88a2f8303b1ad5e08 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Sun, 28 Jan 2018 11:01:44 -0500 Subject: Add fb.c --- bin/fb.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 bin/fb.c diff --git a/bin/fb.c b/bin/fb.c new file mode 100644 index 00000000..985ba3b4 --- /dev/null +++ b/bin/fb.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void draw(uint32_t *buf, uint32_t xres, uint32_t yres); +extern void input(char c); + +static uint32_t size; +static uint32_t *buf; +static uint32_t *saveBuf; + +static void restoreBuf(void) { + memcpy(buf, saveBuf, size); +} + +static struct termios saveTerm; + +static void restoreTerm(void) { + tcsetattr(STDERR_FILENO, TCSADRAIN, &saveTerm); +} + +int main() { + int error; + + char *path = getenv("FRAMEBUFFER"); + if (!path) path = "/dev/fb0"; + + int fd = open(path, O_RDWR); + if (fd < 0) err(EX_OSFILE, "%s", path); + + struct fb_fix_screeninfo fix; + error = ioctl(fd, FBIOGET_FSCREENINFO, &fix); + if (error) err(EX_IOERR, "%s", path); + + struct fb_var_screeninfo var; + error = ioctl(fd, FBIOGET_VSCREENINFO, &var); + if (error) err(EX_IOERR, "%s", path); + + assert(!var.xoffset); + assert(!var.yoffset); + assert(var.bits_per_pixel == 32); + assert(!var.grayscale); + assert(var.red.offset == 16); + assert(var.red.length == 8); + assert(var.green.offset == 8); + assert(var.green.length == 8); + assert(var.blue.offset == 0); + assert(var.blue.length == 8); + assert(fix.line_length == var.xres * 4); + + size = var.xres * var.yres * 4; + buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) err(EX_OSERR, "%s", path); + + saveBuf = malloc(size); + if (!saveBuf) err(EX_OSERR, "malloc"); + memcpy(saveBuf, buf, size); + atexit(restoreBuf); + + error = tcgetattr(STDERR_FILENO, &saveTerm); + if (error) err(EX_IOERR, "tcgetattr"); + atexit(restoreTerm); + + struct termios raw; + cfmakeraw(&raw); + error = tcsetattr(STDERR_FILENO, TCSADRAIN, &raw); + if (error) err(EX_IOERR, "tcsetattr"); + + for (;;) { + draw(buf, var.xres, var.yres); + + char c; + ssize_t len = read(STDIN_FILENO, &c, 1); + if (len < 0) err(EX_IOERR, "read"); + if (!len || c == CTRL('C')) return EX_OK; + + input(c); + } +} -- cgit 1.4.1