#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<linux/fb.h>
#include<unistd.h>
#include<sys/mman.h>
#include<errno.h>
#include<ctype.h>
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
static char *fb;
static int fd;
void draw(char* argv[]){
  printf("bits_per_pixel:%d;xres:%d;yres:%d;yoffset:%ld;xoffset:%ld;xres_virtual:%ld;yres_virtual:%ld;\n",vinfo.bits_per_pixel,vinfo.xres,vinfo.yres,vinfo.yoffset,vinfo.xoffset,vinfo.xres_virtual,vinfo.yres_virtual);
  printf("fb:0x%08x;smem_start:0x%08x;smem_len:%ld;line_length:%ld\n",fb,finfo.smem_start,finfo.smem_len,finfo.line_length);
  printf("size(unsigned short):%d;size(long int):%d;size(unsigned int):%d;size(int):%d\n",sizeof(unsigned short),sizeof(long int),sizeof(unsigned int),sizeof(int));
  int x=atoi(argv[5]);
  int y=atoi(argv[6]);
  unsigned int location = 0;
  location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +(y+vinfo.yoffset) * vinfo.xres_virtual*vinfo.bits_per_pixel/8;
  unsigned short R=atoi(argv[2]);
  unsigned short G=atoi(argv[3]);
  unsigned short B=atoi(argv[4]);
 
  int i=0;
  unsigned short *p=fb;
  unsigned short tmpmix16,tmpB,tmpG,tmpR;
  tmpB=B&0x00F8;
  tmpG=G&0x00FC;
  tmpR=R&0x00F8;
  tmpmix16 = (tmpR<<8) | (tmpG<<3) | (tmpB>>3);
  for(i=0;i<vinfo.xres*vinfo.yres;i++){
    *(location+p++)=tmpmix16;
  }
  printf("tmpmix16:%16x\n",tmpmix16);
  //*(location+p++)=(unsigned short)tmpmix16;
  //*(location+p++)=tmpmix16>>8;
  /*
  char *p=fb;
  *(location+p++)=B;
  *(location+p++)=G;
  *(location+p++)=R;
  *(location+p++)=0x0000;*/

  printf("location:%ld;x:%d;y:%d;p:%#08x;r:%d;g:%d;b:%d;\n",location,x,y,p,R,G,B);
  return;
}
int main(int argc,char *argv[]){
  fd=open(argv[1],O_RDWR);
  if(fd==-1){
    printf("open %s fail\n",argv[1]);
    return -1;
  }
  if(ioctl(fd,FBIOGET_FSCREENINFO,&finfo)==-1){
    printf("Can`t get FSCREENINFO:%s\n",strerror(errno));
    return -1;
  }
  if(ioctl(fd,FBIOGET_VSCREENINFO,&vinfo)==-1){
    printf("Can`t get VSCREENINFO:%s\n",strerror(errno));
    return -1;
  } 
  fb=(char *)mmap(0,finfo.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); 
  if((int)fb==-1){
    printf("mmap error:%s\n",strerror(errno));
    return -1;
  }
  draw(argv);
  munmap(fb,finfo.smem_len);
  close(fd);
  return 0;  
}