Ant*_*ich 6 c c++ gtk xlib xcb
UPD:很久以前就应该更新这篇文章,但如果有人需要示例,可以在https://github.com/awpe/xwinclone上看到结果软件。
我不仅对 Xlib 很陌生,而且对 Linux 接口编程也很陌生。
我正在尝试解决将一个窗口的内容绘制到另一个窗口的常见任务(这并不像看起来那么常见,因为我找不到任何可靠的示例)。
然而,我遇到了严重的性能问题,我正在寻找可以用来使程序更快、更可靠的解决方案。
现在我将提供一些有关程序流程的信息,因为我不确定所选的程序设计是否正确,也许我使用Xlib的方式存在一些错误。
程序以适当的方式获取活动窗口(从现在起称为SrcWin)的ID(Xlib“Window”类型)(不是某些程序的小部件的ID,而是绘制所有内容的真实可见窗口),首先它XGetInputFocus用于获取焦点窗口,然后在找到根窗口的子窗口时使用迭代窗口XQueryTree,然后使用XmuClientWindow函数获取命名窗口(如果不是已找到的窗口)。
然后使用它获取SrcWinXGetWindowAttributes的宽度和高度,它们都在函数中用于创建相同大小的新窗口(称为TrgWin )。XCreateSimpleWindow
一些事件是为新窗口 TrgWin 注册的,例如KeyPress和Expose usingXSelectInput函数。
图形上下文是这样创建的:
GC gc = DefaultGC (Display, ScreenCount (Display) - 1);
Run Code Online (Sandbox Code Playgroud)
现在开始无限循环,在此循环中select调用函数来等待 X 连接上的某些事件或超时 ( struct timeval)。
之后该程序尝试使用以下命令从SrcWin获取图像:
XImage *xi;
xi = XGetImage (Display, SrcWin, 0, 0, SrcWinWidth, SrcWinHeight, AllPlanes, ZPixmap);
Run Code Online (Sandbox Code Playgroud)
如果成功获取图像,则会将其放入TrgWin:
if (xi)
{
XPutImage (Display, TrgWin, gc, xi, 0, 0, 0, 0, SrcWinWidth, SrcWinHeight);
XFree (xi);
}
Run Code Online (Sandbox Code Playgroud)
如果待处理事件是:
while (XPending (Display))
{
XNextEvent (Display, &XEvent);
/* some event processing using switch(XEvent.type){} */
}
Run Code Online (Sandbox Code Playgroud)
如上所述,程序几乎按预期工作。但当我试图让这个程序每 40 毫秒将SrcWin的内容绘制到TrgWin时,我遇到了严重的性能问题(这是 timeval 值,如果有事件,它可能会更快),在核心 i5-3337U 上,它需要 21% 的 cpu 时间程序和近 20% 的 Xorg 进程将一个 683*752 窗口绘制到另一个相同大小的窗口中。
从我的角度来看,如果我能够将 SrcWin 的像素内存区域映射到 TrgWin 的相应内存区域,那就太好了,但我在 Xlib 编程方面不太擅长,我怀疑这是可能的标准 Xlib 函数。
不过,我已经启动 KDE 环境来检查其窗口切换器,并且所有窗口缩略图都实时绘制到窗口切换器的窗口,而没有任何严重的 CPU 负载。它是如何完成的?
某处提到了 XShmGetImage + XShmPutImage 机制 - 它对我的程序来说比 XGetImage+XPutImage 更好吗?
我还看到 QT 和 GTK 中有“窗口损坏”事件,它是工具包特定的事件,还是有 Xlib 等效事件?
我将 QT 和 GTK 中的“窗口损坏”事件理解为在窗口图像缓冲区发生任何变化后发送信号,因此导致窗口中至少一个像素发生变化的所有事件也会生成这样的事件?如果 Xlib 中有这样的东西那就太好了,因为即使 SrcWin 中没有变化,我也可以每 40 毫秒摆脱不断变化的 TrgWin 内容。
我应该使用 GTK+ 让事情变得更容易吗?
预先感谢您的回复,并对大量文字表示歉意。