#include // Represents a colour on the screen. // For each RGB value, accepts a value between 0-255, where // 0 is all the way off and 255 is all the way on. typedef struct Colour { char red; char green; char blue; char alpha; } Colour; // Represents a pixel on the screen. typedef struct Pixel { int x; int y; } Pixel; // Represents the framebuffer that the user has opened. // Use newFramebuffer() to construct this struct. // Get x and y size of screen with .vinfo.xres and .vinfo.yres typedef struct Framebuffer { int fd; struct fb_var_screeninfo vinfo; long int screensize; char* data; } Framebuffer; // Constructs a Framebuffer struct. // Asserts whether device is able to be opened. If unable, program is aborted. Framebuffer newFramebuffer(const char* device); // Writes a colour to the screen. // fb: Pointer to Framebuffer struct (get one with newFramebuffer("/dev/fb0") ) // pixel: Which pixel on the screen to apply to // colour: The colour of the pixel void writeColourToFramebuffer(Framebuffer* fb, Pixel pixel, Colour colour); // Destroys a framebuffer. void destroyFramebuffer(Framebuffer* fb); // Example library usage (puts a red pixel at 100, 100) /* int main() { Framebuffer fb = newFramebuffer("/dev/fb0"); writeColourToFramebuffer(&fb, (Pixel){100, 100}, (Colour){0, 0, 255, 0}); destroyFramebuffer(&fb); return 0; } */ // To use as single-header library, define FB_IMPLEMENTATION before including this header. #ifdef FB_IMPLEMENTATION #include #include #include #include #include #include Framebuffer newFramebuffer(const char* device) { Framebuffer fb; // Open the framebuffer file descriptor fb.fd = open(device, O_RDWR); assert(fb.fd >= 0 && "Invalid framebuffer device, please ensure your user is in the 'video' group."); // Get information about framebuffer ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.vinfo); // Get size of screen for writing pixels in bounds fb.screensize = fb.vinfo.xres * fb.vinfo.yres * fb.vinfo.bits_per_pixel / 8; fb.data = mmap(0, fb.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0); return fb; } void writeColourToFramebuffer(Framebuffer* fb, Pixel pixel, Colour colour) { int offset = (pixel.y * fb->vinfo.xres + pixel.x) * (fb->vinfo.bits_per_pixel / 8); fb->data[offset + 0] = colour.red; fb->data[offset + 1] = colour.green; fb->data[offset + 2] = colour.blue; fb->data[offset + 3] = colour.alpha; munmap(fb->data, fb->screensize); } void destroyFramebuffer(Framebuffer* fb) { close(fb->fd); // NOTE: Do not free fb->data, this is not memory owned by us. // Will cause a segfault } #endif