我不仅是Xlib的新手,也是Linux接口编程的新手。
我试图解决将一个窗口的内容绘制到另一个窗口的常见任务(这似乎不是很常见,因为我无法找到任何可靠的例子)。
然而,我遇到了严重的性能问题,而且我正在寻找可以使程序更快更可靠的解决方案。
现在我提供一些有关程序流程的信息,因为我不确定选择的程序设计是否正确,也许我使用Xlib的方式有一些错误。
程序以正确的方式获取活动窗口的ID(Xlib" Window"类型)(从现在开始称为 SrcWin )(不是某些程序的小部件的ID,但是绘制所有内容的真实可见窗口,首先使用XGetInputFocus
获取聚焦窗口,然后在找到根窗口的子窗口时使用XQueryTree
迭代窗口,然后使用XmuClientWindow
获取命名窗口的函数(如果它不是已经找到的窗口)。
然后使用XGetWindowAttributes
获取 SrcWin 的宽度和高度,它们都在XCreateSimpleWindow
函数中用于创建新窗口(称为 TrgWin )大小相同。
使用XSelectInput
功能为新窗口TrgWin注册了一些事件,例如 KeyPress 和 Expose 。
以这种方式创建图形上下文:
GC gc = DefaultGC (Display, ScreenCount (Display) - 1);
现在启动无限循环,在此循环中select
函数被调用以等待X连接上的某个事件或超时(struct timeval
)。
该程序尝试使用以下方法从 SrcWin 获取图像后
XImage *xi;
xi = XGetImage (Display, SrcWin, 0, 0, SrcWinWidth, SrcWinHeight, AllPlanes, ZPixmap);
如果图像成功获得,则将其放入 TrgWin :
if (xi)
{
XPutImage (Display, TrgWin, gc, xi, 0, 0, 0, 0, SrcWinWidth, SrcWinHeight);
XFree (xi);
}
然后处理待处理事件:
while (XPending (Display))
{
XNextEvent (Display, &XEvent);
/* some event processing using switch(XEvent.type){} */
}
如上所述,程序几乎按预期工作。但是当我尝试让这个程序每隔40ms将 SrcWin 的内容绘制到 TrgWin 时,我遇到了严重的性能问题(这是时间值,事件可能更快) ),在核心i5-3337U上,该程序需要21%的CPU时间,而Xorg进程需要将近一半的683 * 752窗口绘制成另一个相同大小的窗口。
从我的观点来看,如果我能够将具有SrcWin像素的内存区域映射到TrgWin的相应内存区域,那将会很棒,但我在Xlib编程中并不是很好,而且我怀疑标准Xlib功能是否可行。
1)然而,我已经启动了KDE环境来检查其窗口切换器,并且所有窗口缩略图都实时地被绘制到窗口切换器的窗口而没有任何严重的CPU负载。怎么做?
2)提到了XShmGetImage + XShmPutImage机制 - 我的程序比XGetImage + XPutImage更好吗?
3)我也看到有这样的事情,例如"窗户损坏" QT和GTK中的事件,是特定于工具包的事件,还是具有Xlib等效事件?
4)我理解"窗户损坏"在窗口的图像缓冲区发生任何变化后,QT和GTK中的事件作为信号发送,因此导致窗口中至少一个像素发生变化的一切也会产生这样的事件?在Xlib中有这样的东西会很棒,因为即使SrcWin没有变化,我也可以每隔40ms摆脱不断变化的TrgWin内容。
5)我应该使用GTK +来简化工作吗?
提前感谢您的回复,并抱歉收到大量文字。