1

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?

beardeadclown
  • 327
  • 2
  • 14
  • 1
    You should not write two independent questions into one post. Instead of editing the answer into the question it is better to write an answer. (Yes, you can answer your own question.) This will show that the question was answered. I just wanted to write a comment citing a [documentation of XDestroyImage](https://tronche.com/gui/x/xlib/utilities/XDestroyImage.html). I suggest to add soemething like this to the answer. I further suggest to post a separate question for the still unanswered part. – Bodo Aug 12 '21 at 15:07
  • If you want to *draw* on a root window, you need to have a regular X11 client program that *draws* on a root window, and runs forever (or until you don't want that image any more). If you want to *set* a root pixmap without keeping your program running, and let the X server deal with it, look [here](https://github.com/himdel/hsetroot). – n. m. could be an AI Aug 12 '21 at 16:51

1 Answers1

1

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.

beardeadclown
  • 327
  • 2
  • 14