diff options
author | dec05eba <dec05eba@protonmail.com> | 2024-09-06 23:55:43 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2024-09-06 23:55:43 +0200 |
commit | 8158a809b77726c33560b2159ccdd49a97f85dcd (patch) | |
tree | 855079ee55cda9f8592868a0d80939f38fcd17d8 /src/damage.c | |
parent | 3446f864e3418d75fa55298bc7984b264e7167d6 (diff) |
Move damage tracking to separate file
Diffstat (limited to 'src/damage.c')
-rw-r--r-- | src/damage.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/damage.c b/src/damage.c new file mode 100644 index 0000000..1e68e6e --- /dev/null +++ b/src/damage.c @@ -0,0 +1,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; +} |