Xdamage 无法获取损坏区域

问题描述

display *display = XOpendisplay(NULL);
Window root = XDefaultRootwindow(display);

int damage_event,damage_error,count = 0;

XdamageQueryExtension(display,&damage_event,&damage_error);
//tried all 4  damage levels giving the same output
damage dmg = XdamageCreate(display,root,XdamageReportNonEmpty); 
XdamageNotifyEvent *dmg_ev = NULL;
XEvent event;
while (1)
{

    XNextEvent(display,&event);

    if (event.type == damage_event + XdamageNotify)
    {
        printf("Got event\n");
        dmg_ev = (XdamageNotifyEvent *)&event;
        auto region = XFixesCreateRegion(display,NULL,0);
        XdamageSubtract(display,dmg_ev->damage,None,region);
        auto area = XFixesFetchRegion(display,region,&count);
        if (area)
        {
            printf("count is %d \n",count);
            for (int i = 0; i < count; i++)
            {
                auto rect = area[i];
                printf("x:%d y:%d height:%d width:%d\n",rect.x,rect.y,rect.height,rect.width);
            }
            XFree(area);
        }
        else
        {
            printf("areaa is NULL \n");
        }
        XFixesDestroyRegion(display,region);
    }
}

https://www.x.org/releases/X11R7.6/doc/damageproto/damageproto.txt

我正在使用 Xdamage 来检测屏幕中的更改或更改发生的特定区域..就像我在文本编辑器中的第 30 行和第 40 列处进行更改一样,我需要单独隔离该特定区域.上面的程序正在运行,但总是输出

x:0 y:0 height:1080 width:1920)(这是我的屏幕分辨率)

有人能告诉我我是否遗漏了什么,或者是否有可能使用 Xdamage 获取发生更改的确切区域,或者是否有其他一些我可以使用的库(截取屏幕截图并将其与上一张图片一个可能的解决方案,但它会消耗大量 cpu。需要占用更少 cpu 的东西)?

解决方法

来自damageproto.txt

6.损坏报告级别

DamageReportNonEmpty

每次损坏矩形从空变为非空时,以及每次 DamageSubtract 请求的结果导致非空区域时,都会发送一个 DamageNotify 事件。

因此,您只收到一个报告根窗口大小的事件(第一次绘制或没有更多损坏区域)也就不足为奇了。

相反,在对 DamageReportRawRectangles 的函数调用中使用 DamageReportDeltaRectanglesDamageReportLevel 作为 XDamageCreateDamageReportDeltaRectangles 可能是更好的选择,因为它避免被 DamageNotifyEvents 淹没。

进一步

3.1 协议 1.1 版本的补充

...但是直接渲染扩展允许客户端在 X 服务器控制之外执行渲染。

因此,可能不会报告所有区域(如果有的话)。使用的扩展程序或工具包提供了一个界面来获取损坏区域,否则某些库将不得不截取屏幕截图并获取前一个的差异并以每个像素为基础计算损坏区域。不是最高效的方式。