6

I found the following code which was designed to draw a square on screen.

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

 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;
     long int location = 0;

 // Open the file for reading and writing
 fbfd = open("/dev/fb0", O_RDWR);
 if (fbfd == -1) {
     perror("Error: cannot open framebuffer device");
     exit(1);
 }
 printf("The framebuffer device was opened successfully.\n");

 // Get fixed screen information
 if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
     perror("Error reading fixed information");
     exit(2);
 }

 // Get variable screen information
 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
     perror("Error reading variable information");
     exit(3);
 }

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

 // 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) {
     perror("Error: failed to map framebuffer device to memory");
     exit(4);
 }
 printf("The framebuffer device was mapped to memory successfully.\n");

 x = 300; y = 100;       // Where we are going to put the pixel

 // Figure out where in memory to put the pixel
 for (y = 100; y < 300; y++)
     for (x = 100; x < 300; x++) {

         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
             int b = 10;
             int g = (x-100)/6;     // A little green
             int r = 31-(y-100)/16;    // A lot of red
             unsigned short int t = r<<11 | g << 5 | b;
             *((unsigned short int*)(fbp + location)) = t;
         }

     }
 munmap(fbp, screensize);
 close(fbfd);
 return 0;
 }

When I run it there is no error but unfortunately, nothing happens, nothing is displayed. What I should do to obtain a picture on screen? I am working on ubuntu 14.

user3549833
  • 99
  • 1
  • 5
  • 2
    Works for me. How are you running the program? You need to run it from one of the virtual terminals. Not from the X controlled terminal. – kaylum Aug 19 '15 at 04:01
  • Doesn't work in Xwindows or over ssh terminal. Works fine in plain linux console when run as root. Normal user does not have permission to open framebuffer device. Would not recommend this route for any new desktop linux software. – Paul Aug 19 '15 at 04:55

2 Answers2

6

It runs fine.

Framebuffer programs use the Linux "text" consoles (they do more than text), not XWindows, and not an ssh terminal session.

Framebuffer is not a very nice interface for most purposes. It might be OK for writing a game that takes over the machine. A new Linux desktop program should use something XWindows compatible.

To run:

  1. from XWindows Linux desktop press Control+Alt+F1 to get a Linux "text" console. (Don't use a terminal window instead).
  2. Log in with your password
  3. Put the program in square.c. Compile the program with something like gcc square.c -o square It will give a warning about a pointer/int conversion that looks ok.
  4. [*] use sudo su to become root
  5. run the compiled program ./square

It makes a shaded pink square.

enter image description here

Or it prints Error: cannot open framebuffer device if you are not root.

[*] Never run as root a program you do not completely trust

Paul
  • 26,170
  • 12
  • 85
  • 119
  • I am facing: draw_squared_color.cpp:54:10: error: cast from ‘char*’ to ‘int’ loses precision [-fpermissive] How can I solve it ? – M Y Dec 09 '21 at 22:05
0

Use console not terminal . cntl+alt+f2 to open a console. then compile your code and run