#include <stdio.h>
#include <stdlib.h>
#include "framebuffer.h"
#include <termios.h>
#include <unistd.h>
#include <png++/png.hpp>
int mygetch(void)
{
struct termios oldt,newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
void draw_png(png::image <png::rgba_pixel> image, char *fbpointer,int xoffset=0, int yoffest=0)
{
fbColor c;
for (size_t y = 0; y < image.get_height(); ++y)
{
for (size_t x = 0; x < image.get_width(); ++x)
{
c.r=image[y][x].blue;
c.g=image[y][x].green;
c.b=image[y][x].red;
c.alpha=image[y][x].alpha;
fbPutPixel(fbpointer,x+xoffset,y+yoffest,c);
}
}
}
void draw_rectangle(png::image <png::rgba_pixel> image, int ,char *fbpointer)
{
}
int main()
{
int fp=0;
char *fbpointer = initFrameBuffer("/dev/fb0",0,0,fp);
int xplace[3];
int midle;
png::image <png::rgba_pixel> arch("Arch.png");
png::image <png::rgba_pixel> android("Android.png");
png::image <png::rgba_pixel> fsck("Fsck.png");
xplace[0]=vinfo.xres/2/2-android.get_width()/2;
xplace[1]=vinfo.xres/2-arch.get_width()/2;
xplace[2]=vinfo.xres/2/2*3-fsck.get_width()/2;
midle=vinfo.yres/2-200/2;
while ((mygetch())!='q')
{
draw_png(android, fbpointer,xplace[0], midle);
draw_png(arch, fbpointer, xplace[1], midle);
draw_png(fsck, fbpointer, xplace[2], midle);
}
fbClean(fbpointer);
fbClose(fp);
return 0;
}
And the framebuffer.h:
#ifndef FRAMEBUFFER_H_INCLUDED
#define FRAMEBUFFER_H_INCLUDED
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
char *fbp = 0;
typedef struct fbColor
{
int r;
int g;
int b;
int alpha;
}fbColor;
char* initFrameBuffer(char *fbp,int xres,int yres,int fbfd)
{
/* Open the file for reading and writing */
fbfd = open(fbp, O_RDWR);
if (!fbfd)
{
printf("Error: cannot open framebuffer device.\n");
exit(-1);
}
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))
{
printf("Error reading fixed information.\n");
exit(-1);
}
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
{
printf("Error reading variable information.\n");
exit(-1);
}
fbp = ( char *)mmap(0,(vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8), PROT_READ | PROT_WRITE, MAP_SHARED,fbfd, 0);
//if ((int)fbp == -1)
//{
// printf("Error: failed to map framebuffer device to memory.\n");
// exit(-1);
//}
return fbp;
}
long int fbScreenSize()
{
return vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
}
int fbPutPixel(char *fbp,int x,int y,fbColor color)
{
long int location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y+vinfo.yoffset) * finfo.line_length;
if (vinfo.bits_per_pixel == 32)
{
*(fbp + location) = color.b; // Some blue
*(fbp + location + 1) = color.g; // A little green
*(fbp + location + 2) = color.r; // A lot of red
*(fbp + location + 3) = color.alpha; // No transparency
}
else
{
int b = color.b;
int g = color.g; // A little green
int r = color.r; // A lot of red
unsigned short int t = r<<11 | g << 5 | b;
*((unsigned short int*)(fbp + location)) = t;
}
return 0;
}
void fbClose(int fbfd)
{
close(fbfd);
}
void fbClean(char* fbp)
{
munmap(fbp,fbScreenSize());
}
#endif // FRAMEBUFFER_H_INCLUDED