adds new XPointer<T> type

This commit is contained in:
Janis 2022-05-07 00:32:37 +02:00
parent b3f586ea6a
commit e49fdfa5be

View file

@ -1,6 +1,6 @@
use log::{error, warn};
use num_traits::Zero;
use std::{ffi::CString, mem::MaybeUninit, rc::Rc};
use std::{ffi::CString, rc::Rc};
use thiserror::Error;
@ -292,10 +292,15 @@ impl XLib {
(ev.atom == self.atoms.net_wm_window_type)
.then(|| {
(self.get_atom_property(
(self
.get_atom_property(
ev.window,
self.atoms.net_wm_state,
) == Some(self.atoms.net_wm_state_fullscreen))
)
.map(|atom| {
*atom == self.atoms.net_wm_state_fullscreen
})
== Some(true))
.then(|| {
XLibWindowEvent::FullscreenEvent(
FullscreenEvent::new(
@ -361,16 +366,15 @@ impl XLib {
&self,
window: xlib::Window,
atom: xlib::Atom,
) -> Option<xlib::Atom> {
) -> Option<xpointer::XPointer<xlib::Atom>> {
let mut di = 0;
let mut dl0 = 0;
let mut dl1 = 0;
let mut da = 0;
let mut atom_out = MaybeUninit::<xlib::Atom>::zeroed();
unsafe {
(xlib::XGetWindowProperty(
let (atom_out, success) =
xpointer::XPointer::<xlib::Atom>::build_with_result(|ptr| unsafe {
xlib::XGetWindowProperty(
self.dpy(),
window,
atom,
@ -382,10 +386,11 @@ impl XLib {
&mut di,
&mut dl0,
&mut dl1,
atom_out.as_mut_ptr() as *mut _,
) != 0)
.then(|| atom_out.assume_init())
}
ptr as *mut _ as *mut _,
) != 0
});
success.then(|| atom_out).flatten()
}
fn check_for_protocol(
@ -1056,3 +1061,78 @@ unsafe extern "C" fn xlib_error_handler(
}
}
}
pub mod xpointer {
use std::{
ops::{Deref, DerefMut},
ptr::{null, NonNull},
};
use x11::xlib::XFree;
#[repr(C)]
pub struct XPointer<T>(NonNull<T>);
impl<T> XPointer<T> {
pub fn build_with<F>(cb: F) -> Option<Self>
where
F: FnOnce(&mut *const ()),
{
let mut ptr = null() as *const ();
cb(&mut ptr);
NonNull::new(ptr as *mut T).map(|ptr| Self(ptr))
}
pub fn build_with_result<F, R>(cb: F) -> (Option<Self>, R)
where
F: FnOnce(&mut *const ()) -> R,
{
let mut ptr = null() as *const ();
let result = cb(&mut ptr);
(NonNull::new(ptr as *mut T).map(|ptr| Self(ptr)), result)
}
}
impl<T> AsRef<T> for XPointer<T> {
fn as_ref(&self) -> &T {
&**self
}
}
impl<T> AsMut<T> for XPointer<T> {
fn as_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T> PartialEq for XPointer<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> Eq for XPointer<T> where T: Eq {}
impl<T> Deref for XPointer<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.0.as_ref() }
}
}
impl<T> DerefMut for XPointer<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.0.as_mut() }
}
}
impl<T> Drop for XPointer<T> {
fn drop(&mut self) {
unsafe { XFree(self.0.as_ptr() as _) };
}
}
}