How to draw the graph in framebuffer using c language..?

Rahul picture Rahul · Dec 2, 2009 · Viewed 18.4k times · Source

i am new to this linux framebuffer so do anybody guide me to draw the line-graph in framebuffer. And i have the code to draw graph in turbo c but now in linux. So please help me out.

Thank You, Rahul

Answer

asveikau picture asveikau · Dec 2, 2009

Use open() on the right file in /dev (eg. /dev/fb0), then use mmap() to map it into memory. Manpages will help for these syscalls if you do not know how to use them.

Then there are some structures and constants for some ioctl()s in <linux/fb.h>. Like many kernel headers, you can learn a lot simply browsing the file.

Particularly interesting is the ioctl FBIOGET_VSCREENINFO with struct fb_var_screeninfo. Note this has xres, yres (resolution) and bits_per_pixel. Then there's FBIOGET_FSCREENINFO and struct fb_fix_screeninfo which has further information like type and line_length.

So a pixel at (x, y) might be at mmap_base_address + x * bits_per_pixel/8 + y * line_length. The exact format of the pixels will depend on the structures you retrieve via ioctl; it's your job to decide how to read/write them.

It's been a while since I've worked with this so I'm a bit hazy on more details..

Here's a quick and dirty code sample just to illustrate how it's done... I haven't tested this.

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/fb.h>

#include <unistd.h>
#include <fcntl.h>

#include <stdio.h>

int main()
{
   struct fb_var_screeninfo screen_info;
   struct fb_fix_screeninfo fixed_info;
   char *buffer = NULL;
   size_t buflen;
   int fd = -1;
   int r = 1;

   fd = open("/dev/fb0", O_RDWR);
   if (fd >= 0)
   {
      if (!ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) &&
          !ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info))
      {
         buflen = screen_info.yres_virtual * fixed_info.line_length;
         buffer = mmap(NULL,
                       buflen,
                       PROT_READ|PROT_WRITE,
                       MAP_SHARED,
                       fd,
                       0);
         if (buffer != MAP_FAILED)
         {
            /*
             * TODO: something interesting here.
             * "buffer" now points to screen pixels.
             * Each individual pixel might be at:
             *    buffer + x * screen_info.bits_per_pixel/8
             *           + y * fixed_info.line_length
             * Then you can write pixels at locations such as that.
             */

             r = 0;   /* Indicate success */
         }
         else
         {
            perror("mmap");
         }
      }
      else
      {
         perror("ioctl");
      }
   }
   else
   {
      perror("open");
   }

   /*
    * Clean up
    */
   if (buffer && buffer != MAP_FAILED)
      munmap(buffer, buflen);
   if (fd >= 0)
      close(fd);

   return r;
}