1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#include "../include/damage.h"
#include <stdio.h>
#include <string.h>
#include <X11/extensions/Xdamage.h>
bool gsr_damage_init(gsr_damage *self, Display *display) {
memset(self, 0, sizeof(*self));
self->display = display;
if(!XDamageQueryExtension(self->display, &self->damage_event, &self->damage_error)) {
fprintf(stderr, "gsr warning: gsr_damage_init: XDamage is not supported by your X11 server\n");
self->damage_event = 0;
self->damage_error = 0;
return false;
}
self->damaged = true;
return true;
}
void gsr_damage_deinit(gsr_damage *self) {
if(self->damage) {
XDamageDestroy(self->display, self->damage);
self->damage = None;
}
}
bool gsr_damage_set_target_window(gsr_damage *self, uint64_t window) {
if(self->damage_event == 0)
return false;
if(self->damage) {
XDamageDestroy(self->display, self->damage);
self->damage = None;
}
self->damage = XDamageCreate(self->display, window, XDamageReportNonEmpty);
if(self->damage) {
XDamageSubtract(self->display, self->damage, None, None);
self->damaged = true;
return true;
} else {
fprintf(stderr, "gsr warning: gsr_damage_set_target_window: XDamageCreate failed\n");
return false;
}
}
void gsr_damage_update(gsr_damage *self, XEvent *xev) {
if(self->damage_event == 0 || !self->damage)
return;
if(self->damage_event && xev->type == self->damage_event + XDamageNotify) {
XDamageNotifyEvent *de = (XDamageNotifyEvent*)xev;
XserverRegion region = XFixesCreateRegion(self->display, NULL, 0);
/* Subtract all the damage, repairing the window */
XDamageSubtract(self->display, de->damage, None, region);
XFixesDestroyRegion(self->display, region);
XFlush(self->display);
self->damaged = true;
}
}
bool gsr_damage_is_damaged(gsr_damage *self) {
return self->damage_event == 0 || !self->damage || self->damaged;
}
void gsr_damage_clear(gsr_damage *self) {
self->damaged = false;
}
|