用一个实例说明 Linux 下 FrameBuffer 的使用
X-Window-System 是 Unix/Linux 上的图形系统,它是通过 X-Server 来控制硬件的。FrameBuffer 不是一个图形系统,更不是窗口系统。它比 X 要低级,简单来说 FrameBuffer就 是一种机制的实现。这种机制是把屏幕上的每个点映射成一段线性内存空间,程序可以简单的改变这段内存的值来改变屏幕上某一点的颜色。X 的高度可移植性就是来自于这种机制,不管是在那种图形环境下,只要有这种机制的实现就可以运行 X。所以在几乎所有的平台上都有相应的 X 版本的移植。
FrameBuffer 对应的驱动为 /dev/fb*。
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
int main () {
int fp=0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long screensize=0;
char *fbp = 0;
int x = 0, y = 0;
long location = 0;
//以可读可写的形式打开 "/dev/fb0" 文件
fp = open ("/dev/fb0",O_RDWR);
//打开失败
if (fp < 0){
printf("Error : Can not open framebuffer device/n");
exit(1);
}
//获取 fb_var_screeninfo 参数信息
//成员变量 smem_len 是这个 /dev/fb0 的大小,也就是内存大小
//成员变量 line_length 是屏幕上一行的点在内存中占有的空间,不是一行上的点数
if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
printf("Error reading fixed information/n");
exit(2);
}
//获取 fb_fix_screeninfo 参数信息
//成员变量 xres、yres 是 x 和 y 方向的分辨率,就是两个方向上的点数
//成员变量 bits_per_pixel 是每一点占有的内存空间,32 表示一个像素点大小为 32 位。
if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
printf("Error reading variable information/n");
exit(3);
}
//计算屏幕占据的内存大小(字节)
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
//把 fp 所指的文件中从开始到 screensize 大小的内容给映射出来,得到一个指向这块空间的指针
fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
if ((int) fbp == -1)
{
printf ("Error: failed to map framebuffer device to memory./n");
exit (4);
}
//设置坐标,(0,0)点在屏幕左上角,并计算坐标对应的内存地址
x = 100;
y = 100;
location = x * (vinfo.bits_per_pixel / 8) + y * finfo.line_length;
//画点,按照 ARGB8888 格式,直接赋值来改变屏幕上某点的颜色
*(fbp + location) = 100; //蓝色的色深
*(fbp + location + 1) = 15; //绿色的色深
*(fbp + location + 2) = 200; //红色的色深
*(fbp + location + 3) = 0; //透明度
解除映射
munmap (fbp, screensize);
关闭文件
close (fp);
//返回
return 0;
}