2017-02-14 5 views
1

Je suis un débutant dans xlib et je veux attraper l'événement sur les changements de contenu de la fenêtre. Pour des exemples si une région a changé. J'ai lu que je dois utiliser Xdamage pour cela et c'est mon codeXdamage: obtenir l'événement sur les changements de contenu de la fenêtre

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); 

Donc, j'ai un exemple de travail dans lequel je peux obtenir l'événement et ses types de type.The, comme je comprends sont les types xlib - https://tronche.com/gui/x/xlib/events/types.html. Mais comment puis-je savoir à partir de l'événement que la fenêtre a été modifiée.

+0

vous souhaitez vérifier la valeur de retour de 'XDamageQueryExtension'. Il n'est pas garanti que l'extension est réellement chargée. – tofro

Répondre

4

Ce que vous recevez effectivement sont DamageNotify événements dans votre boucle d'événement normal qui ressemblent à ceci:

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; 

selon la documentation de https://www.x.org/releases/current/doc/damageproto/damageproto.txt

Le membre area signale la zone rectangulaire endommagée comme XRectangle .

Le membre drawable signale normalement la fenêtre qui a été endommagée.

Remarque XNextEvent retournera toujours un XEvent C'est le type statique retourné par la fonction. Il a également un type dynamique qui dépend du membre ev->type. - Vérifier son champ type pour savoir si vous pouvez jeter un 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

Merci pour votre réponse. Mais pouvez-vous expliquer comment je peux obtenir 'XDamageNotifyEvent' au lieu de' XEvent'? –

+0

Notez qu'un XEvent a à la fois un * static * (type "C") et un type * dynamic *. 'XNextEvnet' renvoie un' XEvent' qui pourrait être un événement 'XDamage' si son type dynamique le dit. Exemple ajouté pour répondre. – tofro

+0

Je suis un développeur Java. Si ce n'est pas difficile pour vous, pouvez-vous montrer comment obtenir 'XDamageNotifyEvent'? –

1

tard, mais pour ceux qui cherchent la zone qui a réellement changé la zone (EV-> sont les coordonnées de la fenêtre et la taille, pour moi au moins):

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);