Malen Sie die Pixel auf dem Bildschirm über Linux FrameBuffer

Ich war vor kurzem aufgefallen, eine kuriose Idee, um die Eingabe von /dev/urandom, konvertieren relevante Zeichen, die zufällige Ganzzahlen und verwenden Sie diesen Integer-zahlen, wie die rgb/x-y-Werte für die Pixel, um die Farbe auf den Bildschirm.

Ich habe einige der Forschung getan (hier auf StackOverflow und anderswo) und viele vermuten, dass Sie können schreiben Sie einfach an /dev/fb0 direkt, wie es ist die Datei, die die Darstellung des Geräts. Leider scheint dies nicht zu keinem optisch sichtbarem Ergebnis.

Fand ich ein Beispiel-C-Programm, das vom QT-tutorial (nicht mehr erhältlich), mit einer mmap zum schreiben in den Puffer. Wird das Programm erfolgreich ausgeführt, aber wieder, keine Ausgabe auf dem Bildschirm. Interessanterweise, wenn ich legte meine laptop in den Ruhezustand und später wiederhergestellt, sah ich einen momentanen Blitz der das Bild (rotes Quadrat), die geschrieben wurde, um den framebuffer viel früher. Hat das schreiben in den framebuffer mehr in Linux für die Malerei zu Bild? Im Idealfall würde ich gerne schreiben (ba)sh-script, aber C oder ähnlich funktionieren würde, wie gut. Danke!

EDIT: Hier das sample-Programm...kann vertraut Tierärzte.

#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 = 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;
}

InformationsquelleAutor der Frage Richard Martinez | 2011-02-14

Schreibe einen Kommentar