I can copy the contents of the root window to an xcb_image_t
in client (ie. CPU) memory using xcb_image_get()
(regardless of its map status, although presumably the root window is always mapped?). Eg:
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);
Now the pixels of the root window are in xcb_img->data
.
But I'm trying to copy the contents of the root window to an xcb_pixmap_t
(in server memory), and it's not working (the call doesn't
fail, but it returns garbage, as if the window wasn't mapped):
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);
However, it works for other windows that happen to be mapped (and it fails for subregions of those windows that are occluded by other windows, in the sense that the copy returns garbage.)
I understand that a window needs to be mapped in order to have meaninful contents. This leads me to think that the root window is never mapped (or something).
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 XlibPixmap
). How can I do this? (It works so easily forxcb_get_image()
...)
You want your GC to have SubwindowMode set to IncludeInferiors (default is ClipByChildren).
From the X11 protocol description:
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
What this means is that with ClipByChildren, you are only copying from the window that you used as the source. If the window has subwindows, the pixels "in there" are not owned by the window you are using as the source. Thus, X11 assumes you do not want those pixels.