X11/XCB/Xlib: 复制根window到pixmap

X11/XCB/Xlib: Copy root window to pixmap

我可以使用 xcb_image_get()(不管它的 map 状态,虽然据推测根 window 总是 mapped?)。例如:

xcb_image_t* xcb_img = xcb_image_get(xcb_connection, xcb_screen->root, 0, 0, xcb_screen->width_in_pixels, xcb_screen->height_in_pixels, 0x00ffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);

现在根 window 的像素在 xcb_img->data.

但我正在尝试将根 window 的内容复制到 xcb_pixmap_t(在服务器内存中),但它不起作用(调用无效 失败,但它 returns 垃圾,好像 window 没有映射):

  xcb_void_cookie_t    copy_cookie = xcb_copy_area_checked(xcb_connection, xcb_screen->root, xcb_pixmap, xcb_gc_null, 0, 0, 0, 0, xcb_screen->width_in_pixels, xcb_screen->height_in_pixels);
  xcb_generic_error_t* copy_error  = xcb_request_check(xcb_connection, copy_cookie);
  if(copy_error)
    exit(1);

但是,它适用于碰巧被映射的其他 windows(并且对于被其他 windows 遮挡的那些 windows 的子区域无效,因为复制 returns 垃圾。)

我知道 window 需要 映射 才能具有有意义的内容。这让我认为根 window 是 never 映射(或其他)。

All I want is to copy the contents of the display (ie. the pixels that are currently being shown in the physical display/monitor) to an xcb_pixmap_t (or, equivalently, to an Xlib Pixmap). How can I do this? (It works so easily for xcb_get_image()...)

您希望 GC 将 SubwindowMode 设置为 IncludeInferiors(默认为 ClipByChildren)。

来自X11协议描述:

For ClipByChildren, both source and destination windows are additionally clipped by all viewable InputOutput children. For IncludeInferiors, neither source nor destination window is clipped by inferiors. This will result in including subwindow contents in the source and drawing through subwindow boundaries of the destination. The use of IncludeInferiors with a source or destination window of one depth with mapped inferiors of differing depth is not illegal, but the semantics is undefined by the core protocol.

https://www.x.org/releases/X11R7.5/doc/x11proto/proto.html

这意味着对于 ClipByChildren,您只是从用作源的 window 进行复制。如果 window 有子 window,则像素 "in there" 不属于您用作源的 window。因此,X11 假定您不需要这些像素。