diff --git a/Cargo.toml b/Cargo.toml index 2deec97..c13aa0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "safex11" -version = "0.0.3" +version = "0.0.4" description = "Safe, high-level x11 bindings" license-file = "LICENSE" authors = ["Michael Zhang "] diff --git a/src/glx/drawable.rs b/src/glx/drawable.rs new file mode 100644 index 0000000..7b3242b --- /dev/null +++ b/src/glx/drawable.rs @@ -0,0 +1,16 @@ +use x11::xlib; + +use crate::xlib::Window; + +pub enum GlxDrawable<'a> { + Window(Window<'a>), + // TODO: pixmap +} + +impl<'a> GlxDrawable<'a> { + pub fn as_raw(&self) -> xlib::XID { + match self { + GlxDrawable::Window(window) => window.as_raw(), + } + } +} diff --git a/src/glx/mod.rs b/src/glx/mod.rs index af75a1f..6ceac75 100644 --- a/src/glx/mod.rs +++ b/src/glx/mod.rs @@ -1,16 +1,27 @@ mod context; +mod drawable; use x11::glx; use crate::errors::Result; -use crate::xlib::Display; +use crate::xlib::{Display, VisualInfo}; pub use self::context::GlxContext; +pub use self::drawable::GlxDrawable; pub trait GlxExtension { fn query_glx_extension(&self) -> Result; - fn create_context(&self, share_list: Option<&GlxContext>, direct: bool) -> Result; + fn create_context( + &self, + visual_info: &VisualInfo, + share_list: Option<&GlxContext>, + direct: bool, + ) -> Result; + + fn make_current(&self, drawable: GlxDrawable, ctx: GlxContext) -> Result<()>; + + fn choose_visual(&self, screen: i32) -> Result; } impl GlxExtension for Display { @@ -19,12 +30,33 @@ impl GlxExtension for Display { Ok(result == 1) } - fn create_context(&self, share_list: Option<&GlxContext>, direct: bool) -> Result { + fn create_context( + &self, + visual_info: &VisualInfo, + share_list: Option<&GlxContext>, + direct: bool, + ) -> Result { let share_list = share_list .map(|ctx| ctx.as_raw()) .unwrap_or_else(|| 0 as *mut _); - let ctx = - unsafe { glx::glXCreateContext(self.as_raw(), 0 as *mut _, share_list, direct.into()) }; + let ctx = unsafe { + glx::glXCreateContext( + self.as_raw(), + visual_info.as_raw(), + share_list, + direct.into(), + ) + }; Ok(GlxContext { display: self, ctx }) } + + fn make_current(&self, drawable: GlxDrawable, ctx: GlxContext) -> Result<()> { + unsafe { glx::glXMakeCurrent(self.as_raw(), drawable.as_raw(), ctx.as_raw()) }; + Ok(()) + } + + fn choose_visual(&self, screen: i32) -> Result { + let visual = unsafe { glx::glXChooseVisual(self.as_raw(), screen, 0 as *mut _) }; + Ok(VisualInfo::from_raw(visual)) + } } diff --git a/src/xlib/display.rs b/src/xlib/display.rs index 31981c3..57e36a0 100644 --- a/src/xlib/display.rs +++ b/src/xlib/display.rs @@ -102,7 +102,7 @@ impl Display { return Err(Error::GetWindowError); } let window = Window { - display: self.inner, + display: self, inner, }; Ok(window) @@ -115,7 +115,7 @@ impl Display { return Err(Error::GetWindowError); } let window = Window { - display: self.inner, + display: self, inner, }; Ok(window) @@ -152,7 +152,7 @@ impl Display { let child = match child_return { 0 => None, val => Some(Window { - display: self.inner, + display: self, inner: val, }), }; @@ -170,7 +170,7 @@ impl Display { let mut revert_to_return = 0; unsafe { xlib::XGetInputFocus(self.inner, &mut focus_return, &mut revert_to_return) }; let window = Window { - display: self.inner, + display: self, inner: focus_return, }; return Ok((window, revert_to_return)); diff --git a/src/xlib/mod.rs b/src/xlib/mod.rs index 7366e92..6865df2 100644 --- a/src/xlib/mod.rs +++ b/src/xlib/mod.rs @@ -13,5 +13,5 @@ pub use self::display::{Display, GetDisplay}; pub use self::drawable::Drawable; pub use self::event::{Event, EventKind}; pub use self::image::{Image, ImageByteOrder, PixBuffer}; -pub use self::visual::Visual; +pub use self::visual::{Visual, VisualInfo}; pub use self::window::{EventMask, Window}; diff --git a/src/xlib/visual.rs b/src/xlib/visual.rs index 5bcf83d..78b1ad0 100644 --- a/src/xlib/visual.rs +++ b/src/xlib/visual.rs @@ -19,3 +19,17 @@ impl Visual { Visual { inner } } } + +pub struct VisualInfo { + pub(super) inner: *mut xlib::XVisualInfo, +} + +impl VisualInfo { + pub fn from_raw(inner: *mut xlib::XVisualInfo) -> Self { + VisualInfo { inner } + } + + pub fn as_raw(&self) -> *mut xlib::XVisualInfo { + self.inner + } +} diff --git a/src/xlib/window.rs b/src/xlib/window.rs index 18ee13e..fbc8177 100644 --- a/src/xlib/window.rs +++ b/src/xlib/window.rs @@ -12,19 +12,19 @@ use super::drawable::Drawable; use super::image::Image; /// A wrapper around a window handle. -#[derive(Clone, PartialEq, Eq)] -pub struct Window { - pub(super) display: *mut xlib::Display, +#[derive(Clone)] +pub struct Window<'a> { + pub(super) display: &'a Display, pub(super) inner: xlib::Window, } -impl Window { +impl<'a> Window<'a> { /// Create a new window pub fn create( - display: &Display, + display: &'a Display, parent: Option, location: Rectangle, - ) -> Result { + ) -> Result> { let parent = match parent { Some(parent) => parent, None => display.get_default_root_window()?, @@ -47,17 +47,14 @@ impl Window { ) }; Ok(Window { - display: display.as_raw(), + display, inner: window, }) } /// Create a new Window instance from an existing ID pub fn create_from_handle(display: &Display, id: u64) -> Result { - Ok(Window { - display: display.as_raw(), - inner: id, - }) + Ok(Window { display, inner: id }) } /// Get window attributes. @@ -65,7 +62,7 @@ impl Window { let attr = unsafe { libc::malloc(mem::size_of::()) as *mut xlib::XWindowAttributes }; - let result = unsafe { xlib::XGetWindowAttributes(self.display, self.inner, attr) }; + let result = unsafe { xlib::XGetWindowAttributes(self.display.as_raw(), self.inner, attr) }; match result { 0 => Err(Error::GetAttributesError), _ => Ok(WindowAttributes { @@ -101,7 +98,7 @@ impl Window { let v = val.as_raw(); unsafe { xlib::XChangeProperty( - self.display, + self.display.as_raw(), self.inner, key.as_raw(), xlib::XA_ATOM, @@ -115,7 +112,7 @@ impl Window { /// "Maps", or shows a window to a display. pub fn map(&self) { - unsafe { xlib::XMapWindow(self.display, self.inner) }; + unsafe { xlib::XMapWindow(self.display.as_raw(), self.inner) }; } /// Requests for events from the server matching a particular event mask. @@ -123,31 +120,31 @@ impl Window { /// If this function is not called, events will not be reported. pub fn select_input(&self, event_mask: EventMask) { debug!("event mask: {:?}", event_mask); - unsafe { xlib::XSelectInput(self.display, self.inner, event_mask.bits as i64) }; + unsafe { xlib::XSelectInput(self.display.as_raw(), self.inner, event_mask.bits as i64) }; } } -impl GetDisplay for Window { +impl<'a> GetDisplay for Window<'a> { fn get_display(&self) -> *mut xlib::Display { - self.display + self.display.as_raw() } } -impl Drawable for Window { +impl<'a> Drawable for Window<'a> { fn as_drawable(&self) -> xlib::Drawable { self.inner } } -impl Drop for Window { +impl<'a> Drop for Window<'a> { fn drop(&mut self) { - unsafe { xlib::XDestroyWindow(self.display, self.inner) }; + unsafe { xlib::XDestroyWindow(self.display.as_raw(), self.inner) }; } } /// Window Attributes -pub struct WindowAttributes { - pub(super) display: *mut xlib::Display, +pub struct WindowAttributes<'a> { + pub(super) display: &'a Display, pub(self) inner: *mut xlib::XWindowAttributes, } @@ -157,7 +154,7 @@ pub struct WindowAttributes { // } // } -impl WindowAttributes { +impl<'a> WindowAttributes<'a> { /// Gets the width of the window pub fn get_x(&self) -> i32 { unsafe { (*self.inner).x as i32 } @@ -187,12 +184,6 @@ impl WindowAttributes { } } -impl Drop for WindowAttributes { - fn drop(&mut self) { - unsafe { libc::free(self.inner as *mut libc::c_void) }; - } -} - bitflags! { pub struct EventMask: c_ulong { const NO_EVENT_MASK = 0;