设置 X11 root window 像素图

Setting X11 root window pixmap

下面的代码应该使 root window 变白,但什么也没做。编译并运行没有错误。我只省略了包含和变量定义。

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

我该如何开始对此进行故障排除?删除 XClearWindow(dpy, root); 没有帮助。

显然 XSetWindowBackgroundPixmap() 需要一些预先的原子设置。 borrowed function 解决了这个问题。

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