#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <string.h>




int main (void  )
{

int fbfd = 0;
struct fb_var_screeninfo vinfo ;
struct fb_fix_screeninfo finfo ;
long int screensize = 0 ;
 char *fbp = 0;

int x=0;
int y=0;
long int location =0 ;
int r, g, b ;    /*** r and b varies from 0 to 31  ( 5 bits )    g varies from 0 to 63  ( 6 bits ) ***/
unsigned int z;
unsigned short t ;



fbfd = open("/dev/fb0",   O_RDWR );      /*   open this file  */

if ( !fbfd == -1 ) {
    printf("  error cannot open fb \n");     /* and check for sucess */
    return (1) ;
        }

printf(" the framebuffer device opened \n");


if ( ioctl( fbfd,  FBIOGET_FSCREENINFO,  &finfo))    {       /*use     input output control   ioctl()  to get fixed data     */
    printf(" error reading fixed  screen\n");            /*    check for sucess **/
    return (1);
                            }                            

 
if ( ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo )){               /* again iocl to   get variable data    */
    printf (" error reading variable info\n");                  /** and check for sucess */
    return (1) ;                    }



printf( " %d x  %d,  %dbpp\n", vinfo.xres,  vinfo.yres, vinfo.bits_per_pixel);


screensize = vinfo.xres  * vinfo.yres * vinfo.bits_per_pixel /8 ;           /***    x pixel * y pxel *bits per pixal / 8 bits per byte   = bytes of memory  ******/

printf (" screensize = %d \n", screensize );

 
fbp = (char*) mmap(0,                    /*** mmap creates a new maping in virtual address space    starting address is pointer fbp  ***/
            screensize,                  /**** size of maping  ****/
            PROT_READ | PROT_WRITE,         /** protections reading and writing allowed   */
            MAP_SHARED,                   /* shaire this maping with other process ... update when mumap is called */   
            fbfd, 0 );                      /*    fbfd                   and offset os zero */  

if(( int) fbp == -1)  {
    printf("failed to map .\n");
    return (1) ;
            }
printf(" the framebuffer was mapped to memory with sucess\n");





for ( y=0 ; y < 10; y++)
    for ( x=0; x<10;x++){
            location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;

                            b = 0 ;
                                    g =  0 ;
                            r = 31  ;
                            t = r << 11  | g << 5 |  b;     /**** | is bitwise or operator  ***/
                            * (( unsigned short int * ) ( fbp + location)) = t ;   /** take fbp and add location to get a pointer*/
                                                                                                              /*    then  set contents of that pointer equal to t **/  
                }

for ( y=0 ; y < 10; y++)
    for ( x=10; x<20;x++){
            location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;


                            b = 0;
                                    g =  63 ;
                            r =  0  ;
                             t = r << 11  | g << 5 |  b;      /*** << is shift operator  << 11  is shift left 11 places **/

                            * (( unsigned short int * ) ( fbp + location)) = t ;

            }
for ( y=0 ; y < 10; y++)
    for ( x=20; x<30;x++){
            location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;


                            b = 31;
                                    g =  0 ;
                            r = 0  ;
                                t = r << 11  | g << 5 |  b;            /*  t is a 16 bit number  with r shifted 11 bits  g shifted 5 bits  b= no shift **/
                            * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/

            }

z = munmap (fbp, screensize );                              /* now read data into map file */  

printf("  ok  the memory  start is %u \n", z );
printf("  ok  the  address is   is %u   \n",&z );

printf (" the location is %ld  \n",  location ) ;


printf ("  x offset = %d    y offset =   %d\n",    vinfo.xoffset,  vinfo.yoffset );
 

close (fbfd) ;

return 0;

}