aboutsummaryrefslogtreecommitdiff
path: root/lib/fb/fb.c
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-02-15 15:07:56 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-02-15 15:07:56 +0100
commit1645da679ce50b13b6f19a062eabd2d869762a07 (patch)
tree37e19f84000df69bb2a7d88a2f3db800ead6a85a /lib/fb/fb.c
parent3a369468f7daae5b3a60feaa50c6050b240be6d4 (diff)
add framebuffer image support
Diffstat (limited to 'lib/fb/fb.c')
-rw-r--r--lib/fb/fb.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/lib/fb/fb.c b/lib/fb/fb.c
new file mode 100644
index 0000000..aabe86e
--- /dev/null
+++ b/lib/fb/fb.c
@@ -0,0 +1,128 @@
+#include "fb.h"
+
+#include "../sys/mmap.h"
+#include "../sys/munmap.h"
+#include "../io/io.h"
+#include "../sys/ioctl.h"
+#include "../sys/errno.h"
+
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOGET_FSCREENINFO 0x4602
+
+typedef struct {
+ char id[16];
+ unsigned long smem_start;
+ u32 smem_len;
+ u32 type;
+ u32 type_aux;
+ u32 visual;
+ u16 xpanstep;
+ u16 ypanstep;
+ u16 ywrapstep;
+ u32 line_length;
+ unsigned long mmio_start;
+ u32 mmio_len;
+ u32 accel;
+ u16 capabilities;
+ u16 reserved[2];
+} fb_fscreeninfo_t;
+
+typedef struct {
+ u32 offset;
+ u32 length;
+ u32 msb_right;
+} fb_bitfield_t;
+
+typedef struct {
+ u32 xres;
+ u32 yres;
+ u32 xres_virtual;
+ u32 yres_virtual;
+ u32 xoffset;
+ u32 yoffset;
+
+ u32 bits_per_pixel;
+ u32 grayscale;
+
+ fb_bitfield_t red;
+ fb_bitfield_t green;
+ fb_bitfield_t blue;
+ fb_bitfield_t transp;
+
+ u32 nonstd;
+
+ u32 activate;
+
+ u32 height;
+ u32 width;
+
+ u32 accel_flags;
+
+ u32 pixclock;
+ u32 left_margin;
+ u32 right_margin;
+ u32 upper_margin;
+ u32 lower_margin;
+ u32 hsync_len;
+ u32 vsync_len;
+ u32 sync;
+ u32 vmode;
+ u32 rotate;
+ u32 colorspace;
+ u32 reserved[4];
+} fb_vscreeninfo_t;
+
+int fbfd = 0;
+
+
+canvas_t open_framebuffer()
+{
+ fb_vscreeninfo_t vinfo;
+ fb_fscreeninfo_t finfo;
+ canvas_t canvas = { 0, 0, 0 };
+
+ fbfd = open("/system/devices/fb0", OPEN_READ_WRITE, 0);
+
+ if (fbfd < 0)
+ return canvas;
+
+
+ if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) != 0)
+ return canvas;
+
+ if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) != 0)
+ return canvas;
+
+ canvas.width = vinfo.xres;
+ canvas.height = vinfo.yres;
+ canvas.bits_per_pixel = vinfo.bits_per_pixel;
+ canvas.line_length = finfo.line_length;
+
+ canvas.data = (canvas_pixel_t*)mmap(0, sizeof(u32) * canvas.width * canvas.height,
+ PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
+
+ if ((i64)canvas.data < 0) {
+ wff(STDERR_FD, "error: %s\n", errstr[-(i64)canvas.data]);
+ canvas.data = 0;
+ canvas.width = 0;
+ canvas.height = 0;
+ return canvas;
+ }
+
+ return canvas;
+}
+
+
+void close_framebuffer(canvas_t canvas)
+{
+ munmap(canvas.data, sizeof(u32) * canvas.width * canvas.height);
+ close(fbfd);
+}
+
+
+void put_pixel(canvas_t canvas, u64 x, u64 y, canvas_pixel_t p)
+{
+ char *pos = (char*)canvas.data;
+ pos += (x * canvas.bits_per_pixel / 8) + (y * canvas.line_length);
+ *((canvas_pixel_t*) pos) = p;
+}