XPutImage到DefaultRootWindow()什么都没有

时间:2014-03-10 19:58:34

标签: x11 xlib xorg

我正在尝试编写与“xscreensaver”-package兼容的屏幕保护程序。 这需要程序在根窗口中绘制内容。 我自己创建一个非root窗口时运行正常,例如:

Window window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0, width, height, 1, 0, 0);

将其绘制到

窗口窗口= DefaultRootWindow(显示);

反而什么都没有。 我尝试从xscreensaver-demo,xterm,没有窗口管理器的环境中运行它,但他们给出的只是黑色。 在我启动它的终端中,没有显示X11错误。 我的错误处理程序也没有被触发。 我想我现在最大的问题是我找不到(甚至没有google)如何调试这样的东西。

感谢任何帮助!

以下是代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

void draw(char *rgb_out, int w, int h)
{
        for(int i=0; i<w*h*4; i++)
                *rgb_out++ = rand();
}

XImage *create_ximage(Display *display, Visual *visual, int width, int height)
{
        char *image32 = (char *)malloc(width * height * 4);
        draw(image32, width, height);
        return XCreateImage(display, visual, 24, ZPixmap, 0, image32, width, height, 32, 0);
}

int x11_err_handler(Display *pd, XErrorEvent *pxev)
{
        char msg[4096] = { 0 };
        XGetErrorText(pd, pxev -> error_code, msg, sizeof(msg));
        printf("%s\n", msg);
        return 0;
}

int main(int argc, char **argv)
{
        Display *display = XOpenDisplay(getenv("DISPLAY"));

        Window window = DefaultRootWindow(display);

        XWindowAttributes wa;
        XGetWindowAttributes(display, window, &wa);
        int width = wa.width, height = wa.height;
        printf("res: %dx%d\n", width, height);

        GC gc = XCreateGC(display, window, 0, NULL);
        Visual *visual = DefaultVisual(display, 0);

        XSetErrorHandler(x11_err_handler);

        for(;;)
        {
                XImage *ximage = create_ximage(display, visual, width, height);
                XPutImage(display, window, gc, ximage, 0, 0, 0, 0, width, height);
                XDestroyImage(ximage);

                XFlush(display);

                usleep(50000);
        }

        return 0;
}

可以使用以下方法编译:

g++ -O3 -lX11 -lXpm so.cpp

2 个答案:

答案 0 :(得分:0)

您的代码适用于我,使用Xephyr进行测试。我的猜测(正如我已经评论过的)在您的设置根窗口中被DE遮挡,例如在ubuntu中可能会有'nautilus'运行全屏以提供桌面/图标/ DnD /橡皮筋选择功能。

答案 1 :(得分:0)

Xscreensaver不要求你在根窗口上绘图,实际上这不起作用。 Xscreensaver创建“虚拟根目录”,“虚拟根感知”程序将此虚拟根窗口视为根窗口(它不是根窗口)。最好的办法是检查Xscreensaver设置的环境变量(XSCREENSAVER_WINDOW)以找到虚拟根的窗口ID并绘制到该窗口。