The code below is supposed to make root window white, but does nothing. Compiles and runs with no errors. I omitted only includes and variable definitions.
int
main(int argc, char **argv) {
dpy = XOpenDisplay(NULL);
if (!dpy) {
fputs("cannot open display\n", stderr);
return EXIT_FAILURE;
}
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
vis = DefaultVisual(dpy, screen);
depth = DefaultDepth(dpy, screen);
height = DisplayHeight(dpy, screen);
width = DisplayWidth(dpy, screen);
img = malloc(depth/8 * height * width);
if (img == NULL) {
perror("malloc() failed");
return EXIT_FAILURE;
}
memset(img, 0xFF, depth/8 * height * width);
ximg = XCreateImage(dpy, vis, depth, ZPixmap, 0, img, width, height, 32, 0);
pm = XCreatePixmap(dpy, root, width, height, depth);
gc = XCreateGC(dpy, pm, 0, NULL);
XPutImage(dpy, pm, gc, ximg, 0, 0, 0, 0, width, height);
XSetWindowBackgroundPixmap(dpy, root, pm);
XClearWindow(dpy, root);
XFlush(dpy);
XDestroyImage(ximg);
XFreePixmap(dpy, pm);
XFreeGC(dpy, gc);
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}
How do I even start troubleshooting this? removing XClearWindow(dpy, root);
does not help.
Apparently XSetWindowBackgroundPixmap()
needs some prior atom setup. This borrowed function fixed the issue.
// Adapted from fluxbox' bsetroot
int
setRootAtoms(Pixmap pixmap)
{
Atom atom_root, atom_eroot, type;
unsigned char *data_root, *data_eroot;
int format;
unsigned long length, after;
atom_root = XInternAtom(display, "_XROOTMAP_ID", True);
atom_eroot = XInternAtom(display, "ESETROOT_PMAP_ID", True);
// doing this to clean up after old background
if (atom_root != None && atom_eroot != None) {
XGetWindowProperty(display, RootWindow(display, screen), atom_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root);
if (type == XA_PIXMAP) {
XGetWindowProperty(display, RootWindow(display, screen), atom_eroot, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_eroot);
if (data_root && data_eroot && type == XA_PIXMAP && *((Pixmap *) data_root) == *((Pixmap *) data_eroot))
XKillClient(display, *((Pixmap *) data_root));
}
}
atom_root = XInternAtom(display, "_XROOTPMAP_ID", False);
atom_eroot = XInternAtom(display, "ESETROOT_PMAP_ID", False);
if (atom_root == None || atom_eroot == None)
return 0;
// setting new background atoms
XChangeProperty(display, RootWindow(display, screen), atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pixmap, 1);
XChangeProperty(display, RootWindow(display, screen), atom_eroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pixmap, 1);
return 1;
}