1. framebuffer设备介绍

用framebuffer设备,你可以把你的计算机屏幕当成一个真正的图形设备。你可以修改分辨率,刷新率,色彩深度等。最好的一点是,你可以把像素点绘在任何你想要的地方。framebuffer设备不是一个图形库,而更确切的是一个低级的通用设备。这样创造了巨大的灵活性,但同时也有它的缺点。想使用framebuffer设备,你应该做以下事情: 
1、判断出你使用的设备 
2、打开设备 
3、取回或改变屏幕设置 
4、映射(Map)屏幕内存 
    通常要打开的设备是/dev/fb0,但是如果用户有多个视频卡和监视器的话,设备也可能不同。大多数应用通过读取环境变量FRAMEBUFFER (用getenv();)来决定该使用哪个设备。如果该环境变量不存在,那么就用/dev/fb0。 
    通过open()调用打开设备,读设备意味着读取屏幕内存(可称之为显存)。用$cat /dev/fb0 >screenshot将屏幕内存导入一个文件,恢复刚才的屏幕截图则可使用:$cat screenshot >/dev/fb0。

2、设备的基本用法

显然,用上述方法使用屏幕内存并不经济方便。在读或写之前持续的寻址(见man lseek)将会导致很多的开销。这就是为什么你要映射你的屏幕内存。当你将屏幕内存映射到你的应用程序时,你将得到一个直接指向屏幕内存的指针。 
     在我们可以映射屏幕内存之前,我们需要知道我们能够映射多少,以及我们需要映射多少。第一件要做的事情就是从我们新得到的framebuffer设备取回信息。有两个结构包含着我们需要的信息,第一个包含固定的屏幕信息,这部分是由硬件和驱动的能力决定的;第二个包含着可变的屏幕信息,这部分是由硬件的当前状态决定的,可以由用户空间的程序调用ioctl()来改变。

struct fb_fix_screeninfo {
char id[16];  /*identification string eg "TT Builtin" */
unsigned long smem_start; /*Start of frame buffer mem */
/* (physical address) */
    __u32 smem_len; /* Length of frame buffer mem */
    __u32 type; /* see FB_TYPE_* */
    __u32 type_aux; /* Interleave for interleaved Planes*/
    __u32 visual; /* see FB_VISUAL_* */
    __u16 xpanstep; /* zero if no hardware panning*/
    __u16 ypanstep; /* zero if no hardware panning*/
    __u16 ywrapstep; /* zero if no hardware ywrap*/
    __u32 line_length; /* length of a line in bytes*/
unsigned long mmio_start; /*Start of Memory Mapped I/O?? */
/* (physical address) */
    __u32 mmio_len; /* Length of Memory Mapped I/O?*/
    __u32 accel; /* Type of acceleration available */
    __u16 reserved[3]; /* Reserved for future compatibility*/
}; 
在这里非常重要的域是smem_len和line-length。smem-len告诉我们framebuffer设备的大小,第二个域告诉我们指针应该前进多少字节去得到下一行的数据。第二个结构则要有意思的多,它给了我们可以改变的信息。 
/* more kernel header files copied shamelessly */
struct fb_bitfield {
    __u32 offset; /* beginning of bitfield */
    __u32 length; /* length of bitfield */
    __u32 msb_right; /* != 0 : Most significant bit is */
/* right */
};
struct fb_var_screeninfo {
    __u32 xres; /* visible resolution */
    __u32 yres;
    __u32 xres_virtual; /* virtual resolution */
    __u32 yres_virtual;
    __u32 xoffset; /* offset from virtual to visible */
    __u32 yoffset; /* resolution */
    __u32 bits_per_pixel; /* guess what */
    __u32 grayscale; /* != 0 Graylevels instead of colors*/
struct fb_bitfield red; /*bitfield in fb mem if true color, */
struct fb_bitfield green; /*else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /*transparency */
    __u32 nonstd; /* != 0 Non standard pixel format */
    __u32 activate; /* see FB_ACTIVATE_* */
    __u32 height; /* height of picture in mm???*/
    __u32 width; /* width of picture in mm????*/
    __u32 accel_flags; /* acceleration flags (hints) */
/* Timing: All values in pixclocks, except pixclock (of course) */
    __u32 pixclock; /* pixel clock in ps (pico seconds) */
    __u32 left_margin; /* time from sync to picture */
    __u32 right_margin; /* time from picture to sync */
    __u32 upper_margin; /* time from sync to picture */
    __u32 lower_margin;
    __u32 hsync_len; /* length of horizontal sync */
    __u32 vsync_len; /* length of vertical sync */
    __u32 sync; /* see FB_SYNC_* */
    __u32 vmode; /* see FB_VMODE_* */
    __u32 reserved[6]; /* Reserved for future compatibility*/
}; 
     前几个成员决定了分辨率。xres和yres 是在屏幕上可见的实际分辨率,在通常的vga模式将为640和400(也许是480,by highbar)。*res-virtual决定了构建屏幕时视频卡读取屏幕内存的方式。当实际的垂直分辨率为400,虚拟分辨率可以是800。这意味着 800行的数据被保存在了屏幕内存区中。因为只有400行可以被显示,决定从那一行开始显示就是你的事了。这个可以通过设置*offset来实现。给 yoffset赋0将显示前400行,赋35将显示第36行到第435行,如此重复。这个功能在许多情形下非常方便实用。它可以用来做双缓冲。双缓冲就是你的程序分配了可以填充两个屏幕的内存。将offset设为0,将显示前400行(假设是标准的vga),同时可以秘密的在400行到799行构建另一个屏幕,当构建结束时,将yoffset设为400,新的屏幕将立刻显示出来。现在将开始在第一块内存区中构建下一个屏幕的数据,如此继续。这在动画中十分有用。 
   另外一个应用就是用来平滑的滚动整个屏幕。就像在前面屏幕中一样,在内存分配800行的空间。每隔10毫秒设定一个定时器(timer,见man settimer和man
signal / man sigaction),将offset设为1或是比上次更多,瞧,你看到了一个平滑滚动的屏幕。确保你的信号(signal)不要因为最佳输出的原因被信号处理程序阻塞。 
将 bits_per_pixel 设为1,2,4,8,16,24或32来改变颜色深度(color depth)。不是所有的视频卡和驱动都支持全部颜色深度。当颜色深度改变,驱动将自动改变fb-bitfields。这些指出,在一个特定的颜色基准上,多少和哪些比特被哪种颜色使用。如果bits-per-pixel小于8,则fb-bitfields将无定义而且颜色映射将启用。 
    在fb-var-screeninfo结构结尾的定时的设置是当你选择一个新的分辨率的时候用来设定视频定时的。

FrameBuffer编程二(简单的程序上)相关推荐

  1. Abp框架从零开始(基于.Net Core 2.2) 小记(二) 简单的文件上传

    这一篇文章,我们实现文件的简单上传功能.    首先,我们就像创建一个普通接口一样,在Application层创建一个目录,目录下定义一个接口IFileCommonService,这个IFileCom ...

  2. 基于C语言的停车场管理系统编程(二)简单版

    一.系统功能 (1)通过菜单的形式实现人机交互界面 (2)实现便道上停车信息显示 (3)实现录入进入停车场的车辆车牌号 二.设计思想 1.人机交互界面 2.录入进入车牌信息 3.显示已停停车场情况 下 ...

  3. pic16f630 c语言编程,PIC16f630简单练习程序

    /*************PIC16F630单片机程序******************************/ /*************************************** ...

  4. C++核心编程(二)

    C++核心编程(二) 0.写在前面 如果你是期末时间紧张冲刺型选手,请移步:C++期末复习超详细总结知识点(期末冲刺) 如果你是时间充足型选手,请按顺序依次学习! 本篇笔记视频讲解地址:https:/ ...

  5. 通过物联网网关如何进行三菱PLC的远程程序上下载?

    PLC是一种可编程控制器,具备性能稳定.编程简单等特点,在工业控制领域广泛使用,西门子.三菱.施耐德.欧姆龙等等都是市场上的主流PLC.随着通信技术与物联网技术的发展,对于PLC的远程监控与远程维护需 ...

  6. 微信小程序——项目成员管理、小程序上传、发布步骤

    一.项目成员管理 登录微信公众号平台:https://mp.weixin.qq.com/ 二.小程序上传 1.点击上传 2.填写"版本号"与"项目备注" 三.小 ...

  7. python socket编程 实现简单p2p聊天程序

    转载自:https://www.cnblogs.com/wuxie1989/p/7204887.html python socket编程 实现简单p2p聊天程序 目标是写一个python的p2p聊天的 ...

  8. python的简单程序代码_小白学编程?从一个简单的程序开始学习Python编程

    笔者思虑再三还是决定选择图文(因为百家的视频发布画质真不怎么样[囧]). 笔者学习编程的时间也挺长的,因为业余,因为时间不多,各种原因,自学编程的路特别难走.然后笔者发现,自己能为小白贡献一些力量,然 ...

  9. js 两个map合并为一个map_ArcGIS API for JS3.x教程二:构建第一个简单的程序

    本文衔接上文: 不睡觉的怪叔叔:ArcGIS API for JS3.x教程一:本地开发环境配置​zhuanlan.zhihu.com 一.创建简单的HTML文档 创建一个简单的HTML文档: < ...

最新文章

  1. 图解Spark原理及实践----大数据技术栈12
  2. C# 异步方法的异常处理
  3. 数学题 贪心+二分答案
  4. Eclipse 为jar包加入 Java Source和Javadoc(如何向Eclipse中导入源码和doc)
  5. Java 使用阿里云短信的API接口
  6. Pomelo:网易开源基于 Node.js 的游戏服务端框架
  7. Python不能做游戏?游戏实战之-----《ink spill》(附游戏完整源码)
  8. iOS 之 Property List
  9. Android跳转到拨打电话的页面
  10. bzoj 3374: [Usaco2004 Mar]Special Serial Numbers 特殊编号
  11. IE浏览器降级详细教程
  12. 用C语言实现PID控制代码
  13. 微信公众号运营技巧总结
  14. 无线通信算法工程师知识地图
  15. oracle 定时 analyze,Oracle工具:Analyze
  16. 【AUTOSAR-COM】-10.3-接收的IPDU Callout(Com_RxIpduCallout)的使用小结
  17. javaFX裁剪视频exe
  18. 电精2 android,安卓街机模拟器|街机电精2(街机模拟器)安卓版 - 系统天堂
  19. TCP连接的建立和释放过程详解(三次握手、四次挥手)
  20. kali linux怎么远程桌面,适用于kali linux的远程桌面开启方法(从windows xp 远程登录到kali linux )...

热门文章

  1. 【ThinkingInC++】66、pointer Stash的使用
  2. twitter中处理网页被iframe方式
  3. 【转自小峰博客】协调器的启动【自动模式】
  4. Python学习笔记之元组
  5. SpringCloud创建项目父工程
  6. python安装到桌面的路径是什么_Python 获取windows桌面路径的5种方法小结
  7. 利用VS2012自带功能,将xml文档反序列化为对象
  8. 初识贪心——调度问题
  9. Java 匿名内部类解析
  10. java多线程为啥一直用的一个线程_一个Java多线程的问题,颠覆了我多年的认知!...