我正在尝试编写与“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
答案 0 :(得分:0)
您的代码适用于我,使用Xephyr进行测试。我的猜测(正如我已经评论过的)在您的设置根窗口中被DE遮挡,例如在ubuntu中可能会有'nautilus'运行全屏以提供桌面/图标/ DnD /橡皮筋选择功能。
答案 1 :(得分:0)
Xscreensaver不要求你在根窗口上绘图,实际上这不起作用。 Xscreensaver创建“虚拟根目录”,“虚拟根感知”程序将此虚拟根窗口视为根窗口(它不是根窗口)。最好的办法是检查Xscreensaver设置的环境变量(XSCREENSAVER_WINDOW)以找到虚拟根的窗口ID并绘制到该窗口。