/**
* @file demo2.c
* @Synopsis 实现设备文件映射内存,画正方形,及正方
* 形的上下移动,及左右,上下移动;
* @author MrClimb
* @version 1.1.0
* @date 2012-05-10
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
typedef unsigned char u8_t;
// 这里为什么要写 整形呢
// 类型转换规律。
// 占用空间小的向占用空间大的转换
// 类型一样,一个有符号,一个无符号。向谁转换。
// 像无符号转换
typedef unsigned int u32_t;
typedef struct
{
int w;
int h;
int bpp;
void *memo;
} fbscr_t;
fbscr_t fb_v;
/**
* @param fb_v.memo 代表内存映射的当前位置
* @param x 代表 横坐标偏移位置
* @param y 代表纵坐标
* @param y*fb_v.w 这里跨多少行,也就是纵轴偏移
* fb_v.memo+x 代表横坐标位置
* fb_v.memo+x+y*fb_v.w 即获得实际位置
* 这里只是用坐标来形容,实际内存并非如此,而是一条线性的;
* u32_t color 设置颜色值,可查看颜色表
*/
int fb_one_pixel(int x, int y, u32_t color)
{
*((u32_t *)fb_v.memo+x+y*fb_v.w) = color;
return 0;
}
void init_data(void)
{
// 以只读方式 打开设备
int fd = open("/dev/fb0", O_RDWR);
if(fd < 0)
{
perror("fb0");
exit(1);
}
/**
* 设备 屏幕信息结构体
*/
struct fb_var_screeninfo fb_var;
if(ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) < 0)
{
perror("ioctl");
exit(1);
}
// printf("%d\t%d\t%d\n", fb_var.xres, fb_var.yres, fb_var.bits_per_pixel);
fb_v.w = fb_var.xres;
fb_v.h = fb_var.yres;
fb_v.bpp = fb_var.bits_per_pixel;
fb_v.memo = mmap(NULL, fb_v.w*fb_v.h*fb_v.bpp/8, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(fb_v.memo == MAP_FAILED)
{
perror("map");
exit(1);
}
close(fd);
}
/**
* 画正方形
* @param x0,y0 确定屏幕正方形左上角顶点位置
*/
int square(int x0,int y0,int l,u32_t color)
{
int i=0;//x zuobiao
int j=0;//y zuobiao
for(j=0;j<l;j++)// 纵坐标偏移
{
for(i=0;i<l;i++)// 横坐标偏移
{
fb_one_pixel(x0+i,y0+j,color);// 传坐标点进行设置颜色,根据循环进行偏移
}
}
return 0;
}
int main(void)
{
// 屏幕设备文件与内存建立映射
init_data();
int i = 0;
#if 0
for(i=0; i<500; i++)
{
fb_one_pixel(i, i, 0x0000ff00);
}
#endif
#if 0
// 画正方形
square(500,300,100,0x0000ff00);
#endif
#if 1
/**
* 实现正方形上下移动。。
*/
int x=500; // 横坐标偏移500个点
int y=0;// 从顶部偏移
for(;y<(fb_v.h-50);y+=10)
{
square(x,y,50,0x0000ff00);//开始打印
usleep(1000*100);// stop 10 毫秒
square(x,y,50,0x0);// 这里重新写一次,相当于清屏,重新在该位置设置一次,设置与屏幕颜色一致
}
#endif
#if 0
// 接上往上移
while(y>50)
{
y-=10;
square(x,y,50,0x0000ff00);//开始打印
usleep(1000*100);// stop 10 毫秒
square(x,y,50,0x0);
}
#endif
return 0;
}
/**
* 按一定规则来移动。。。。
*
*/
#if 0
int x=500;
int y=0;
int lx = 1;
int ly = 1;
while(1)
{
square(x,y,50,0x0000ff00);
usleep(1000*10);// s0 ms
square(x,y,50,0x0);
if(x <= 0)
{
lx = 1;
}
if(x >= (fb_v.w-50))
{
lx = -1;
}
if(y <= 0)
{
ly = 1;
}
if(y >= (fb_v.h-50))
{
ly = -1;
}
x += lx;
y += ly;
}
#endif
结果: