X11 / XCB / Xlib:将根窗口复制到像素图

时间:2018-06-20 21:30:55

标签: linux x11 xlib xserver xcb

我可以使用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(或等效地,到Xlib Pixmap)。我怎样才能做到这一点? (它对于xcb_get_image()来说很容易...)

1 个答案:

答案 0 :(得分:1)

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

根据X11协议的说明:

  

对于ClipByChildren,所有可见的InputOutput子项都会同时剪切源窗口和目标窗口。对于IncludeInferiors,源窗口和目标窗口都不会被其裁剪。这将导致在源中包含子窗口内容,并通过目标的子窗口边界进行绘制。带有一个深度的源窗口或目标窗口,具有不同深度的映射的下等项的IncludeInferiors的使用不是非法的,但是核心协议未定义语义。

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

这意味着ClipByChildren只是从用作源的窗口中复制。如果该窗口具有子窗口,则“用作其中”的窗口不拥有“其中”的像素。因此,X11假设您不需要这些像素。