use std::io::Error as IoError;
use std::ptr;
use std::sync::{Arc, Mutex};
use ffi::interfaces::display::wl_display;
use ffi::abi;
use ffi::abi::WAYLAND_CLIENT_HANDLE as WCH;
use ffi::FFI;
use super::{From, Registry};
struct InternalDisplay {
ptr: *mut wl_display
}
unsafe impl Send for InternalDisplay {}
#[derive(Clone)]
pub struct Display {
internal: Arc<Mutex<InternalDisplay>>
}
impl Display {
pub fn get_registry(&self) -> Registry {
From::from(self.clone())
}
pub fn sync_roundtrip(&self) {
let internal = self.internal.lock().unwrap();
unsafe {
(WCH.wl_display_roundtrip)(internal.ptr);
}
}
pub fn dispatch_pending(&self) {
let internal = self.internal.lock().unwrap();
unsafe {
(WCH.wl_display_dispatch_pending)(internal.ptr);
}
}
pub fn dispatch(&self) {
let internal = self.internal.lock().unwrap();
unsafe {
(WCH.wl_display_dispatch)(internal.ptr);
}
}
pub fn flush(&self) -> Result<(), IoError> {
let internal = self.internal.lock().unwrap();
if unsafe { (WCH.wl_display_flush)(internal.ptr) } < 0 {
Err(IoError::last_os_error())
} else {
Ok(())
}
}
}
impl Drop for InternalDisplay {
fn drop(&mut self) {
unsafe {
(WCH.wl_display_disconnect)(self.ptr);
}
}
}
impl FFI for Display {
type Ptr = wl_display;
fn ptr(&self) -> *const wl_display {
self.internal.lock().unwrap().ptr as *const wl_display
}
unsafe fn ptr_mut(&self) -> *mut wl_display {
self.internal.lock().unwrap().ptr
}
}
pub fn default_display() -> Option<Display> {
unsafe {
let handle = match abi::WAYLAND_CLIENT_OPTION.as_ref() {
Some(h) => h,
None => return None
};
let ptr = (handle.wl_display_connect)(ptr::null_mut());
if ptr.is_null() {
None
} else {
Some(Display {
internal: Arc::new(Mutex::new(InternalDisplay{ ptr: ptr}))
})
}
}
}