use std::{ptr, time::Duration};
use libc::{clock_t};
use wlroots_sys::{timespec, wlr_output, wlr_output_damage, wlr_output_damage_add,
wlr_output_damage_add_box, wlr_output_damage_add_whole,
wlr_output_damage_create, wlr_output_damage_destroy,
wlr_output_damage_make_current, wlr_output_damage_swap_buffers};
use {area::Area, render::PixmanRegion};
#[derive(Debug)]
pub struct Damage {
damage: *mut wlr_output_damage
}
impl Damage {
pub(crate) unsafe fn new(output: *mut wlr_output) -> Self {
unsafe {
let damage = wlr_output_damage_create(output);
if damage.is_null() {
panic!("Damage was none")
}
Damage { damage }
}
}
pub(crate) unsafe fn from_ptr(damage: *mut wlr_output_damage) -> Self {
Damage { damage }
}
pub(crate) unsafe fn as_ptr(&self) -> *mut wlr_output_damage {
self.damage
}
pub(crate) unsafe fn clone(&self) -> Self {
Damage { damage: self.damage }
}
pub fn make_current<'a, T>(&mut self, damage: T) -> bool
where T: Into<Option<&'a mut PixmanRegion>>
{
unsafe {
let mut res = false;
let damage = match damage.into() {
Some(region) => &mut region.region as *mut _,
None => ptr::null_mut()
};
wlr_output_damage_make_current(self.damage, &mut res, damage);
res
}
}
pub fn swap_buffers<'a, T, U>(&mut self, when: T, damage: U) -> bool
where T: Into<Option<Duration>>,
U: Into<Option<&'a mut PixmanRegion>>
{
unsafe {
let when = when.into().map(|duration| {
timespec { tv_sec: duration.as_secs() as clock_t,
tv_nsec: duration.subsec_nanos() as clock_t }
});
let when_ptr =
when.map(|mut duration| &mut duration as *mut _).unwrap_or_else(|| ptr::null_mut());
let damage = match damage.into() {
Some(region) => &mut region.region as *mut _,
None => ptr::null_mut()
};
wlr_output_damage_swap_buffers(self.damage, when_ptr, damage)
}
}
pub fn add(&mut self, damage: &mut PixmanRegion) {
unsafe {
wlr_output_damage_add(self.damage, &mut damage.region);
}
}
pub fn add_whole(&mut self) {
unsafe { wlr_output_damage_add_whole(self.damage) }
}
pub fn add_area(&mut self, area: Area) {
unsafe { wlr_output_damage_add_box(self.damage, &mut area.into()) }
}
}
impl Drop for Damage {
fn drop(&mut self) {
wlr_log!(WLR_DEBUG, "Dropped Damage {:p}", self.damage);
unsafe {
wlr_output_damage_destroy(self.damage);
}
}
}