int initFB(void) {
	L("--Initializing framebuffer access method--\n");
	
	fbmmap = MAP_FAILED;
	
	if ((fbfd = open(framebuffer_device, O_RDWR)) == -1) {
		L("Cannot open fb device %s\n", framebuffer_device);
		return -1;
	}
	
	update_fb_info();
	
	if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscrinfo) != 0) {
		L("ioctl error\n");
		return -1;
	}
	
	L("line_length=%d xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n",
		(int)fscrinfo.line_length,(int)scrinfo.xres, (int)scrinfo.yres,
		(int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual,
		(int)scrinfo.xoffset, (int)scrinfo.yoffset,
		(int)scrinfo.bits_per_pixel);
	
	size_t size = scrinfo.yres_virtual;
	
	size_t fbSize = roundUpToPageSize(fscrinfo.line_length * size);
	
	fbmmap = mmap(NULL, fbSize , PROT_READ|PROT_WRITE ,  MAP_SHARED , fbfd, 0);
	
	if (fbmmap == MAP_FAILED) {
		L("mmap failed\n");
		return -1;
	}
	
	// always scale down by 2
	screenformat.width = scrinfo.xres / 2;
	screenformat.height = scrinfo.yres / 2;
	
	// constants for RGB565
	screenformat.bitsPerPixel = 16;
	screenformat.size = screenformat.width * screenformat.height * screenformat.bitsPerPixel / CHAR_BIT;
	screenformat.redShift = 11;
	screenformat.redMax = 5;
	screenformat.greenShift = 5;
	screenformat.greenMax = 6;
	screenformat.blueShift = 0;
	screenformat.blueMax = 5;
	
	return 1;
}
void FUNCTION(void)
{  
  static int i,j,offset;
  
 update_fb_info();
  
// //   detect active buffer
//      offset= (scrinfo.xoffset) * (scrinfo.bits_per_pixel/8) +
//                        (scrinfo.yoffset) * scrinfo.xres;
//   if (scrinfo.yoffset)
//     offset=scrinfo.xres*scrinfo.yoffset;
//   else
//     offset=0;

 offset = scrinfo.xres * scrinfo.yoffset +  scrinfo.xoffset * scrinfo.bits_per_pixel / CHAR_BIT;
		       
  OUT_T* a = (OUT_T*)cmpbuf;
  OUT_T* b = (OUT_T*)fbmmap;
  
  int max_x=-1,max_y=-1, min_x=9999, min_y=9999;
  idle=1;
  
  if (rotation==0)
  {
   //memcpy(vncbuf,fbmmap,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT);
	for (j = 0; j < scrinfo.yres; j++)
	{
	  for (i = 0; i < scrinfo.xres; i++)
	    {
		if (a[i + j * scrinfo.xres]!=b[i + j * scrinfo.xres + offset ])
		{
		  a[i + j * scrinfo.xres]=b[i + j * scrinfo.xres + offset];

		  if (i>max_x)
		    max_x=i;
		  if (i<min_x)
		    min_x=i;
		  
		  if (j>max_y)
		    max_y=j;
		  if (j<min_y)
		    min_y=j;
		  
		  if (idle)
		    idle=0;
		}
	    }
	}
  }
  else if (rotation==90)
  {
	for (j = 0; j < scrinfo.yres; j++)
	{
	  for (i = 0; i < scrinfo.xres; i++)
		{
		  if (a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[i + j * scrinfo.xres + offset])
		   {
		  a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[i + j * scrinfo.xres + offset ];
		  
		  if (i>max_y)
		    max_y=i;
		  if (i<min_y)
		    min_y=i;
		  
		  int h=scrinfo.yres-j;
		  
		  if (h < min_x)
		    min_x=scrinfo.yres-j;
 		  if (h > max_x)
		    max_x=scrinfo.yres-j;
		  
		  if (idle)
		    idle=0;
		  }
		}
	}
  }
  else if (rotation==180)
  {
        for (j = 0; j < scrinfo.yres; j++)
	{
		for (i = 0; i < scrinfo.xres; i++)
		{
		  if (a[i + j * scrinfo.xres]!=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres ) + offset ])
		  {
		    a[i + j * scrinfo.xres]=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres) + offset ];
		    
		  if (i>max_x)
		    max_x=i;
		  if (i<min_x)
		    min_x=i;
		  
		  if (j>max_y)
		    max_y=j;
		  if (j<min_y)
		    min_y=j;
		  
		if (idle)
		    idle=0;
		  }
		}
	}
  }
  else if (rotation==270)
  {
    	for (j = 0; j < scrinfo.yres; j++)
	{
	  
		for (i = 0; i < scrinfo.xres; i++)
		{
		    if(a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ])
		    {
		      a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ];
	          if (i>max_y)
		    max_y=i;
		  if (i<min_y)
		    min_y=i;
		  
		  int h=scrinfo.yres-j;
		  
		  if (h < min_x)
		    min_x=scrinfo.yres-j;
 		  if (h > max_x)
		    max_x=scrinfo.yres-j;
		  
		  if (idle)
		    idle=0;
		  }
		}
	}
	
}
  
memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT);

  

  if (min_x!=9999 && min_y!=9999 && max_x!=-1 && max_y!=-1)
  {
//      min_x--;
     max_x++;
//      min_y--;
     max_y++;
     
  rfbMarkRectAsModified(vncscr, min_x, min_y, max_x, max_y);
  rfbProcessEvents(vncscr, 10000);
  } 
  
//     rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.yres,scrinfo.xres);
//       rfbProcessEvents(vncscr, 10000);
 
 
  if (idle)
  {
    standby=standby+1;
    
    if (standby>30)
      rfbProcessEvents(vncscr, 1000000);
    else
      rfbProcessEvents(vncscr, 100000);
   
//       __android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset);
    change=0;
  }
  else
  {
    change=change+1;
    standby=0;
    rfbProcessEvents(vncscr, 100000);
//        __android_log_print(ANDROID_LOG_INFO,"VNC","change %d\tmin_x=%d max_x=%d min_y=%d max_y=%d xoff=%d yoff=%d\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset);
  } 
}
unsigned int *readBufferFB(void) {
	update_fb_info();
	return fbmmap;
}