beardeadclown
beardeadclown

Reputation: 377

Drawing to X11 root window

I've followed How to upload 32 bit image to server-side pixmap and XDestroy(ximg); segfaults.

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

Also, according to How to draw an image from file on window with Xlib I should include something like

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

before cleaning up, but how/when do I give system resources back then?

UPDATE

Apparently free(img); was causing the segfault, because XDestroyImage(ximg); is itself freeing the image. But still, where do I put that event loop and what terminating condition should it have so that I can free system resources accordingly?

Upvotes: 2

Views: 2066

Answers (1)

beardeadclown
beardeadclown

Reputation: 377

According to 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.

So free(img); is redundant and will cause a SegFault.

Upvotes: 1

Related Questions