注:本文是Console programming HOWTO,Wiebe Zoon ;wiebe@linvision.com的一部分,原文为英文版,本文由highbar翻译。如转载,请注明原作者及译者。 WW.W_PLC※JS_C,OM-PL,C-技.术_网
7. framebuffer WWW.PLCJS.COM——可编程控制器技术门户
P.L.C.技.术.网——可编程控制器技术门户
WWW_PL※CJS_COM-PLC-技.术_网
7.1. framebuffer设备介绍 WWW.PLCJS.COM——可编程控制器技术门户
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
这是一个关于如何编程的文档,因此,请在你编译或执行例子之前,正确配置你的framebuffer设备。 WW.W_PLC※JS_C,OM-PL,C-技.术_网
用framebuffer设备,你可以把你的计算机屏幕当成一个真正的图形设备。你可以修改分辨率,刷新率,色彩深度等。最好的一点是,你可以把像素点绘在任何你想要的地方。framebuffer设备不是一个图形库,而更确切的是一个低级的通用设备。这样创造了巨大的灵活性,但同时也有它的缺点。想使用framebuffer设备,你应该做以下事情: W1WW_P4LCJS_COM-PLC-技.术_网
断定出你使用的设备 ——可——编——程——控-制-器-技——术——门——户
打开设备 ——可——编——程——控-制-器-技——术——门——户
取回或改变屏幕设置 WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
映射(Map)屏幕内存 WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
通常要打开的设备是/dev/fb0,但是如果用户有多个视频卡和监视器的话,设备也可能不同。大多数应用通过读取环境变量FRAMEBUFFER (用getenv();) ——可——编——程——控-制-器-技——术——门——户
来决定该使用哪个设备。如果该环境变量不存在,那么就用/dev/fb0。 WWW_P※LCJS_COM-PLC-)技.术_网
通过open()调用打开设备,读设备意味着读取屏幕内存(可称之为显存)。用$cat /dev/fb0 >screenshot将屏幕内存导入一个文件,恢复刚才的屏幕截图则可使用:$cat WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
screenshot >/dev/fb0。 plcjs.技.术_网
7.2.?设备的基本用法 WWW_PLCJS_COM-PLC-技.术_网
plcjs.技.术_网
显然,用上述方法使用屏幕内存并不经济方便。在读或写之前持续的寻址(见man WWW_P※LCJS_CO※M-PLC-技-.术_网
lseek)将会导致很多的开销。这就是为什么你要映射你的屏幕内存。当你将屏幕内存映射到你的应用程序时,你将得到一个直接指向屏幕内存的指针。 WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
在我们可以映射屏幕内存之前,我们需要知道我们能够映射多少,以及我们需要映射多少。第一件要做的事情就是从我们新得到的framebuffer设备取回信息。有两个结构包含着我们需要的信息,第一个包含固定的屏幕信息,这部分是由硬件和驱动的能力决定的;第二个包含着可变的屏幕信息,这部分是由硬件的当前状态决定的,可以由用户空间的程序调用ioctl()来改变。 WWW_PL※CJS_COM-PLC-技.术_网
struct fb_fix_screeninfo { ——可——编——程——控-制-器-技——术——门——户
char id[16]; ??????????????????????? /* plcjs.技.术_网
identification string eg "TT Builtin" */ P.L.C.技.术.网——可编程控制器技术门户
WWW_PLC※JS_COM-PmLC-技.术_网
unsigned long smem_start; /* WW.W_PLC※JS_C,OM-PL,C-技.术_网
Start of frame buffer mem */ WWW_PLCJS_COM-PLC-技.术_网
——可——编——程——控-制-器-技——术——门——户
/* (physical address) */ WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
WWW_PLCJS_COM-PLC-技.术_网
__u32 smem_len; /* Length of frame buffer mem */ WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
__u32 type; /* see FB_TYPE_* */ WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
WW.W_PLCJS_COM-PLC-技.术_网
__u32 type_aux; /* Interleave for interleaved Planes WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
*/ WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
__u32 visual; /* see FB_VISUAL_* */ P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
__u16 xpanstep; /* zero if no hardware panning? W1WW_P4LCJS_COM-PLC-技.术_网
*/ WWW_P※LCJS_CO※M-PLC-技-.术_网
WWW.PLCJS.COM——可编程控制器技术门户
__u16 ypanstep; /* zero if no hardware panning? WWW_PLCJS@_COM%-PLC-技.术_网
*/ WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
__u16 ywrapstep; /* zero if no hardware ywrap??? WWW_P※LCJS_COM-PLC-)技.术_网
*/ WW.W_PLCJS_COM-PLC-技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
__u32 line_length; /* length of a line in bytes??? WWW_PL※CJS_COM-PLC-技.术_网
*/ WWW_PL※CJS_COM-PLC-技.术_网
W1WW_P4LCJS_COM-PLC-技.术_网
unsigned long mmio_start; /* WWW.PLCJS.COM——可编程控制器技术门户
Start of Memory Mapped I/O?? */ P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
WWW.PLCJS.COM——可编程控制器技术门户
/* (physical address) */ WWW_P※LCJS_CO※M-PLC-技-.术_网
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
__u32 mmio_len; /* Length of Memory Mapped I/O? P.L.C.技.术.网——可编程控制器技术门户
*/ WWW_PLC※JS_COM-PmLC-技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
__u32 accel; /* Type of acceleration available */ WWcW_PLCJS_COM-PLC-技.术_网
WW.W_PLC※JS_C,OM-PL,C-技.术_网
__u16 reserved[3]; /* Reserved for future compatibility WWW_PLCJS_COM-PLC-技.术_网
*/ P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
}; WWW_P※LCJS_COM-PLC-)技.术_网
在这里非常重要的域是smem_len和line-length。smem-len告诉我们framebuffer设备的大小,第二个域告诉我们指针应该前进多少字节去得到下一行的数据。第二个结构则要有意思的多,它给了我们可以改变的信息。 WW.W_PLCJS_COM-PLC-技.术_网
/* more kernel header files copied shamelessly */ WW.W_PLC※JS_C,OM-PL,C-技.术_网
struct fb_bitfield { WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
__u32 offset; /* beginning of bitfield */ WW.W_PLCJS_COM-PLC-技.术_网
WWW_PLC※JS_COM-PmLC-技.术_网
__u32 length; /* length of bitfield */ WWW_P※LCJS_COM-PLC-)技.术_网
WWW_P※LCJS_CO※M-PLC-技-.术_网
__u32 msb_right; /* != 0 : Most significant bit is */ WWW.PLCJS.COM——可编程控制器技术门户
WWcW_PLCJS_COM-PLC-技.术_网
/* right */ WW.W_PLCJS_COM-PLC-技.术_网
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
}; W1WW_P4LCJS_COM-PLC-技.术_网
struct fb_var_screeninfo { WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
__u32 xres; /* visible resolution */ WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
WWcW_PLCJS_COM-PLC-技.术_网
__u32 yres; plcjs.技.术_网
__u32 xres_virtual; /* virtual resolution */ WWW_PL※CJS_COM-PLC-技.术_网
——可——编——程——控-制-器-技——术——门——户
__u32 yres_virtual; WWW.PLCJS.COM——可编程控制器技术门户
__u32 xoffset; /* offset from virtual to visible */ WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)