use std::mem; use imlib2::Drawable; use libc; use x11::xlib as x; use Display; use Image; use Rectangle; use X11Error; /// A wrapper around a window handle. #[derive(Copy, Clone, PartialEq, Eq)] pub struct Window { pub(super) display: *mut x::Display, pub(super) inner: x::Window, } /// Window Attributes pub struct WindowAttributes { pub(self) inner: *mut x::XWindowAttributes, } impl Window { /// Create a new window pub fn create( display: &Display, parent: Option, location: Rectangle, ) -> Result { let parent = match parent { Some(parent) => parent, None => display.get_default_root_window()?, }; let visual = display.default_visual(0); let window = unsafe { x::XCreateWindow( display.as_raw(), parent.as_raw(), location.x as i32, location.y as i32, location.width, location.height, 0, 0, 0, visual.as_raw(), 0, 0 as *mut x::XSetWindowAttributes, ) }; Ok(Window { display: display.as_raw(), inner: window, }) } /// Get window attributes. pub fn get_attributes(&self) -> Result { let attr = unsafe { libc::malloc(mem::size_of::()) as *mut x::XWindowAttributes }; let result = unsafe { x::XGetWindowAttributes(self.display, self.inner, attr) }; match result { 0 => Err(X11Error::GetAttributesError), _ => Ok(WindowAttributes { inner: attr }), } } /// Capture a snapshot of this window. pub fn get_image(&self) -> Result { let attr = self.get_attributes()?; let image = unsafe { x::XGetImage( self.display, self.inner, attr.get_x(), attr.get_y(), attr.get_width(), attr.get_height(), 0xffffffff, x::ZPixmap, ) }; Ok(Image { inner: image }) } /// Get the raw window handle pub fn as_raw(&self) -> x::Window { self.inner } } impl AsRef for Window { fn as_ref(&self) -> &Drawable { &self.inner } } impl WindowAttributes { /// Gets the width of the window pub fn get_x(&self) -> i32 { unsafe { (*self.inner).x as i32 } } /// Gets the height of the window pub fn get_y(&self) -> i32 { unsafe { (*self.inner).y as i32 } } /// Gets the width of the window pub fn get_width(&self) -> u32 { unsafe { (*self.inner).width as u32 } } /// Gets the height of the window pub fn get_height(&self) -> u32 { unsafe { (*self.inner).height as u32 } } } impl Drop for WindowAttributes { fn drop(&mut self) { unsafe { libc::free(self.inner as *mut libc::c_void) }; } }