我最近被一个奇怪的 idea 打动了:从/dev/uradom获取输入,将相关字符转换为随机整数,并将这些整数用作要在屏幕上绘制的像素的rgb/x-y值.

我做了一些研究(这里是关于StackOverflow和其他地方的),许多人建议您可以直接写入/dev/fb0,因为它是设备的文件表示形式.不幸的是,这似乎没有产生任何明显的视觉效果.

我发现一个示例C程序来自一个QT教程(不再提供),它使用mmap写入缓冲区.程序运行成功,但同样没有输出到屏幕.有趣的是,当我将笔记本电脑置于暂停状态并随后恢复时,我看到了一个瞬间的图像(红色方块),该图像在很久以前就写入了帧缓冲区.在Linux中,写入帧缓冲区是否可以用于绘制屏幕?理想情况下,我想写一个(ba)sh脚本,但C或类似的也可以.谢谢

编辑:这里是示 routine 序...在兽医看来可能很熟悉.

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

推荐答案

如果运行的是X11,则必须通过X11 API才能绘制到屏幕上.在X服务器上运行是非常糟糕的(而且,正如您所看到的,经常是不起作用的).它还可能导致崩溃,或者只是一般的显示损坏.

如果你想在任何地方都能运行(包括控制台和X下),可以看看SDL或GGI.如果您只关心X11,那么可以使用GTK、QT甚至Xlib.有很多很多 Select ...

Linux相关问答推荐

在Zenity进度窗口上单击取消后如何停止bash脚本

为什么我的Linuxshell 程序有时找不到它刚刚创建的文件?

在 cURL 中使用的确切位置将字节分成一些范围部分

根据外部请求在 Netbeans 中启动 XDebug

如何安装脚本以从命令行的任何位置运行?

Bash 变量:是否区分大小写?

从 shell 将多个 .sql 转储文件导入 mysql 数据库

为什么 XGrabKey 会生成额外的聚焦和聚焦事件?

如何在 Ubuntu 12.04 中更改 Jenkins 安装的端口号

如何从 linux 的命令行将 Sublime Text 2 文件打开到选项卡,而不是新窗口

为什么可执行文件操作系统依赖于?

使用inotify的正确方法是什么?

为什么`du`的输出通常与`du -b`如此不同

我可以告诉 Linux 不要换出特定进程的内存吗?

命令行 Arduino 编译和上传?

如何自动化 HTML 到 PDF 的转换?

在 shell 脚本的 for 循环中迭代行而不是单词

使用 Bash 查找和复制文件

从文件中随机 Select 行而不用 Unix 啜饮它

如何计算一个单词在目录的所有文件中出现的次数?