diff --git a/framebuffer.cpp b/framebuffer.cpp new file mode 100644 index 0000000..2fc04f2 --- /dev/null +++ b/framebuffer.cpp @@ -0,0 +1,100 @@ +#include "framebuffer.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; + } +} diff --git a/framebuffer.hpp b/framebuffer.hpp new file mode 100644 index 0000000..0c204a9 --- /dev/null +++ b/framebuffer.hpp @@ -0,0 +1,30 @@ +#ifndef FRAMEBUFFER_H +#define FRAMEBUFFER_H + +#include + +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 diff --git a/main.cpp b/main.cpp index d04955c..59d60a0 100644 --- a/main.cpp +++ b/main.cpp @@ -1,70 +1,48 @@ -#include -#include -#include -#include -#include -#include +#include "framebuffer.hpp" #include -#include +#include -const unsigned int RED = 0xFFFF0000; -const unsigned int GREEN = 0xFF00FF00; -const unsigned int BLUE = 0xFF0000FF; const unsigned int SECOND = 1000000; +Framebuffer fb{"/dev/fb0"}; -// AARRGGBB -void clearFramebuffer(int fd, int width, int height, int bytespp, unsigned int color) { - int row, col; - unsigned int *data; - - 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); +void exitHandler(int s) { + printf("Caught signal %d\n", s); + fb.done(); + exit(-1); } 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; - ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo); - - bitspp = screeninfo.bits_per_pixel; - 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; - } + sigIntHandler.sa_handler = exitHandler; + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + sigaction(SIGINT, &sigIntHandler, NULL); int counter = 0; - while(true) { - unsigned int color = (counter == 0) ? RED : ((counter == 1) ? GREEN : BLUE); - clearFramebuffer(fd, width, height, bytespp, color); + unsigned int color = (counter == 0) ? COLOR_RED : + ((counter == 1) ? COLOR_GREEN : COLOR_BLUE); + + int success = fb.clear(color); + + if(success != 0) { + fb.done(); + return -1; + } + if(counter < 2) counter++; else counter = 0; + usleep(SECOND); } - close(fd); + fb.done(); return 0; } diff --git a/makefile b/makefile new file mode 100644 index 0000000..23027a4 --- /dev/null +++ b/makefile @@ -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