基于FrameBuffer的简易图形库开发

QT不是基于FrameBuffer的吗,现在被Nokia收购了,可惜对于很简单的应用,QT太宠大了,既然知道FrameBuffer的工作原理,自己写一个也行啊,找了找资料,写了以下的代码,当然功能极其简单,实现的基本原理是将FrameBuffer的物理内容映射到进程空间内,然后直接对这段内存进行写操作,这样就会直接将数据显示在屏幕上。
//zsygui.h
#ifndef __ZSYGUI_H__
#define __ZSYGUI_H__
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#define ERR(fmt,args...) printf("Error:" fmt,##args)
/*frame buffer device structure*/
struct fb_dev{
 int fd; /*file descriptor*/
 struct fb_fix_screeninfo fixinfo;
 struct fb_var_screeninfo varinfo;
 char *addr; /*map address*/
 int fb_size; /*frame buffer size*/
 char *buffer; /*buffer,equals to framebufer's size*/
};
struct fb_dev* zsygui_open(const char *device,int mode);
extern int zsygui_flush_buffer(struct fb_dev *pdev);
extern int zsygui_fill_color(struct fb_dev*pdev,int color);
extern int zsygui_draw_line(struct fb_dev *pdev,int whichline,int startpos,int endpos,int color);
extern int zsygui_close(struct fb_dev *pdev);
#endif //__ZSYGUI_H__
 
//zsygui.c
#include "zsygui.h"
struct fb_dev* zsygui_open(const char *device,int mode){
 struct fb_dev *dev=(struct fb_dev*)malloc(sizeof(struct fb_dev));
 if(!dev){
  return NULL;
 }
 if(!device){
  free(dev);
  return NULL;
 }
 if((dev->fd=open(device,mode))<0){
  printf("open %s failed./n",device);
  free(dev);
  return NULL;
 }  
 if(ioctl(dev->fd,FBIOGET_FSCREENINFO,&dev->fixinfo)==-1){
  printf("ioctl failed./n");
  free(dev);
  return NULL;
 }
 if(ioctl(dev->fd,FBIOGET_VSCREENINFO,&dev->varinfo)==-1){
  printf("ioctl failed./n");
  free(dev);
  return NULL;
 }
 //frame buffer size
 dev->fb_size=(dev->varinfo.yres) * (dev->fixinfo.line_length);
 //map physical address to process virtual address
 dev->addr=mmap(NULL,dev->fb_size,PROT_READ|PROT_WRITE,MAP_SHARED,dev->fd,0);
 if(!dev->addr){
  printf("mmap failed./n");
  free(dev);
  return NULL;
 }
 //allocate the same size buffer
 dev->buffer=(char*)malloc(dev->fb_size);
 if(!dev->buffer){
  printf("malloc failed./n");
  free(dev);
  return NULL;
 }
 memset(dev->buffer,0,dev->fb_size);
 return dev; 
}
int zsygui_fill_color(struct fb_dev*pdev,int color){
 if(!pdev){
  return -1;
 }
 memset(pdev->buffer,color,pdev->fb_size);
 zsygui_flush_buffer(pdev);
 return 0;
}
int zsygui_close(struct fb_dev*pdev){
 free(pdev->buffer);
 free(pdev);  
}
int zsygui_flush_buffer(struct fb_dev *pdev){
 char *src,*dst;
 int size=0;
 int lines=0;
 int offset=0;
 if(!pdev){
  return -1;
 }
 src=pdev->buffer;
 dst=pdev->addr;
 size=pdev->varinfo.xres;
 printf("bits_per_pixel=%d/n",pdev->varinfo.bits_per_pixel);
//这里实现一行一行的写,相当于逐行扫描
//一个像素对应几个位,由bits_per_pixel获取,除以8,得到字节数
//每次地址要偏移xres个单元
 lines=pdev->varinfo.yres*((pdev->varinfo.bits_per_pixel)/8);
 offset=pdev->varinfo.xres;
 while(lines-->=0){
  memcpy(dst,src,size);
  src+=offset;
  dst+=offset;
 }
 return 0;
}
int zsygui_draw_hline(struct fb_dev*pdev,int whichline,int startpos,int endpos,int color){
 int i;
 char *buf;
 if(!pdev){
  return -1;
 }
 if(startpos<0 || startpos>pdev->varinfo.xres)
  startpos=0;
 if(endpos<0 || endpos>pdev->varinfo.xres)
  endpos=pdev->varinfo.xres;
 if(whichline<0 || whichline>pdev->varinfo.yres)
  whichline=0;
 buf=pdev->buffer+whichline*pdev->varinfo.xres;
 for(i=startpos;i<endpos;i++)
  *buf++=color;
 zsygui_flush_buffer(pdev);
 return 0; 
}
//测试程序
#include "zsygui.h"
int main(int argc,char **argv){
 struct fb_dev *dev;
 dev=zsygui_open("/dev/fb0",O_RDWR);
 printf("%p/n",dev);
 zsygui_fill_color(dev,0x0);
 zsygui_draw_hline(dev,300,0,500,0xb0);
 zsygui_draw_hline(dev,301,0,500,0xb0);
 zsygui_close(dev);
 return 0;
}
差不多,编译后,尽量在字符模式下编译,运行,实现了预期效果,后来我把它交叉编译后,放到ARM板上,运行也算良好。
 
下一次的工作就是要将jpeg格式的图片,显示出来,涉及到jpeg解码问题,当然,自己写是不太可能的,不过,我找到了一个libjpeg的解码库,这个还不错,可以直接使用,等成功了,再发上来!
编译libjpeg库
1.download jpegsrc.v7.tar.gz
2.tar zxvf jpegsrc.v7.tar.gz
3.cd jpeg-7
4. mkdir ../libjpeg7
5../configure ---prefix=/home/creatory/ldd3/code/libjpeg7 && make && make install
这样就在libjpeg7目录下生成了相当的文件
#ls libjpeg7
发生有如下目录
bin include lib share
看来头文件和库都生成了。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值