twm/src/modules/fb.c

84 lines
2.3 KiB
C

#define MODULE_NAME "fb"
#include "../twm.h"
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
typedef struct {
int fb_fd;
long screen_size;
struct fb_fix_screeninfo fscrinfo;
struct fb_var_screeninfo vscrinfo;
uint8_t* frame_buffer;
} FBData;
static FBData* data;
Vec2 display_get_size() {
return (Vec2) { data->vscrinfo.xres, data->vscrinfo.yres };
}
uint32_t get_pixel_color(Color col) {
return (col.red << data->vscrinfo.red.offset) | (col.green << data->vscrinfo.green.offset) | (col.blue << data->vscrinfo.blue.offset);
}
void display_put_pixel(Vec2 pos, Color col) {
long pixel_offset = (pos.x + data->vscrinfo.xoffset) * (data->vscrinfo.bits_per_pixel / 8) + (pos.y + data->vscrinfo.yoffset) * data->fscrinfo.line_length;
*((uint32_t*)(data->frame_buffer + pixel_offset)) = get_pixel_color(col);
}
void display_blit(Vec2 pos, Image image) {
for (int x = 0; x < image.size.x; x++) {
for (int y = 0; y < image.size.y; y++) {
display_put_pixel((Vec2) { x + pos.x, y + pos.y }, image.data[y][x]);
}
}
}
void display_flip() {
}
//---------------------------------------------
const uint64_t FEATURE_LISTS[] = {
BIT(BASIC_RENDERING),
0
};
const FeatureFunc FUNCTIONS[] = {
(FeatureFunc) { DISPLAY_PUT_PIXEL_V1, display_put_pixel },
(FeatureFunc) { DISPLAY_BLIT_V1, display_blit },
(FeatureFunc) { DISPLAY_GET_SIZE_V1, display_get_size },
(FeatureFunc) { DISPLAY_FLIP_V1, display_flip },
(FeatureFunc) { FUNC_END, NULL },
};
FeatureFunc* module_init(size_t feature_selected) {
data = malloc(sizeof(FBData));
if (data == NULL)
return NULL;
data->fb_fd = open("/dev/fb0", O_RDWR);
ioctl(data->fb_fd, FBIOGET_FSCREENINFO, &data->fscrinfo);
ioctl(data->fb_fd, FBIOGET_VSCREENINFO, &data->vscrinfo);
data->vscrinfo.bits_per_pixel = 32;
data->vscrinfo.grayscale = 0;
ioctl(data->fb_fd, FBIOPUT_VSCREENINFO, &data->vscrinfo);
ioctl(data->fb_fd, FBIOGET_VSCREENINFO, &data->vscrinfo);
data->screen_size = data->vscrinfo.yres_virtual * data->fscrinfo.line_length;
data->frame_buffer = mmap(0, data->screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, data->fb_fd, (off_t)0);
return (FeatureFunc*)FUNCTIONS;
}
void module_close() {
munmap(data->frame_buffer, data->screen_size);
close(data->fb_fd);
free(data);
}