Paint Pixels to Screen via Linux FrameBuffer












34















I was recently struck by a curious idea to take input from /dev/urandom, convert relevant characters to random integers, and use those integers as the rgb/x-y values for pixels to paint onto the screen.



I've done some research (here on StackOverflow and elsewhere) and many suggest that you can simply write to /dev/fb0 directly as it is the file representation of the device. Unfortunately, this does not seem to produce any visually apparent results.



I found a sample C program that was from a QT tutorial (no longer available) that used an mmap to write to the buffer. The program runs successfully, but again, no output to the screen. Interestingly enough, when I placed my laptop into Suspend and later restored, I saw a momentary flash of the image (a red square) that was written to the framebuffer much earlier. Does writing to the framebuffer work anymore in Linux for painting to screen? Ideally, I'd like to write a (ba)sh script, but C or similar would work as well. Thanks!



EDIT: Here's the sample program...may look familiar to vets.



#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, %dbppn", 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 = 100; 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
//location += 4;
} 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;
}









share|improve this question

























  • Ideally, this needs to work for most (all?) Linux systems (DE independent) and other compatibility is appreciated but optional.

    – Richard Martinez
    Feb 14 '11 at 20:31






  • 6





    The framebuffer device is often (but not always) independent of X - try switching to a virtual console with ctrl-alt-f1 or ctrl-alt-f2 and running the demo there.

    – caf
    Feb 14 '11 at 20:41











  • Interesting...that seems to work. Is there any possibility that I would be able to set the display as tty7 (X server)?

    – Richard Martinez
    Feb 14 '11 at 20:58






  • 2





    Note, Wikipedia link[/link] mentions some programs that use the framebuffer directly, like MPlayer. How do they attach the output to the desktop environment?

    – Richard Martinez
    Feb 14 '11 at 21:07








  • 1





    @RichardMartinez: As it says, "Graphic programs avoiding the heavy overhead of the X Window System." Those programs can access it directly when they're not running under X Windows (e.g. on an embedded device with an LCD screen), I think.

    – Craig McQueen
    Mar 20 '13 at 0:40


















34















I was recently struck by a curious idea to take input from /dev/urandom, convert relevant characters to random integers, and use those integers as the rgb/x-y values for pixels to paint onto the screen.



I've done some research (here on StackOverflow and elsewhere) and many suggest that you can simply write to /dev/fb0 directly as it is the file representation of the device. Unfortunately, this does not seem to produce any visually apparent results.



I found a sample C program that was from a QT tutorial (no longer available) that used an mmap to write to the buffer. The program runs successfully, but again, no output to the screen. Interestingly enough, when I placed my laptop into Suspend and later restored, I saw a momentary flash of the image (a red square) that was written to the framebuffer much earlier. Does writing to the framebuffer work anymore in Linux for painting to screen? Ideally, I'd like to write a (ba)sh script, but C or similar would work as well. Thanks!



EDIT: Here's the sample program...may look familiar to vets.



#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, %dbppn", 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 = 100; 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
//location += 4;
} 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;
}









share|improve this question

























  • Ideally, this needs to work for most (all?) Linux systems (DE independent) and other compatibility is appreciated but optional.

    – Richard Martinez
    Feb 14 '11 at 20:31






  • 6





    The framebuffer device is often (but not always) independent of X - try switching to a virtual console with ctrl-alt-f1 or ctrl-alt-f2 and running the demo there.

    – caf
    Feb 14 '11 at 20:41











  • Interesting...that seems to work. Is there any possibility that I would be able to set the display as tty7 (X server)?

    – Richard Martinez
    Feb 14 '11 at 20:58






  • 2





    Note, Wikipedia link[/link] mentions some programs that use the framebuffer directly, like MPlayer. How do they attach the output to the desktop environment?

    – Richard Martinez
    Feb 14 '11 at 21:07








  • 1





    @RichardMartinez: As it says, "Graphic programs avoiding the heavy overhead of the X Window System." Those programs can access it directly when they're not running under X Windows (e.g. on an embedded device with an LCD screen), I think.

    – Craig McQueen
    Mar 20 '13 at 0:40
















34












34








34


17






I was recently struck by a curious idea to take input from /dev/urandom, convert relevant characters to random integers, and use those integers as the rgb/x-y values for pixels to paint onto the screen.



I've done some research (here on StackOverflow and elsewhere) and many suggest that you can simply write to /dev/fb0 directly as it is the file representation of the device. Unfortunately, this does not seem to produce any visually apparent results.



I found a sample C program that was from a QT tutorial (no longer available) that used an mmap to write to the buffer. The program runs successfully, but again, no output to the screen. Interestingly enough, when I placed my laptop into Suspend and later restored, I saw a momentary flash of the image (a red square) that was written to the framebuffer much earlier. Does writing to the framebuffer work anymore in Linux for painting to screen? Ideally, I'd like to write a (ba)sh script, but C or similar would work as well. Thanks!



EDIT: Here's the sample program...may look familiar to vets.



#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, %dbppn", 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 = 100; 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
//location += 4;
} 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;
}









share|improve this question
















I was recently struck by a curious idea to take input from /dev/urandom, convert relevant characters to random integers, and use those integers as the rgb/x-y values for pixels to paint onto the screen.



I've done some research (here on StackOverflow and elsewhere) and many suggest that you can simply write to /dev/fb0 directly as it is the file representation of the device. Unfortunately, this does not seem to produce any visually apparent results.



I found a sample C program that was from a QT tutorial (no longer available) that used an mmap to write to the buffer. The program runs successfully, but again, no output to the screen. Interestingly enough, when I placed my laptop into Suspend and later restored, I saw a momentary flash of the image (a red square) that was written to the framebuffer much earlier. Does writing to the framebuffer work anymore in Linux for painting to screen? Ideally, I'd like to write a (ba)sh script, but C or similar would work as well. Thanks!



EDIT: Here's the sample program...may look familiar to vets.



#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, %dbppn", 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 = 100; 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
//location += 4;
} 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;
}






c linux framebuffer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 4 '18 at 18:47









Dan Mašek

8,89832647




8,89832647










asked Feb 14 '11 at 20:12









Richard MartinezRichard Martinez

3621615




3621615













  • Ideally, this needs to work for most (all?) Linux systems (DE independent) and other compatibility is appreciated but optional.

    – Richard Martinez
    Feb 14 '11 at 20:31






  • 6





    The framebuffer device is often (but not always) independent of X - try switching to a virtual console with ctrl-alt-f1 or ctrl-alt-f2 and running the demo there.

    – caf
    Feb 14 '11 at 20:41











  • Interesting...that seems to work. Is there any possibility that I would be able to set the display as tty7 (X server)?

    – Richard Martinez
    Feb 14 '11 at 20:58






  • 2





    Note, Wikipedia link[/link] mentions some programs that use the framebuffer directly, like MPlayer. How do they attach the output to the desktop environment?

    – Richard Martinez
    Feb 14 '11 at 21:07








  • 1





    @RichardMartinez: As it says, "Graphic programs avoiding the heavy overhead of the X Window System." Those programs can access it directly when they're not running under X Windows (e.g. on an embedded device with an LCD screen), I think.

    – Craig McQueen
    Mar 20 '13 at 0:40





















  • Ideally, this needs to work for most (all?) Linux systems (DE independent) and other compatibility is appreciated but optional.

    – Richard Martinez
    Feb 14 '11 at 20:31






  • 6





    The framebuffer device is often (but not always) independent of X - try switching to a virtual console with ctrl-alt-f1 or ctrl-alt-f2 and running the demo there.

    – caf
    Feb 14 '11 at 20:41











  • Interesting...that seems to work. Is there any possibility that I would be able to set the display as tty7 (X server)?

    – Richard Martinez
    Feb 14 '11 at 20:58






  • 2





    Note, Wikipedia link[/link] mentions some programs that use the framebuffer directly, like MPlayer. How do they attach the output to the desktop environment?

    – Richard Martinez
    Feb 14 '11 at 21:07








  • 1





    @RichardMartinez: As it says, "Graphic programs avoiding the heavy overhead of the X Window System." Those programs can access it directly when they're not running under X Windows (e.g. on an embedded device with an LCD screen), I think.

    – Craig McQueen
    Mar 20 '13 at 0:40



















Ideally, this needs to work for most (all?) Linux systems (DE independent) and other compatibility is appreciated but optional.

– Richard Martinez
Feb 14 '11 at 20:31





Ideally, this needs to work for most (all?) Linux systems (DE independent) and other compatibility is appreciated but optional.

– Richard Martinez
Feb 14 '11 at 20:31




6




6





The framebuffer device is often (but not always) independent of X - try switching to a virtual console with ctrl-alt-f1 or ctrl-alt-f2 and running the demo there.

– caf
Feb 14 '11 at 20:41





The framebuffer device is often (but not always) independent of X - try switching to a virtual console with ctrl-alt-f1 or ctrl-alt-f2 and running the demo there.

– caf
Feb 14 '11 at 20:41













Interesting...that seems to work. Is there any possibility that I would be able to set the display as tty7 (X server)?

– Richard Martinez
Feb 14 '11 at 20:58





Interesting...that seems to work. Is there any possibility that I would be able to set the display as tty7 (X server)?

– Richard Martinez
Feb 14 '11 at 20:58




2




2





Note, Wikipedia link[/link] mentions some programs that use the framebuffer directly, like MPlayer. How do they attach the output to the desktop environment?

– Richard Martinez
Feb 14 '11 at 21:07







Note, Wikipedia link[/link] mentions some programs that use the framebuffer directly, like MPlayer. How do they attach the output to the desktop environment?

– Richard Martinez
Feb 14 '11 at 21:07






1




1





@RichardMartinez: As it says, "Graphic programs avoiding the heavy overhead of the X Window System." Those programs can access it directly when they're not running under X Windows (e.g. on an embedded device with an LCD screen), I think.

– Craig McQueen
Mar 20 '13 at 0:40







@RichardMartinez: As it says, "Graphic programs avoiding the heavy overhead of the X Window System." Those programs can access it directly when they're not running under X Windows (e.g. on an embedded device with an LCD screen), I think.

– Craig McQueen
Mar 20 '13 at 0:40














6 Answers
6






active

oldest

votes


















7














If you're running X11, you MUST go through X11 APIs to draw to the screen. Going around the X server is very broken (and, often as you've seen, does not work). It may also cause crashes, or just general display corruption.



If you want to be able to run everywhere (both console & under X), look at SDL or GGI. If you only care about X11, you can use GTK, QT, or even Xlib. There are many, many options...






share|improve this answer
























  • Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

    – Richard Martinez
    Feb 14 '11 at 21:21



















10














I've had success with the following few experiments.



First, find out if X is using TrueColor RGB padded to 32 bits (or just assume this is the case). Then find out if you have write permission to fb0 (and that it exists). If these are true (and I expect many modern toolkits/desktops/PCs might use these as defaults), then you should be able to do the following (and if these defaults don't hold, then you probably can still have some success with the following tests though the details may vary):



Test 1: open up a virtual terminal (in X) and type in:
$ echo "ddd ... ddd" >/dev/fb0
where the ... is actually a few screen-fulls of d. The result will be one or more (partial) lines of gray across the top of your screen, depending on how long is your echo string and what pixel resolution you have enabled. You can also pick any letters (the ascii values are all less than 0x80, so the color produced will be a dark gray.. and vary the letters if you want something besides gray). Obviously, this can be generalized to a shell loop or you can cat a large file to see the effect more clearly: eg:
$ cat /lib/libc.so.6 >/dev/fb0
in order to see the true colors of some fsf supporters ;-P



Don't worry if a large chunk of your screen gets written over. X still has control of the mouse pointer and still has its idea of where windows are mapped. All you have to do is to grab any window and drag it around a bit to erase the noise.



Test 2: cat /dev/fb0 > xxx
then change the appearance of your desktop (eg, open new windows and close others).
Finally, do the reverse: cat xxx > /dev/fb0 in order to get your old desktop back!



Ha, well, not quite. The image of your old desktop is an illusion, and you will quickly dispense with it when you open any window to full screen.



Test 3: Write a little app that grabs a prior dump of /dev/fb0 and modifies the colors of the pixels, eg, to remove the red component or augment the blue, or flip the red and green, etc. Then write back these pixels into a new file you can look at later via the simple shell approach of test 2. Also, note that you will likely be dealing with B-G-R-A 4-byte quantities per pixel. This means that you want to ignore every 4th byte and also treat the first in each set as the blue component. "ARGB" is big-endian, so if you visit these bytes through increasing index of a C array, blue would come first, then green, then red.. ie, B-G-R-A (not A-R-G-B).



Test 4: write an app in any language that loops at video speed sending a non square picture (think xeyes) to a part of the screen so as to create an animation without any windows borders. For extra points, have the animation move all over the screen. You will have to make sure to skip a large space after drawing a small row's worth of pixels (to make up for the screen width that is likely much wider than the picture being animated).



Test 5: play a trick on a friend, eg, extend test 4 so that a picture of an animated person appears to pop up on their desktop (maybe film yourself to get the pixel data), then walks over to one of their important desktop folders, picks up the folder and shreds it apart, then starts laughing hysterically, and then have a fireball come out and engulf their entire desktop. Though this will all be an illusion, they may freak out a bit.. but use that as a learning experience to show off Linux and open source and show how its much scarier looking to a novice than it actually is. [the "virus" are generally harmless illusions on Linux]






share|improve this answer





















  • 1





    1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

    – Braden Best
    Sep 23 '15 at 17:32






  • 2





    Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

    – Braden Best
    Sep 23 '15 at 19:52








  • 2





    @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

    – uliwitness
    Oct 1 '15 at 7:37













  • Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

    – Braden Best
    Oct 1 '15 at 14:42











  • (@uliwitness that comment was directed at you)

    – Braden Best
    Oct 1 '15 at 14:49



















2














I'd say be careful before trying writing to /dev/fb0, as suggested above. I tried it under X
in ubuntu 10.04 and a) nothing happened visually, b) it wrecked all shell windows, even other ttys, leading to kernel errors and lack of functionality.






share|improve this answer



















  • 5





    That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

    – Richard Martinez
    Jun 29 '12 at 16:34






  • 2





    As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

    – Alexander
    Oct 24 '12 at 18:58



















1














You should use fb_fix_screeninfo.smem_len for screensize instead of doing the multiplication yourself. The buffer might be align on 4 bytes or something else.



screensize = finfo.smem_len;





share|improve this answer































    0














    When I used this program to write full screen it had crashed that is due screen size calculation is wrong.



    // Figure out the size of the screen in bytes     
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


    This supposed to be:



    /* Calculate the size of the screen in bytes */   
    screensize = vinfo.xres_virtual * vinfo.yres_virtual * (vinfo.bits_per_pixel / 8);





    share|improve this answer

































      0














      if you debug your program, you will find the line:



       screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


      screensize is 0. because vinfo.xres is 0.
      you should change it to:



      long ppc_fx = (((long)fixed_info.smem_start) - ((long) fixed_info.smem_start & ~(PAGE_SIZE-1)));
      screensize = finfo.smem_len + ppc_fx;



      since Linux 2.6.2? , the 2nd arguments of mmap(), screensize, must not be 0. otherwise mmap() will return MAP_FAILED.







      share|improve this answer























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4996777%2fpaint-pixels-to-screen-via-linux-framebuffer%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        6 Answers
        6






        active

        oldest

        votes








        6 Answers
        6






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        7














        If you're running X11, you MUST go through X11 APIs to draw to the screen. Going around the X server is very broken (and, often as you've seen, does not work). It may also cause crashes, or just general display corruption.



        If you want to be able to run everywhere (both console & under X), look at SDL or GGI. If you only care about X11, you can use GTK, QT, or even Xlib. There are many, many options...






        share|improve this answer
























        • Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

          – Richard Martinez
          Feb 14 '11 at 21:21
















        7














        If you're running X11, you MUST go through X11 APIs to draw to the screen. Going around the X server is very broken (and, often as you've seen, does not work). It may also cause crashes, or just general display corruption.



        If you want to be able to run everywhere (both console & under X), look at SDL or GGI. If you only care about X11, you can use GTK, QT, or even Xlib. There are many, many options...






        share|improve this answer
























        • Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

          – Richard Martinez
          Feb 14 '11 at 21:21














        7












        7








        7







        If you're running X11, you MUST go through X11 APIs to draw to the screen. Going around the X server is very broken (and, often as you've seen, does not work). It may also cause crashes, or just general display corruption.



        If you want to be able to run everywhere (both console & under X), look at SDL or GGI. If you only care about X11, you can use GTK, QT, or even Xlib. There are many, many options...






        share|improve this answer













        If you're running X11, you MUST go through X11 APIs to draw to the screen. Going around the X server is very broken (and, often as you've seen, does not work). It may also cause crashes, or just general display corruption.



        If you want to be able to run everywhere (both console & under X), look at SDL or GGI. If you only care about X11, you can use GTK, QT, or even Xlib. There are many, many options...







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 14 '11 at 21:13









        derobertderobert

        39.1k676115




        39.1k676115













        • Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

          – Richard Martinez
          Feb 14 '11 at 21:21



















        • Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

          – Richard Martinez
          Feb 14 '11 at 21:21

















        Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

        – Richard Martinez
        Feb 14 '11 at 21:21





        Thanks for the tip. Between this and caf's comment above, I've realized just how low-level the framebuffer is. I think I'll stick with it for simplicity for this script, but I will definitely be using higher level systems (at least X) if I'm interesting in something more complex.

        – Richard Martinez
        Feb 14 '11 at 21:21













        10














        I've had success with the following few experiments.



        First, find out if X is using TrueColor RGB padded to 32 bits (or just assume this is the case). Then find out if you have write permission to fb0 (and that it exists). If these are true (and I expect many modern toolkits/desktops/PCs might use these as defaults), then you should be able to do the following (and if these defaults don't hold, then you probably can still have some success with the following tests though the details may vary):



        Test 1: open up a virtual terminal (in X) and type in:
        $ echo "ddd ... ddd" >/dev/fb0
        where the ... is actually a few screen-fulls of d. The result will be one or more (partial) lines of gray across the top of your screen, depending on how long is your echo string and what pixel resolution you have enabled. You can also pick any letters (the ascii values are all less than 0x80, so the color produced will be a dark gray.. and vary the letters if you want something besides gray). Obviously, this can be generalized to a shell loop or you can cat a large file to see the effect more clearly: eg:
        $ cat /lib/libc.so.6 >/dev/fb0
        in order to see the true colors of some fsf supporters ;-P



        Don't worry if a large chunk of your screen gets written over. X still has control of the mouse pointer and still has its idea of where windows are mapped. All you have to do is to grab any window and drag it around a bit to erase the noise.



        Test 2: cat /dev/fb0 > xxx
        then change the appearance of your desktop (eg, open new windows and close others).
        Finally, do the reverse: cat xxx > /dev/fb0 in order to get your old desktop back!



        Ha, well, not quite. The image of your old desktop is an illusion, and you will quickly dispense with it when you open any window to full screen.



        Test 3: Write a little app that grabs a prior dump of /dev/fb0 and modifies the colors of the pixels, eg, to remove the red component or augment the blue, or flip the red and green, etc. Then write back these pixels into a new file you can look at later via the simple shell approach of test 2. Also, note that you will likely be dealing with B-G-R-A 4-byte quantities per pixel. This means that you want to ignore every 4th byte and also treat the first in each set as the blue component. "ARGB" is big-endian, so if you visit these bytes through increasing index of a C array, blue would come first, then green, then red.. ie, B-G-R-A (not A-R-G-B).



        Test 4: write an app in any language that loops at video speed sending a non square picture (think xeyes) to a part of the screen so as to create an animation without any windows borders. For extra points, have the animation move all over the screen. You will have to make sure to skip a large space after drawing a small row's worth of pixels (to make up for the screen width that is likely much wider than the picture being animated).



        Test 5: play a trick on a friend, eg, extend test 4 so that a picture of an animated person appears to pop up on their desktop (maybe film yourself to get the pixel data), then walks over to one of their important desktop folders, picks up the folder and shreds it apart, then starts laughing hysterically, and then have a fireball come out and engulf their entire desktop. Though this will all be an illusion, they may freak out a bit.. but use that as a learning experience to show off Linux and open source and show how its much scarier looking to a novice than it actually is. [the "virus" are generally harmless illusions on Linux]






        share|improve this answer





















        • 1





          1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

          – Braden Best
          Sep 23 '15 at 17:32






        • 2





          Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

          – Braden Best
          Sep 23 '15 at 19:52








        • 2





          @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

          – uliwitness
          Oct 1 '15 at 7:37













        • Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

          – Braden Best
          Oct 1 '15 at 14:42











        • (@uliwitness that comment was directed at you)

          – Braden Best
          Oct 1 '15 at 14:49
















        10














        I've had success with the following few experiments.



        First, find out if X is using TrueColor RGB padded to 32 bits (or just assume this is the case). Then find out if you have write permission to fb0 (and that it exists). If these are true (and I expect many modern toolkits/desktops/PCs might use these as defaults), then you should be able to do the following (and if these defaults don't hold, then you probably can still have some success with the following tests though the details may vary):



        Test 1: open up a virtual terminal (in X) and type in:
        $ echo "ddd ... ddd" >/dev/fb0
        where the ... is actually a few screen-fulls of d. The result will be one or more (partial) lines of gray across the top of your screen, depending on how long is your echo string and what pixel resolution you have enabled. You can also pick any letters (the ascii values are all less than 0x80, so the color produced will be a dark gray.. and vary the letters if you want something besides gray). Obviously, this can be generalized to a shell loop or you can cat a large file to see the effect more clearly: eg:
        $ cat /lib/libc.so.6 >/dev/fb0
        in order to see the true colors of some fsf supporters ;-P



        Don't worry if a large chunk of your screen gets written over. X still has control of the mouse pointer and still has its idea of where windows are mapped. All you have to do is to grab any window and drag it around a bit to erase the noise.



        Test 2: cat /dev/fb0 > xxx
        then change the appearance of your desktop (eg, open new windows and close others).
        Finally, do the reverse: cat xxx > /dev/fb0 in order to get your old desktop back!



        Ha, well, not quite. The image of your old desktop is an illusion, and you will quickly dispense with it when you open any window to full screen.



        Test 3: Write a little app that grabs a prior dump of /dev/fb0 and modifies the colors of the pixels, eg, to remove the red component or augment the blue, or flip the red and green, etc. Then write back these pixels into a new file you can look at later via the simple shell approach of test 2. Also, note that you will likely be dealing with B-G-R-A 4-byte quantities per pixel. This means that you want to ignore every 4th byte and also treat the first in each set as the blue component. "ARGB" is big-endian, so if you visit these bytes through increasing index of a C array, blue would come first, then green, then red.. ie, B-G-R-A (not A-R-G-B).



        Test 4: write an app in any language that loops at video speed sending a non square picture (think xeyes) to a part of the screen so as to create an animation without any windows borders. For extra points, have the animation move all over the screen. You will have to make sure to skip a large space after drawing a small row's worth of pixels (to make up for the screen width that is likely much wider than the picture being animated).



        Test 5: play a trick on a friend, eg, extend test 4 so that a picture of an animated person appears to pop up on their desktop (maybe film yourself to get the pixel data), then walks over to one of their important desktop folders, picks up the folder and shreds it apart, then starts laughing hysterically, and then have a fireball come out and engulf their entire desktop. Though this will all be an illusion, they may freak out a bit.. but use that as a learning experience to show off Linux and open source and show how its much scarier looking to a novice than it actually is. [the "virus" are generally harmless illusions on Linux]






        share|improve this answer





















        • 1





          1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

          – Braden Best
          Sep 23 '15 at 17:32






        • 2





          Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

          – Braden Best
          Sep 23 '15 at 19:52








        • 2





          @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

          – uliwitness
          Oct 1 '15 at 7:37













        • Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

          – Braden Best
          Oct 1 '15 at 14:42











        • (@uliwitness that comment was directed at you)

          – Braden Best
          Oct 1 '15 at 14:49














        10












        10








        10







        I've had success with the following few experiments.



        First, find out if X is using TrueColor RGB padded to 32 bits (or just assume this is the case). Then find out if you have write permission to fb0 (and that it exists). If these are true (and I expect many modern toolkits/desktops/PCs might use these as defaults), then you should be able to do the following (and if these defaults don't hold, then you probably can still have some success with the following tests though the details may vary):



        Test 1: open up a virtual terminal (in X) and type in:
        $ echo "ddd ... ddd" >/dev/fb0
        where the ... is actually a few screen-fulls of d. The result will be one or more (partial) lines of gray across the top of your screen, depending on how long is your echo string and what pixel resolution you have enabled. You can also pick any letters (the ascii values are all less than 0x80, so the color produced will be a dark gray.. and vary the letters if you want something besides gray). Obviously, this can be generalized to a shell loop or you can cat a large file to see the effect more clearly: eg:
        $ cat /lib/libc.so.6 >/dev/fb0
        in order to see the true colors of some fsf supporters ;-P



        Don't worry if a large chunk of your screen gets written over. X still has control of the mouse pointer and still has its idea of where windows are mapped. All you have to do is to grab any window and drag it around a bit to erase the noise.



        Test 2: cat /dev/fb0 > xxx
        then change the appearance of your desktop (eg, open new windows and close others).
        Finally, do the reverse: cat xxx > /dev/fb0 in order to get your old desktop back!



        Ha, well, not quite. The image of your old desktop is an illusion, and you will quickly dispense with it when you open any window to full screen.



        Test 3: Write a little app that grabs a prior dump of /dev/fb0 and modifies the colors of the pixels, eg, to remove the red component or augment the blue, or flip the red and green, etc. Then write back these pixels into a new file you can look at later via the simple shell approach of test 2. Also, note that you will likely be dealing with B-G-R-A 4-byte quantities per pixel. This means that you want to ignore every 4th byte and also treat the first in each set as the blue component. "ARGB" is big-endian, so if you visit these bytes through increasing index of a C array, blue would come first, then green, then red.. ie, B-G-R-A (not A-R-G-B).



        Test 4: write an app in any language that loops at video speed sending a non square picture (think xeyes) to a part of the screen so as to create an animation without any windows borders. For extra points, have the animation move all over the screen. You will have to make sure to skip a large space after drawing a small row's worth of pixels (to make up for the screen width that is likely much wider than the picture being animated).



        Test 5: play a trick on a friend, eg, extend test 4 so that a picture of an animated person appears to pop up on their desktop (maybe film yourself to get the pixel data), then walks over to one of their important desktop folders, picks up the folder and shreds it apart, then starts laughing hysterically, and then have a fireball come out and engulf their entire desktop. Though this will all be an illusion, they may freak out a bit.. but use that as a learning experience to show off Linux and open source and show how its much scarier looking to a novice than it actually is. [the "virus" are generally harmless illusions on Linux]






        share|improve this answer















        I've had success with the following few experiments.



        First, find out if X is using TrueColor RGB padded to 32 bits (or just assume this is the case). Then find out if you have write permission to fb0 (and that it exists). If these are true (and I expect many modern toolkits/desktops/PCs might use these as defaults), then you should be able to do the following (and if these defaults don't hold, then you probably can still have some success with the following tests though the details may vary):



        Test 1: open up a virtual terminal (in X) and type in:
        $ echo "ddd ... ddd" >/dev/fb0
        where the ... is actually a few screen-fulls of d. The result will be one or more (partial) lines of gray across the top of your screen, depending on how long is your echo string and what pixel resolution you have enabled. You can also pick any letters (the ascii values are all less than 0x80, so the color produced will be a dark gray.. and vary the letters if you want something besides gray). Obviously, this can be generalized to a shell loop or you can cat a large file to see the effect more clearly: eg:
        $ cat /lib/libc.so.6 >/dev/fb0
        in order to see the true colors of some fsf supporters ;-P



        Don't worry if a large chunk of your screen gets written over. X still has control of the mouse pointer and still has its idea of where windows are mapped. All you have to do is to grab any window and drag it around a bit to erase the noise.



        Test 2: cat /dev/fb0 > xxx
        then change the appearance of your desktop (eg, open new windows and close others).
        Finally, do the reverse: cat xxx > /dev/fb0 in order to get your old desktop back!



        Ha, well, not quite. The image of your old desktop is an illusion, and you will quickly dispense with it when you open any window to full screen.



        Test 3: Write a little app that grabs a prior dump of /dev/fb0 and modifies the colors of the pixels, eg, to remove the red component or augment the blue, or flip the red and green, etc. Then write back these pixels into a new file you can look at later via the simple shell approach of test 2. Also, note that you will likely be dealing with B-G-R-A 4-byte quantities per pixel. This means that you want to ignore every 4th byte and also treat the first in each set as the blue component. "ARGB" is big-endian, so if you visit these bytes through increasing index of a C array, blue would come first, then green, then red.. ie, B-G-R-A (not A-R-G-B).



        Test 4: write an app in any language that loops at video speed sending a non square picture (think xeyes) to a part of the screen so as to create an animation without any windows borders. For extra points, have the animation move all over the screen. You will have to make sure to skip a large space after drawing a small row's worth of pixels (to make up for the screen width that is likely much wider than the picture being animated).



        Test 5: play a trick on a friend, eg, extend test 4 so that a picture of an animated person appears to pop up on their desktop (maybe film yourself to get the pixel data), then walks over to one of their important desktop folders, picks up the folder and shreds it apart, then starts laughing hysterically, and then have a fireball come out and engulf their entire desktop. Though this will all be an illusion, they may freak out a bit.. but use that as a learning experience to show off Linux and open source and show how its much scarier looking to a novice than it actually is. [the "virus" are generally harmless illusions on Linux]







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 8 '11 at 12:47

























        answered May 8 '11 at 12:39









        Jose_XJose_X

        834711




        834711








        • 1





          1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

          – Braden Best
          Sep 23 '15 at 17:32






        • 2





          Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

          – Braden Best
          Sep 23 '15 at 19:52








        • 2





          @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

          – uliwitness
          Oct 1 '15 at 7:37













        • Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

          – Braden Best
          Oct 1 '15 at 14:42











        • (@uliwitness that comment was directed at you)

          – Braden Best
          Oct 1 '15 at 14:49














        • 1





          1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

          – Braden Best
          Sep 23 '15 at 17:32






        • 2





          Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

          – Braden Best
          Sep 23 '15 at 19:52








        • 2





          @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

          – uliwitness
          Oct 1 '15 at 7:37













        • Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

          – Braden Best
          Oct 1 '15 at 14:42











        • (@uliwitness that comment was directed at you)

          – Braden Best
          Oct 1 '15 at 14:49








        1




        1





        1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

        – Braden Best
        Sep 23 '15 at 17:32





        1. I've never been able to affect X with the framebuffer. It only works in a TTY. 2. It's actually BGRT. You'll see it referenced if you pay notice to the kernel messages around the time it sets up the fb device during boot. I don't know what the T means, but it certainly isn't alpha or "transparency". In fact, the fourth byte doesn't seem to do anything at all. I've tried drawing colors with the fourth byte ranging from 0 to 255, and it looks exactly the same. I guess they're just saving a fourth channel in case aliens introduce us to new colors or something.

        – Braden Best
        Sep 23 '15 at 17:32




        2




        2





        Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

        – Braden Best
        Sep 23 '15 at 19:52







        Edit: Found out that the T in BGRT actually is transparency. Also confirmed straight from the horse's mouth that it's BGRT and not BGRA. Though I still can't get transparency to make anything, well, transparent.

        – Braden Best
        Sep 23 '15 at 19:52






        2




        2





        @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

        – uliwitness
        Oct 1 '15 at 7:37







        @B1KMusic AIUI you're not getting transparency because the frame buffer is the "backmost" thing. There is nothing "behind" it. T is just a dummy value for most devices. If you had a special framebuffer device talking to a screen that supports transparency/opacity (e.g. a TFT that can also generate white pixels, not just transparent ones that let the backlight shine through) you'd see an effect. Also, you're overwriting the backbuffer, so you're smashing any previous values and would have to account for Alpha yourself.

        – uliwitness
        Oct 1 '15 at 7:37















        Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

        – Braden Best
        Oct 1 '15 at 14:42





        Yep, trying to set 0x00 to 0xFF for the first byte is not magically going to set it to 0x77 if the fourth byte is 0x77, or whatever would be interpreted as 50%. I do seem to recall implementing some sort of algorithm to take two colors and an alpha value, and return the resulting color. I believe I found said algorithm, so here's a demo showing what I'm talking about.

        – Braden Best
        Oct 1 '15 at 14:42













        (@uliwitness that comment was directed at you)

        – Braden Best
        Oct 1 '15 at 14:49





        (@uliwitness that comment was directed at you)

        – Braden Best
        Oct 1 '15 at 14:49











        2














        I'd say be careful before trying writing to /dev/fb0, as suggested above. I tried it under X
        in ubuntu 10.04 and a) nothing happened visually, b) it wrecked all shell windows, even other ttys, leading to kernel errors and lack of functionality.






        share|improve this answer



















        • 5





          That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

          – Richard Martinez
          Jun 29 '12 at 16:34






        • 2





          As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

          – Alexander
          Oct 24 '12 at 18:58
















        2














        I'd say be careful before trying writing to /dev/fb0, as suggested above. I tried it under X
        in ubuntu 10.04 and a) nothing happened visually, b) it wrecked all shell windows, even other ttys, leading to kernel errors and lack of functionality.






        share|improve this answer



















        • 5





          That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

          – Richard Martinez
          Jun 29 '12 at 16:34






        • 2





          As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

          – Alexander
          Oct 24 '12 at 18:58














        2












        2








        2







        I'd say be careful before trying writing to /dev/fb0, as suggested above. I tried it under X
        in ubuntu 10.04 and a) nothing happened visually, b) it wrecked all shell windows, even other ttys, leading to kernel errors and lack of functionality.






        share|improve this answer













        I'd say be careful before trying writing to /dev/fb0, as suggested above. I tried it under X
        in ubuntu 10.04 and a) nothing happened visually, b) it wrecked all shell windows, even other ttys, leading to kernel errors and lack of functionality.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jun 28 '12 at 17:06









        DavidDavid

        211




        211








        • 5





          That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

          – Richard Martinez
          Jun 29 '12 at 16:34






        • 2





          As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

          – Alexander
          Oct 24 '12 at 18:58














        • 5





          That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

          – Richard Martinez
          Jun 29 '12 at 16:34






        • 2





          As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

          – Alexander
          Oct 24 '12 at 18:58








        5




        5





        That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

        – Richard Martinez
        Jun 29 '12 at 16:34





        That's interesting. I've performed this (cat /dev/urandom > /dev/fb0) on a few different systems, and I typically get no output while on X but a cool screen full of random pixels if I'm on one of the virtual tty's. I'm surprised that something like that would ruin other parts of the OS, but maybe X freaked when it say stuff was drawn on screen already.

        – Richard Martinez
        Jun 29 '12 at 16:34




        2




        2





        As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

        – Alexander
        Oct 24 '12 at 18:58





        As I understand, if X uses the framebuffer and KMS is used, writing random values to the graphics memory (/dev/fd0) is more likely to work than if X uses its own way of managing graphics.

        – Alexander
        Oct 24 '12 at 18:58











        1














        You should use fb_fix_screeninfo.smem_len for screensize instead of doing the multiplication yourself. The buffer might be align on 4 bytes or something else.



        screensize = finfo.smem_len;





        share|improve this answer




























          1














          You should use fb_fix_screeninfo.smem_len for screensize instead of doing the multiplication yourself. The buffer might be align on 4 bytes or something else.



          screensize = finfo.smem_len;





          share|improve this answer


























            1












            1








            1







            You should use fb_fix_screeninfo.smem_len for screensize instead of doing the multiplication yourself. The buffer might be align on 4 bytes or something else.



            screensize = finfo.smem_len;





            share|improve this answer













            You should use fb_fix_screeninfo.smem_len for screensize instead of doing the multiplication yourself. The buffer might be align on 4 bytes or something else.



            screensize = finfo.smem_len;






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 11 '16 at 22:17









            Alex ArsenaultAlex Arsenault

            111




            111























                0














                When I used this program to write full screen it had crashed that is due screen size calculation is wrong.



                // Figure out the size of the screen in bytes     
                screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                This supposed to be:



                /* Calculate the size of the screen in bytes */   
                screensize = vinfo.xres_virtual * vinfo.yres_virtual * (vinfo.bits_per_pixel / 8);





                share|improve this answer






























                  0














                  When I used this program to write full screen it had crashed that is due screen size calculation is wrong.



                  // Figure out the size of the screen in bytes     
                  screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                  This supposed to be:



                  /* Calculate the size of the screen in bytes */   
                  screensize = vinfo.xres_virtual * vinfo.yres_virtual * (vinfo.bits_per_pixel / 8);





                  share|improve this answer




























                    0












                    0








                    0







                    When I used this program to write full screen it had crashed that is due screen size calculation is wrong.



                    // Figure out the size of the screen in bytes     
                    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                    This supposed to be:



                    /* Calculate the size of the screen in bytes */   
                    screensize = vinfo.xres_virtual * vinfo.yres_virtual * (vinfo.bits_per_pixel / 8);





                    share|improve this answer















                    When I used this program to write full screen it had crashed that is due screen size calculation is wrong.



                    // Figure out the size of the screen in bytes     
                    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                    This supposed to be:



                    /* Calculate the size of the screen in bytes */   
                    screensize = vinfo.xres_virtual * vinfo.yres_virtual * (vinfo.bits_per_pixel / 8);






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited May 23 '14 at 9:25









                    Getz

                    3,20262948




                    3,20262948










                    answered May 23 '14 at 9:06









                    Nataraja KMNataraja KM

                    91




                    91























                        0














                        if you debug your program, you will find the line:



                         screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                        screensize is 0. because vinfo.xres is 0.
                        you should change it to:



                        long ppc_fx = (((long)fixed_info.smem_start) - ((long) fixed_info.smem_start & ~(PAGE_SIZE-1)));
                        screensize = finfo.smem_len + ppc_fx;



                        since Linux 2.6.2? , the 2nd arguments of mmap(), screensize, must not be 0. otherwise mmap() will return MAP_FAILED.







                        share|improve this answer




























                          0














                          if you debug your program, you will find the line:



                           screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                          screensize is 0. because vinfo.xres is 0.
                          you should change it to:



                          long ppc_fx = (((long)fixed_info.smem_start) - ((long) fixed_info.smem_start & ~(PAGE_SIZE-1)));
                          screensize = finfo.smem_len + ppc_fx;



                          since Linux 2.6.2? , the 2nd arguments of mmap(), screensize, must not be 0. otherwise mmap() will return MAP_FAILED.







                          share|improve this answer


























                            0












                            0








                            0







                            if you debug your program, you will find the line:



                             screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                            screensize is 0. because vinfo.xres is 0.
                            you should change it to:



                            long ppc_fx = (((long)fixed_info.smem_start) - ((long) fixed_info.smem_start & ~(PAGE_SIZE-1)));
                            screensize = finfo.smem_len + ppc_fx;



                            since Linux 2.6.2? , the 2nd arguments of mmap(), screensize, must not be 0. otherwise mmap() will return MAP_FAILED.







                            share|improve this answer













                            if you debug your program, you will find the line:



                             screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;


                            screensize is 0. because vinfo.xres is 0.
                            you should change it to:



                            long ppc_fx = (((long)fixed_info.smem_start) - ((long) fixed_info.smem_start & ~(PAGE_SIZE-1)));
                            screensize = finfo.smem_len + ppc_fx;



                            since Linux 2.6.2? , the 2nd arguments of mmap(), screensize, must not be 0. otherwise mmap() will return MAP_FAILED.








                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jun 12 '16 at 16:39









                            Hsiang ChenHsiang Chen

                            11




                            11






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4996777%2fpaint-pixels-to-screen-via-linux-framebuffer%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Florida Star v. B. J. F.

                                Danny Elfman

                                Lugert, Oklahoma