1 use std::ops::{Deref, DerefMut}; 2 3 use super::*; 4 5 pub struct XSmartPointer<'a, T> { 6 xconn: &'a XConnection, 7 pub ptr: *mut T, 8 } 9 10 impl<'a, T> XSmartPointer<'a, T> { 11 // You're responsible for only passing things to this that should be XFree'd. 12 // Returns None if ptr is null. new(xconn: &'a XConnection, ptr: *mut T) -> Option<Self>13 pub fn new(xconn: &'a XConnection, ptr: *mut T) -> Option<Self> { 14 if !ptr.is_null() { 15 Some(XSmartPointer { 16 xconn, 17 ptr, 18 }) 19 } else { 20 None 21 } 22 } 23 } 24 25 impl<'a, T> Deref for XSmartPointer<'a, T> { 26 type Target = T; 27 deref(&self) -> &T28 fn deref(&self) -> &T { 29 unsafe { &*self.ptr } 30 } 31 } 32 33 impl<'a, T> DerefMut for XSmartPointer<'a, T> { deref_mut(&mut self) -> &mut T34 fn deref_mut(&mut self) -> &mut T { 35 unsafe { &mut *self.ptr } 36 } 37 } 38 39 impl<'a, T> Drop for XSmartPointer<'a, T> { drop(&mut self)40 fn drop(&mut self) { 41 unsafe { 42 (self.xconn.xlib.XFree)(self.ptr as *mut _); 43 } 44 } 45 } 46 47 impl XConnection { alloc_class_hint(&self) -> XSmartPointer<ffi::XClassHint>48 pub fn alloc_class_hint(&self) -> XSmartPointer<ffi::XClassHint> { 49 XSmartPointer::new(self, unsafe { (self.xlib.XAllocClassHint)() }) 50 .expect("`XAllocClassHint` returned null; out of memory") 51 } 52 alloc_size_hints(&self) -> XSmartPointer<ffi::XSizeHints>53 pub fn alloc_size_hints(&self) -> XSmartPointer<ffi::XSizeHints> { 54 XSmartPointer::new(self, unsafe { (self.xlib.XAllocSizeHints)() }) 55 .expect("`XAllocSizeHints` returned null; out of memory") 56 } 57 alloc_wm_hints(&self) -> XSmartPointer<ffi::XWMHints>58 pub fn alloc_wm_hints(&self) -> XSmartPointer<ffi::XWMHints> { 59 XSmartPointer::new(self, unsafe { (self.xlib.XAllocWMHints)() }) 60 .expect("`XAllocWMHints` returned null; out of memory") 61 } 62 } 63