我可以使用xcb_image_t
将根窗口的内容复制到客户端(即CPU)内存中的xcb_image_get()
上(无论其 map 状态如何,尽管根窗口始终是映射的?)。例如:
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);
现在,根窗口的像素位于xcb_img->data
中。
但是我正在尝试将根窗口的内容复制到xcb_pixmap_t
(在服务器内存中),并且它不起作用(调用不起作用)
失败,但返回垃圾,就像未映射窗口一样):
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);
但是,它适用于碰巧被映射的其他窗口(在副本被返回垃圾的意义上,它不适用于那些被其他窗口遮挡的窗口的子区域。)
我了解,为了拥有有意义的内容,必须映射一个窗口。这使我认为根窗口从未映射过(或任何东西)。
我所要做的就是将显示器的内容(即当前在物理显示器/监视器中显示的像素)复制到
xcb_pixmap_t
(或等效地,到XlibPixmap
)。我怎样才能做到这一点? (它对于xcb_get_image()
来说很容易...)
答案 0 :(得分:1)
您希望您的GC将SubwindowMode设置为IncludeInferiors(默认为ClipByChildren)。
根据X11协议的说明:
对于ClipByChildren,所有可见的InputOutput子项都会同时剪切源窗口和目标窗口。对于IncludeInferiors,源窗口和目标窗口都不会被其裁剪。这将导致在源中包含子窗口内容,并通过目标的子窗口边界进行绘制。带有一个深度的源窗口或目标窗口,具有不同深度的映射的下等项的IncludeInferiors的使用不是非法的,但是核心协议未定义语义。
https://www.x.org/releases/X11R7.5/doc/x11proto/proto.html
这意味着ClipByChildren只是从用作源的窗口中复制。如果该窗口具有子窗口,则“用作其中”的窗口不拥有“其中”的像素。因此,X11假设您不需要这些像素。