The main steps for operating framebuffer are as follows:
1. Open an available framebuffer device;
2. Map the physical memory space of the video card to the user space through MMAP calls;
3. Change and display the pixel data in the memory space;
4. Disable the framebuffer device when exiting.
The following example draws a gradient progress bar using framebuffer. The Code framebuf. C is as follows:
# Include <unistd. h>
# Include <stdio. h>
# Include <fcntl. h>
# Include <Linux/FB. h>
# Include <sys/Mman. h>
Inline static unsigned short int make16color (unsigned char R,
Unsigned char g, unsigned char B)
{
Return
(
(R> 3)
& 31) <11) |
(G> 2)
& 63) <
5) |
(B> 3)
&
31)
);
}
Int main (){
Int fbfd =
0;
Struct
Fb_var_screeninfo vinfo;
Struct
Fb_fix_screeninfo finfo;
Long int
Screensize = 0;
Char * FBP = 0;
Int x = 0, y
= 0;
Int
Guage_height = 20, step = 10;
Long int
Location = 0;
// Open
The file for reading and writing
Fbfd =
Open ("/dev/graphics/fb0", o_rdwr );
If (! Fbfd)
{
Printf ("error: cannot open framebuffer device./N ");
Exit (1 );
}
Printf ("
Framebuffer device was opened successfully./N ");
// Get
Fixed Screen Information
If
(IOCTL (fbfd, fbioget_fscreeninfo, & finfo )){
Printf ("error reading fixed information./N ");
Exit (2 );
}
// Get
Variable screen information
If
(IOCTL (fbfd, fbioget_vscreeninfo, & vinfo )){
Printf ("error reading variable information./N ");
Exit (3 );
}
Printf ("sizeof (unsigned short) = % d/N ",
Sizeof (unsigned short ));
Printf ("% DX % d, % dbpp/N", vinfo. xres, vinfo. yres,
Vinfo. bits_per_pixel );
Printf ("xoffset: % d, yoffset: % d, line_length:
% D/N ", vinfo. xoffset, vinfo. yoffset, finfo. line_length );
// Figure
Out the size of the screen in bytes
Screensize =
Vinfo. xres * vinfo. yres * vinfo. bits_per_pixel/8 ;;
// Map
The device to memory
FBP = (char
*) MMAP (0, screensize, prot_read | prot_write, map_shared,
Fbfd, 0 );
If
(INT) FBP =-1 ){
Printf ("error: failed to map framebuffer device
Memory./N ");
Exit (4 );
}
Printf ("
Framebuffer device was mapped to memory successfully./N ");
// Set to black color first
Memset (FBP, 0, screensize );
// Draw
Rectangle
Y =
(Vinfo. yres-guage_height)/2-
2;
// Where we are going to put the pixel
For (x =
Step-2; x <vinfo. xres-step + 2; X ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) +
(Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
Y =
(Vinfo. yres + guage_height)/2 +
2;
// Where we are going to put the pixel
For (x =
Step-2; x <vinfo. xres-step + 2; X ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) +
(Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
X = step
-2;
For (y =
(Vinfo. yres-guage_height)/2-2; y <(vinfo. yres
+ Guage_height)/2 + 2; y ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) +
(Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
X =
Vinfo. xres-step + 2;
For (y =
(Vinfo. yres-guage_height)/2-2; y <(vinfo. yres
+ Guage_height)/2 + 2; y ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) +
(Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
// Figure
Out where in memory to put the pixel
For (x =
Step; x <vinfo. xres-step; X ++ ){
For (y = (vinfo. yres-guage_height)/2; y <
(Vinfo. yres + guage_height)/2; y ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) +
(Y + vinfo. yoffset) * finfo. line_length;
If (vinfo. bits_per_pixel = 32 ){
* (FBP + location) =
100;
// Some blue
* (FBP + location + 1) =
15 + (X-100)/2;
// A little green
* (FBP + location + 2) =
200-(y-100)/5;
// A lot of red
* (FBP + location + 3) =
0;
// No transparency
} Else {// assume 16bpp
Unsigned char B = 255 * x/(vinfo. xres-step );
Unsigned char G =
255;
// (X-100)/6 a little green
Unsigned char r =
255; // a lot
Of red
Unsigned short int T = make16color (R, G, B );
* (Unsigned short int *) (FBP + location) = T;
}
}
// Printf ("x = % d, temp = % d/N ",
X, temp );
// Sleep to see it
Usleep (200 );
}
// Clean
Framebuffer
Munmap (FBP,
Screensize );
Close (fbfd );
Return
0;
}
Note: In the android environment, the framebuffer device is not like/dev/fb0 in Linux,/Dev/graphics/fb0
,
Fbfd = open ("/dev/graphics/fb0", o_rdwr );
Enable the framebuffer device,
FBP =
(Char *) MMAP (0, screensize, prot_read | prot_write,
Map_shared,
Fbfd, 0 );
Map the device to a memory, and then you can operate on the memory space to display the image you want to draw.
Don't forget to close the device:
Munmap (FBP, screensize );
Close (fbfd );