//                     compile with  cc drawline.c -lm                   
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <math.h>

void setwhite() ;
void setblack()  ;

void openfile ();
void drawline2 ();
int r, g, b ;    /*** r and b varies from 0 to 31  ( 5 bits )    g varies from 0 to 63  ( 6 bits ) ***/
int fbfd = 0;
unsigned short t ;
 char *fbp = 0;
long int screensize = 0 ;

long int location =0 ;
unsigned int z;
int i , k;
int x, y,   xx, yy, xxx,  yyy ;

struct fb_var_screeninfo vinfo ;
struct fb_fix_screeninfo finfo ;
float m ;
float a,  c ;

int main (void  )
{

openfile ();
setwhite() ;



for ( k = 100 ; k < 700 ; k++)
{
a = sqrt( 90000 - (k - 400) * ( k - 400) );


xx = 400 ;
yy = 400 ;
xxx = k ;
yyy = 400 - a ;
drawline2() ;

xx = 400 ;
yy = 400 ;
xxx = k ;
yyy = 400 + a ;
drawline2() ;


}







z = munmap (fbp, screensize );                              /* now close the map file space   */  

close (fbfd) ;

return 0;

}
/********************************************/
void setwhite()
{

    b = 31 ;
    g = 63 ;
    r = 31 ;
    t = r << 11  | g << 5 |  b;            /*  t is a 16 bit number for color  with r shifted 11 bits  g shifted 5 bits  b= no shift **/
}
/***********************************************/
/********************************************/
void setblack()
{

    b = 5 ;
    g = 10 ;
    r = 5 ;
    t = r << 11  | g << 5 |  b;            /*  t is a 16 bit number for color  with r shifted 11 bits  g shifted 5 bits  b= no shift **/
}
/***********************************************/
void openfile ()
{

fbfd = open("/dev/fb0",   O_RDWR );      /*   open this file  */
        if ( !fbfd == -1 )
         {
        return  ;
        }
//        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 ;
        }

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



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





            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,                   /* share this maping with other process ... update when mumap is called */   
            fbfd, 0 );


            if(( int) fbp == -1)  {
            printf("failed to map .\n");
            return  ;


            }



}
/******************************************/
void drawline2 ( )
{


if (xx < 0 || xxx < 0  || yy < 0 || yyy < 0 )
return ;

if ( xx == yy && xxx == yyy )
return ;


if ( xx > 1600)
 xx = 1600;

if ( xxx > 1600)
 xxx = 1600;

if ( yy > 900)
 yy = 900;

if ( yyy > 900)
 yyy = 900 ;





    if( xx == xxx )
    {
    if ( yyy > yy )
    {
        for (i = yy ;   i < yyy ; i++ )
        {
         y = i  ;
        x = xx  ;

        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }
    if ( yyy < yy )
    {
        for (i = yyy ;   i < yy ; i++ )
        {
         y = i  ;
        x = xx  ;

        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }

return ;    // end horz
    }



/************************************************************/
    if( yy == yyy )
    {
    if ( xxx > xx )
    {
        for (i = xx ;   i <= xxx ; i++ )
        {
         x = i  ;
        y = yy  ;

        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }
    if ( xxx < xx )
    {
        for (i = xxx ;   i <= xx ; i++ )
        {
         x = i  ;
        y = yy  ;

        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }
     return ;  /// end vert

    }
/*****************************************/

if ( xxx == xx )
return ;

m = (float)  ((yyy - yy )  /(float) ( xxx - xx )) ;
//printf (" m = %f \n", m);

/*************************************/
    if (m == 1.0 )
    {
         if (xxx > xx && yyy > yy  )
    {
        for (i = xx; i <= xxx; i++)
        {
        x = i ;
        y = ( i - xx)   + yy ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }

         if (xxx < xx && yyy < yy  )
    {
        for (i = xxx; i <= xx ; i++)
        {
        x = i ;
        y = ( i - xxx)   + yyy ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }    
    return ;
    }                //    end    slope = plus 1 ;   
/********************************************/
    if (m == -1.0 )
    {
         if (xxx > xx && yyy < yy  )
    {
        for (i = xx; i <= xxx; i++)
        {
        x = i ;
        y = yy -  ( i - xx)   ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }
         if (xxx < xx && yyy > yy  )
    {

        for (i = xxx; i <= xx ; i++)
        {
        x = i ;
        y =   yyy - ( i - xxx)    ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }  
         return ;                   //// end slope  minus 1    
}

/********************************************/
    if (m > 0 && m < 1  )
    {
         if (xxx > xx && yyy > yy  )
    {
        for (i = xx; i <= xxx; i++)
        {
        x = i ;
        y = ( i - xx) *m   + yy ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }

         if (xxx < xx && yyy < yy  )
    {
        for (i = xxx; i <= xx ; i++)
        {
        x = i ;
        y = ( i - xxx) * m   + yyy ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }

    }





    return ;
   }                //    end    slope = plus 1 ;   


/********************************************************/
/********************************************/
    if (m > 1   )
    {
         if (xxx > xx && yyy > yy  )
    {
        for (i = yy; i <= yyy; i++)
        {
        y = i ;
        x =   xx + ( i - yy) / m    ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }

         if (xxx < xx && yyy < yy  )
    {
        for (i = yyy; i <= yy ; i++)
        {
        y = i ;
        x = xxx +   ( i - yyy) / m  ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }

    }





    return ;
   }                //    end    slope = plus 1 ;   


/********************************************************/

    if (m >  -1.0 && m < 0  )
    {
      m = m * -1.0  ;
         if (xxx > xx && yyy < yy  )
    {
        for (i = xx; i <= xxx; i++)
        {
        x = i ;
        y = yy -  ( i - xx) * m   ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }
         if (xxx < xx && yyy > yy  )
    {

        for (i = xxx; i <= xx ; i++)
        {
        x = i ;
        y =   yyy - ( i - xxx) * m     ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }  
         return ;                   //// end slope  minus 1    
}

/********************************************/
/********************************************************/
    if (m < -1.0    )
    {
      m = m * -1.0  ;
         if (xxx > xx && yyy < yy  )
    {
        for (i = yyy; i <= yy; i++)
        {
        y = i ;
        x = xx  +  ( yy - y) / m   ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }
         if (xxx < xx && yyy > yy  )
    {

        for (i = yy; i <= yyy ; i++)
        {
        y = i ;
        x =   xx - ( i - yy ) / m     ;
        location = (x + vinfo.xoffset )  *  ( vinfo.bits_per_pixel /8)   + (y+vinfo.yoffset) * ( finfo.line_length) ;
        * (( unsigned short int *  ) ( fbp + location)) = t ;      /*  contents memory at fpb added to location   is set = t ***/
        }
    }  
         return ;                   //// end slope  minus 1    
}

/********************************************/

}
/******************************************/