#![warn(missing_debug_implementations)]
#![deny(missing_docs)]
extern crate gbm_sys as ffi;
extern crate libc;
#[cfg(feature = "import-wayland")]
extern crate wayland_server;
#[cfg(feature = "drm-support")]
extern crate drm;
extern crate drm_fourcc;
#[macro_use]
extern crate bitflags;
mod buffer_object;
mod device;
mod surface;
pub use self::buffer_object::*;
pub use self::device::*;
pub use self::surface::*;
pub use drm_fourcc::{DrmFourcc as Format, DrmModifier as Modifier};
use std::fmt;
use std::sync::{Arc, Weak};
pub trait AsRaw<T> {
fn as_raw(&self) -> *const T;
#[doc(hidden)]
fn as_raw_mut(&self) -> *mut T {
self.as_raw() as *mut _
}
}
struct PtrDrop<T>(*mut T, Option<Box<dyn FnOnce(*mut T) + Send + 'static>>);
impl<T> Drop for PtrDrop<T> {
fn drop(&mut self) {
(self.1.take().unwrap())(self.0);
}
}
#[derive(Clone)]
pub(crate) struct Ptr<T>(Arc<PtrDrop<T>>);
impl<T> Ptr<T> {
fn new<F: FnOnce(*mut T) + Send + 'static>(ptr: *mut T, destructor: F) -> Ptr<T> {
Ptr(Arc::new(PtrDrop(ptr, Some(Box::new(destructor)))))
}
fn downgrade(&self) -> WeakPtr<T> {
WeakPtr(Arc::downgrade(&self.0))
}
}
impl<T> std::ops::Deref for Ptr<T> {
type Target = *mut T;
fn deref(&self) -> &Self::Target {
&(self.0).0
}
}
impl<T> fmt::Pointer for Ptr<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
fmt::Pointer::fmt(&self.0 .0, f)
}
}
#[derive(Clone)]
pub(crate) struct WeakPtr<T>(Weak<PtrDrop<T>>);
impl<T> WeakPtr<T> {
fn upgrade(&self) -> Option<Ptr<T>> {
self.0.upgrade().map(Ptr)
}
}
impl<T> fmt::Pointer for WeakPtr<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self.upgrade() {
Some(x) => fmt::Pointer::fmt(&x, f),
None => fmt::Pointer::fmt(&std::ptr::null::<T>(), f),
}
}
}
unsafe impl<T> Send for WeakPtr<T> where Ptr<T>: Send {}
#[cfg(test)]
mod test {
fn is_send<T: Send>() {}
#[test]
fn device_is_send() {
is_send::<super::Device<std::fs::File>>();
is_send::<super::Device<super::FdWrapper>>();
}
#[test]
fn surface_is_send() {
is_send::<super::Surface<std::fs::File>>();
is_send::<super::Surface<super::FdWrapper>>();
}
#[test]
fn unmapped_bo_is_send() {
is_send::<super::BufferObject<()>>();
}
}