2017-02-14 58 views
1

我是xlib的初學者,我想捕獲窗口內容更改的事件。例如,如果某個地區發生變化。我讀過,我需要使用Xdamage爲,這是我的代碼Xdamage:獲取窗口內容更改的事件

Display* display = XOpenDisplay(NULL); 
    Window root = DefaultRootWindow(display); 
    XWindowAttributes attributes = {0}; 
    XGetWindowAttributes(display, root, &attributes); 
    int width, height; 
    width = attributes.width; 
    height = attributes.height; 
    //XDAMAGE INIT 
    int damage_event, damage_error, test; 
    test = XDamageQueryExtension(display, &damage_event, &damage_error); 
    Damage damage = XDamageCreate(display, root, XDamageReportNonEmpty); 
    while (true){ 
     XEvent event; 
     XNextEvent(display,&event); 
     //HERE I GET EVENT 
     XDamageSubtract(display,damage,None,None); 
    } 
    XCloseDisplay(display); 

所以,我有一個工作的例子,我可以得到事件及其type.The類型,我的理解是Xlib的類型 - https://tronche.com/gui/x/xlib/events/types.html。但是我怎麼能從事件中發現窗口已經改變了。根據從https://www.x.org/releases/current/doc/damageproto/damageproto.txt

area員將損壞的矩形區域作爲XRectangle文檔

typedef struct { 
    int type;   /* event base */ 
    unsigned long serial; 
    Bool send_event; 
    Display *display; 
    Drawable drawable; 
    Damage damage; 
    int level; 
    Bool more;   /* more events will be delivered immediately */ 
    Time timestamp; 
    XRectangle area; 
    XRectangle geometry; 
} XDamageNotifyEvent; 

+0

你想檢查'XDamageQueryExtension'的返回值。不保證擴展程序實際加載。 – tofro

回答

4

您實際收到是在你的正常事件循環DamageNotify事件,看起來像這樣。

drawable成員通常會報告已損壞的窗口。

注意XNextEvent將始終返回XEvent這就是靜態函數返回的類型。它也有一個動態類型取決於ev->type成員。 - 檢查其type場,以找出是否你可以將其轉換爲XDamageEvent

XEvent ev; 

/* We might need a pointer to an XDamageEvent... */ 
XDamageNotifyEvent *dev; 

while (1) { 
    XNextEvent(display,&ev); 
    switch (ev.type){ 
     ... 
     case DamageNotify: 
     dev = (XDamageNotifyEvent*)&ev; /* if type matches, cast to XDamageNotify event */ 
     printf ("Damage notification in window %d\n", dev->drawable); 
     printf ("Rectangle x=%d, y=%d, w=%d, h=%d\n", 
       dev->area.x, dev->area.y, 
       dev->area.width, dev->area.height); 
     break; 
     ... 
    } 
+0

謝謝你的回答。但是,你能解釋一下,我怎樣才能得到'XDamageNotifyEvent'而不是'XEvent'? –

+0

請注意,XEvent同時具有* static *(其「C」類型)和* dynamic *類型。 'XNextEvnet'返回一個'XEvent',如果它的動態類型如此說明的話,它實際上可能是一個'XDamage'事件。添加示例以回答。 – tofro

+0

我是一名java開發人員。如果對你來說不難,你能展示如何獲得'XDamageNotifyEvent'嗎? –

1

較晚,但爲尋找該地區實際改變(EV->區域是窗口座標和大小,對我來說至少):

auto ev = (XDamageNotifyEvent*)e; 
auto region = XFixesCreateRegion(display, null, 0); 
XDamageSubtract(display, ev->damage, None, region); 
int count; 
auto area = XFixesFetchRegion(display, region, &count); 
if(area){ 
    for(int i; i < count; i++){ 
     auto rect = area[i]; 
     // do something with rect 
    } 
    XFree(area); 
} 
XFixesDestroyRegion(display, region);