使用X11的Xcomposite扩展获取隐藏或不可见或最小化的窗口的屏幕截图 [英] Get a screenshot of a window that is cover or not visible or minimized with Xcomposite extension for X11

查看:1034
本文介绍了使用X11的Xcomposite扩展获取隐藏或不可见或最小化的窗口的屏幕截图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下起始代码来获取X窗口的屏幕截图(该窗口可以覆盖,不可见或最小化).

I have the follow starting code to get a screenshot of a X window (the window can be covered, not visibled, or minimized).

#include <stdlib.h>
#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/X.h>
#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编译代码并使用./a.out运行]

[Compile the code with gcc file.c -lX11 -lXcomposite -lXrender and run with ./a.out]

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

[You can get a valid XID of a window of your Desktop with the command xdotool search --name "Title of a window" | head -1]

现在我有两个问题:

  1. 调用XRenderFindVisualFormat函数时出现BadMatch (invalid parameter attributes)错误.我不知道为什么.存在XID 90177543的窗口.
  2. 我不知道如何获取Picture picture的缓冲区以将其另存为PNG图像.我不想使用QT库来做到这一点.
  1. I get a BadMatch (invalid parameter attributes) error when I call the XRenderFindVisualFormat function. I dont know why. The window with XID 90177543 exists.
  2. I don't know how to get the buffer of the Picture picture to save it as a PNG image. I don't want use QT library to do this.

你能帮我吗?

推荐答案

我能够按照以下方式重现您的错误:

I am able to reproduce your error as follows:

$ ./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进行设置(使用xwininfo找到的0x440000B或71303179)时,我没有收到错误:

When set using a window id I knew to exist (0x440000B or 71303179, found using xwininfo), I received no error:

$ ./xidtest 
COMPOSITE IS ENABLED!

我认为错误是您提供的窗口ID无效.

I conclude that the error is the window id you have provided is invalid.

这篇关于使用X11的Xcomposite扩展获取隐藏或不可见或最小化的窗口的屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆