使用X11的Xcomposite扩展程序获取封面或不可见或最小化的窗口截图

我有下面的开始代码来获得X窗口的屏幕截图(窗口可以被覆盖,不可见或最小化)。

#include <stdlib.h> #include <stdio.h> #include <X11/Xlib.h> #include <X11/Xh> #include <X11/extensions/Xcomposite.h> #include <X11/extensions/Xrender.h> int main () { Display *display = XOpenDisplay (NULL); XID xid = 90177543; // xdotool search --name "World of Warcraft" | head -1 // Check if Composite extension is enabled int event_base_return; int error_base_return; if (XCompositeQueryExtension (display, &event_base_return, &error_base_return)) printf ("COMPOSITE IS ENABLED!\n"); // Requests the X server to direct the hierarchy starting at window to off-screen storage XCompositeRedirectWindow (display, xid, CompositeRedirectAutomatic); // Preventing the backing pixmap from being freed when the window is hidden/destroyed // If you want the window contents to still be available after the window has been destroyed, // or after the window has been resized (but not yet redrawn), you can increment the backing // pixmaps ref count to prevent it from being deallocated. Pixmap pixmap = XCompositeNameWindowPixmap (display, xid); // Get window attributes XWindowAttributes attr; Status s = XGetWindowAttributes (display, xid, &attr); if (s == 0) printf ("Fail to get window attributes!\n"); // Extract the data XRenderPictFormat *format = XRenderFindVisualFormat (display, attr.visual); int width = attr.width; int height = attr.height; int depth = attr.depth; // What we need to do now is to create an XRender Picture for the window, // which we'll need to draw it with the Render extension. // A picture is a basically a handle to a server side struct with some // additional information about a drawable (in this case a window), // such as its format, which clipping region should be used when // drawing it (if any), whether it should be tiled etc. XRenderPictureAttributes pa; pa.subwindow_mode = IncludeInferiors; Picture picture = XRenderCreatePicture (display, xid, format, CPSubwindowMode, &pa); // We now have all the information we need in order to be able to draw the window // using the Xrender extension, and we've created and prepared a source picture // for the window for this purpose. // The Xrender function we'll use to draw the window is XRenderComposite(). //XRenderComposite (display, PictOpSrc, picture, None, ???destination???, 0,0, 0,0, 0,0, width, height); XFreePixmap (display, pixmap); XCompositeUnredirectWindow (display, xid, CompositeRedirectAutomatic); return 0; } 

[用gcc file.c -lX11 -lXcomposite -lXrender编译代码,用gcc file.c -lX11 -lXcomposite -lXrender运行]

[您可以使用命令xdotool search --name "Title of a window" | head -1来获取桌面窗口的有效XID xdotool search --name "Title of a window" | head -1 xdotool search --name "Title of a window" | head -1 ]

现在我有两个问题:

  1. 当我调用XRenderFindVisualFormat函数时,出现BadMatch (invalid parameter attributes)错误。 我不知道为什么。 存在XID 90177543的窗口。
  2. 我不知道如何获取Picture picture的缓冲区,将其保存为PNG图片。 我不希望使用QT库来做到这一点。

你可以帮我吗?

Solutions Collecting From Web of "使用X11的Xcomposite扩展程序获取封面或不可见或最小化的窗口截图"

我能够重现您的错误,如下所示:

 $ ./xidtest COMPOSITE IS ENABLED! X Error of failed request: BadWindow (invalid Window parameter) Major opcode of failed request: 142 (Composite) Minor opcode of failed request: 1 () Resource id in failed request: 0x5600007 Serial number of failed request: 9 Current serial number in output stream: 12 

当使用我知道存在的窗口id(0x440000B或71303179,使用xwininfo找到)设置时,我没有收到任何错误:

 $ ./xidtest COMPOSITE IS ENABLED! 

我得出结论,错误是你提供的窗口ID是无效的。