134 lines
4.0 KiB
Vala
134 lines
4.0 KiB
Vala
using Posix;
|
|
|
|
public class FramebufferDemo {
|
|
private const int WIDTH = 720;
|
|
private const int HEIGHT = 720;
|
|
private const int BPP = 4; // BGRA = 4 bytes per pixel
|
|
|
|
private int fb_fd;
|
|
private uint8[] framebuffer;
|
|
|
|
public FramebufferDemo() {
|
|
// Open framebuffer device
|
|
fb_fd = Posix.open("/dev/fb0", Posix.O_RDWR);
|
|
if (fb_fd < 0) {
|
|
GLib.stderr.printf("Error: Cannot open framebuffer device /dev/fb0\n");
|
|
GLib.stderr.printf("Make sure you have permissions (try running with sudo)\n");
|
|
return;
|
|
}
|
|
|
|
// Allocate framebuffer memory
|
|
framebuffer = new uint8[WIDTH * HEIGHT * BPP];
|
|
|
|
GLib.stdout.printf("Framebuffer opened successfully\n");
|
|
GLib.stdout.printf("Resolution: %dx%d, Format: BGRA\n", WIDTH, HEIGHT);
|
|
}
|
|
|
|
~FramebufferDemo() {
|
|
if (fb_fd >= 0) {
|
|
Posix.close(fb_fd);
|
|
}
|
|
}
|
|
|
|
// Set a pixel at (x, y) with BGRA color
|
|
public void set_pixel(int x, int y, uint8 b, uint8 g, uint8 r, uint8 a) {
|
|
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
|
|
return;
|
|
}
|
|
|
|
int offset = (y * WIDTH + x) * BPP;
|
|
framebuffer[offset + 0] = b; // Blue
|
|
framebuffer[offset + 1] = g; // Green
|
|
framebuffer[offset + 2] = r; // Red
|
|
framebuffer[offset + 3] = a; // Alpha
|
|
}
|
|
|
|
// Fill entire screen with a color
|
|
public void fill_screen(uint8 b, uint8 g, uint8 r, uint8 a) {
|
|
for (int y = 0; y < HEIGHT; y++) {
|
|
for (int x = 0; x < WIDTH; x++) {
|
|
set_pixel(x, y, b, g, r, a);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Draw a rectangle
|
|
public void draw_rectangle(int x, int y, int w, int h, uint8 b, uint8 g, uint8 r, uint8 a) {
|
|
for (int dy = 0; dy < h; dy++) {
|
|
for (int dx = 0; dx < w; dx++) {
|
|
set_pixel(x + dx, y + dy, b, g, r, a);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Draw a circle
|
|
public void draw_circle(int cx, int cy, int radius, uint8 b, uint8 g, uint8 r, uint8 a) {
|
|
for (int y = -radius; y <= radius; y++) {
|
|
for (int x = -radius; x <= radius; x++) {
|
|
if (x * x + y * y <= radius * radius) {
|
|
set_pixel(cx + x, cy + y, b, g, r, a);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update the framebuffer (write to /dev/fb0)
|
|
public void update() {
|
|
if (fb_fd < 0) {
|
|
GLib.stderr.printf("Error: Framebuffer not opened\n");
|
|
return;
|
|
}
|
|
|
|
// Seek to beginning of framebuffer
|
|
Posix.lseek(fb_fd, 0, Posix.SEEK_SET);
|
|
|
|
// Write framebuffer data
|
|
ssize_t written = Posix.write(fb_fd, framebuffer, framebuffer.length);
|
|
if (written < 0) {
|
|
GLib.stderr.printf("Error writing to framebuffer\n");
|
|
}
|
|
}
|
|
|
|
public bool is_open() {
|
|
return fb_fd >= 0;
|
|
}
|
|
|
|
public static int main(string[] args) {
|
|
var fb = new FramebufferDemo();
|
|
|
|
if (!fb.is_open()) {
|
|
return 1;
|
|
}
|
|
|
|
GLib.stdout.printf("Drawing demo graphics...\n");
|
|
|
|
// Fill screen with black
|
|
fb.fill_screen(0, 0, 0, 255);
|
|
|
|
// Draw a red rectangle
|
|
fb.draw_rectangle(100, 100, 200, 150, 0, 0, 255, 255);
|
|
|
|
// Draw a green circle
|
|
fb.draw_circle(500, 200, 80, 0, 255, 0, 255);
|
|
|
|
// Draw a blue rectangle
|
|
fb.draw_rectangle(200, 400, 300, 100, 255, 0, 0, 255);
|
|
|
|
// Draw a yellow circle
|
|
fb.draw_circle(360, 360, 100, 0, 255, 255, 255);
|
|
|
|
// Update the framebuffer
|
|
fb.update();
|
|
|
|
GLib.stdout.printf("Graphics drawn! Press Enter to clear and exit...\n");
|
|
GLib.stdin.read_line();
|
|
|
|
// Clear screen before exit
|
|
fb.fill_screen(0, 0, 0, 255);
|
|
fb.update();
|
|
|
|
GLib.stdout.printf("Done!\n");
|
|
return 0;
|
|
}
|
|
}
|