[Create Framebuffer Class]

This commit is contained in:
xoy 2024-06-18 23:43:41 +02:00
parent 8f57f6404f
commit 72345ee066
4 changed files with 175 additions and 47 deletions

100
framebuffer.cpp Normal file
View File

@ -0,0 +1,100 @@
#include "framebuffer.hpp"
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <unistd.h>
#include <stdio.h>
Framebuffer::Framebuffer(std::string devicePath) {
char *devicePathCharArray = new char[devicePath.length()]();
for(int i = 0; i < (int) devicePath.length(); i++) {
devicePathCharArray[i] = devicePath[i];
}
this->devicePath = devicePathCharArray;
}
int Framebuffer::init() {
if(devicePath == NULL || isDeviceOpen) return -1;
device = open(devicePath, O_RDWR);
struct fb_var_screeninfo screeninfo;
ioctl(device, FBIOGET_VSCREENINFO, &screeninfo);
bitsPerPixel = screeninfo.bits_per_pixel;
if(bitsPerPixel != 32) {
printf("Colorscale: %i bits per pixel\n", bitsPerPixel);
printf("Change the colordepth to 32 bits per pixel\n");
close(device);
return -1;
}
width = screeninfo.xres;
height = screeninfo.yres;
bytesPerPixel = bitsPerPixel / 8;
if(sizeof(unsigned int) != bytesPerPixel) {
close(device);
return -1;
}
isDeviceOpen = true;
mmapData();
return 0;
}
int Framebuffer::getWidth() {
return width;
}
int Framebuffer::getHeight() {
return height;
}
int Framebuffer::getBytesPerPixel() {
return bytesPerPixel;
}
void Framebuffer::mmapData() {
data = (unsigned int*) mmap(0, width * height * bytesPerPixel,
PROT_READ | PROT_WRITE, MAP_SHARED, device, 0);
isDataMapped = true;
}
int Framebuffer::setPixel(int x, int y, unsigned int color) {
if(isDataMapped)
data[y * width + x] = color;
else
return -1;
return 0;
}
int Framebuffer::clear(unsigned int color) {
for(int row = 0; row < height; row++) {
for(int column = 0; column < width; column++) {
int success = setPixel(column, row, color);
if(success != 0) return -1;
}
}
return 0;
}
void Framebuffer::munmapData() {
munmap(data, width * height * bytesPerPixel);
isDataMapped = false;
}
void Framebuffer::done() {
if(isDataMapped) munmapData();
if(isDeviceOpen) {
close(device);
isDeviceOpen = false;
}
}

30
framebuffer.hpp Normal file
View File

@ -0,0 +1,30 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include <string>
const unsigned int COLOR_RED = 0xFFFF0000;
const unsigned int COLOR_GREEN = 0xFF00FF00;
const unsigned int COLOR_BLUE = 0xFF0000FF;
class Framebuffer {
public:
Framebuffer(std::string devicePath);
int init();
int getWidth();
int getHeight();
int getBytesPerPixel();
int setPixel(int x, int y, unsigned int color);
int clear(unsigned int color);
void done();
void mmapData();
void munmapData();
private:
unsigned int *data;
int device, width, height, bitsPerPixel, bytesPerPixel;
bool isDataMapped = false;
bool isDeviceOpen = false;
const char *devicePath;
};
#endif

View File

@ -1,70 +1,48 @@
#include <sys/types.h> #include "framebuffer.hpp"
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <signal.h>
const unsigned int RED = 0xFFFF0000;
const unsigned int GREEN = 0xFF00FF00;
const unsigned int BLUE = 0xFF0000FF;
const unsigned int SECOND = 1000000; const unsigned int SECOND = 1000000;
Framebuffer fb{"/dev/fb0"};
// AARRGGBB void exitHandler(int s) {
void clearFramebuffer(int fd, int width, int height, int bytespp, unsigned int color) { printf("Caught signal %d\n", s);
int row, col; fb.done();
unsigned int *data; exit(-1);
data = (unsigned int*) mmap(0, width * height * bytespp, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
for(row = 0; row < height; row++)
for(col = 0; col < width; col++)
data[row * width + col] = color;
munmap(data, width * height * bytespp);
} }
int main() { int main() {
int width, height, bitspp, bytespp; if(fb.init() != 0) return -1;
int fd = open("/dev/fb0", O_RDWR); struct sigaction sigIntHandler;
struct fb_var_screeninfo screeninfo; sigIntHandler.sa_handler = exitHandler;
ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo); sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
bitspp = screeninfo.bits_per_pixel; sigaction(SIGINT, &sigIntHandler, NULL);
if(bitspp != 32) {
printf("Farbaufloesung = %i Bits pro Pixel\n", bitspp);
printf("Bitte aendern Sie die Farbtiefe auf 32 Bits pro Pixel\n");
close(fd);
return 1;
}
width = screeninfo.xres;
height = screeninfo.yres;
bytespp = bitspp / 8;
if(sizeof(unsigned int) != bytespp) {
close(fd);
return 1;
}
int counter = 0; int counter = 0;
while(true) { while(true) {
unsigned int color = (counter == 0) ? RED : ((counter == 1) ? GREEN : BLUE); unsigned int color = (counter == 0) ? COLOR_RED :
clearFramebuffer(fd, width, height, bytespp, color); ((counter == 1) ? COLOR_GREEN : COLOR_BLUE);
int success = fb.clear(color);
if(success != 0) {
fb.done();
return -1;
}
if(counter < 2) if(counter < 2)
counter++; counter++;
else else
counter = 0; counter = 0;
usleep(SECOND); usleep(SECOND);
} }
close(fd); fb.done();
return 0; return 0;
} }

20
makefile Normal file
View File

@ -0,0 +1,20 @@
CXX = g++
CXXFLAGS = -std=c++11 -Wall
TARGET = FramebufferFun
SRCS = main.cpp framebuffer.cpp
OBJS = $(SRCS:.cpp=.o)
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o $(TARGET)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: clean