绘图到 X11 根 window

Drawing to X11 root window

我关注了 How to upload 32 bit image to server-side pixmapXDestroy(ximg); 段错误。

#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int
main(int argc, char **argv) {
    Display  *dpy;
    Window    root;
    Screen   *screen;
    GC        gc;
    XImage   *ximg;
    Pixmap    pm;
    int depth, h, w;
    char *img;
    dpy = XOpenDisplay(0);
    if (!dpy) {
        fputs("cannot open display\n", stderr);
        return 1;
    }
    screen = DefaultScreenOfDisplay(dpy);
    h = HeightOfScreen(screen);
    w = WidthOfScreen(screen);
    root = DefaultRootWindow(dpy);
    depth = DefaultDepth(dpy, DefaultScreen(dpy));
    img = malloc(depth/8 * h * w);
    if (img == NULL) {
        perror("malloc() failed");
        return 1;
    }
    memset(img, 0xFF, depth/8 * h * w);
    ximg = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, img, w, h, 32, 0);
    pm = XCreatePixmap(dpy, root, w, h, depth);
    gc = XCreateGC(dpy, pm, 0, NULL);
    XPutImage(dpy, pm, gc, ximg, 0, 0, 0, 0, w, h);
    XCopyArea(dpy, pm, root, gc, 0, 0, w, h, 0, 0);
    free(img);
    XFreePixmap(dpy, pm);
    XDestroyImage(ximg);
    XFreeGC(dpy, gc);
    XCloseDisplay(dpy);
    return 0;
}

此外,根据 How to draw an image from file on window with Xlib 我应该包括类似

的内容
XEvent ev;
while (1) {
    XNextEvent(dpy, &ev);
    if (ev.type == Expose)
        XCopyArea(dpy, pm, root, gc, 0, 0, w, h, 0, 0);
}

在清理之前,但是 how/when 那时我是否还给系统资源?

更新

显然是 free(img); 导致了段错误,因为 XDestroyImage(ximg); 本身正在释放图像。但是,我应该把那个事件循环放在哪里,它应该有什么终止条件,以便我可以相应地释放系统资源?

根据XDestroyImage(3)

Note that when the image is created using XCreateImage, XGetImage, or XSubImage, the destroy procedure that the XDestroyImage function calls frees both the image structure and the data pointed to by the image structure.

所以 free(img); 是多余的,会导致段错误。