This commit is contained in:
Michael Zhang 2020-06-30 03:10:12 -05:00
parent 1a9624a80e
commit d8860f28cc
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
7 changed files with 93 additions and 40 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "safex11" name = "safex11"
version = "0.0.3" version = "0.0.4"
description = "Safe, high-level x11 bindings" description = "Safe, high-level x11 bindings"
license-file = "LICENSE" license-file = "LICENSE"
authors = ["Michael Zhang <iptq@protonmail.com>"] authors = ["Michael Zhang <iptq@protonmail.com>"]

16
src/glx/drawable.rs Normal file
View file

@ -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(),
}
}
}

View file

@ -1,16 +1,27 @@
mod context; mod context;
mod drawable;
use x11::glx; use x11::glx;
use crate::errors::Result; use crate::errors::Result;
use crate::xlib::Display; use crate::xlib::{Display, VisualInfo};
pub use self::context::GlxContext; pub use self::context::GlxContext;
pub use self::drawable::GlxDrawable;
pub trait GlxExtension { pub trait GlxExtension {
fn query_glx_extension(&self) -> Result<bool>; fn query_glx_extension(&self) -> Result<bool>;
fn create_context(&self, share_list: Option<&GlxContext>, direct: bool) -> Result<GlxContext>; fn create_context(
&self,
visual_info: &VisualInfo,
share_list: Option<&GlxContext>,
direct: bool,
) -> Result<GlxContext>;
fn make_current(&self, drawable: GlxDrawable, ctx: GlxContext) -> Result<()>;
fn choose_visual(&self, screen: i32) -> Result<VisualInfo>;
} }
impl GlxExtension for Display { impl GlxExtension for Display {
@ -19,12 +30,33 @@ impl GlxExtension for Display {
Ok(result == 1) Ok(result == 1)
} }
fn create_context(&self, share_list: Option<&GlxContext>, direct: bool) -> Result<GlxContext> { fn create_context(
&self,
visual_info: &VisualInfo,
share_list: Option<&GlxContext>,
direct: bool,
) -> Result<GlxContext> {
let share_list = share_list let share_list = share_list
.map(|ctx| ctx.as_raw()) .map(|ctx| ctx.as_raw())
.unwrap_or_else(|| 0 as *mut _); .unwrap_or_else(|| 0 as *mut _);
let ctx = let ctx = unsafe {
unsafe { glx::glXCreateContext(self.as_raw(), 0 as *mut _, share_list, direct.into()) }; glx::glXCreateContext(
self.as_raw(),
visual_info.as_raw(),
share_list,
direct.into(),
)
};
Ok(GlxContext { display: self, ctx }) 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<VisualInfo> {
let visual = unsafe { glx::glXChooseVisual(self.as_raw(), screen, 0 as *mut _) };
Ok(VisualInfo::from_raw(visual))
}
} }

View file

@ -102,7 +102,7 @@ impl Display {
return Err(Error::GetWindowError); return Err(Error::GetWindowError);
} }
let window = Window { let window = Window {
display: self.inner, display: self,
inner, inner,
}; };
Ok(window) Ok(window)
@ -115,7 +115,7 @@ impl Display {
return Err(Error::GetWindowError); return Err(Error::GetWindowError);
} }
let window = Window { let window = Window {
display: self.inner, display: self,
inner, inner,
}; };
Ok(window) Ok(window)
@ -152,7 +152,7 @@ impl Display {
let child = match child_return { let child = match child_return {
0 => None, 0 => None,
val => Some(Window { val => Some(Window {
display: self.inner, display: self,
inner: val, inner: val,
}), }),
}; };
@ -170,7 +170,7 @@ impl Display {
let mut revert_to_return = 0; let mut revert_to_return = 0;
unsafe { xlib::XGetInputFocus(self.inner, &mut focus_return, &mut revert_to_return) }; unsafe { xlib::XGetInputFocus(self.inner, &mut focus_return, &mut revert_to_return) };
let window = Window { let window = Window {
display: self.inner, display: self,
inner: focus_return, inner: focus_return,
}; };
return Ok((window, revert_to_return)); return Ok((window, revert_to_return));

View file

@ -13,5 +13,5 @@ pub use self::display::{Display, GetDisplay};
pub use self::drawable::Drawable; pub use self::drawable::Drawable;
pub use self::event::{Event, EventKind}; pub use self::event::{Event, EventKind};
pub use self::image::{Image, ImageByteOrder, PixBuffer}; pub use self::image::{Image, ImageByteOrder, PixBuffer};
pub use self::visual::Visual; pub use self::visual::{Visual, VisualInfo};
pub use self::window::{EventMask, Window}; pub use self::window::{EventMask, Window};

View file

@ -19,3 +19,17 @@ impl Visual {
Visual { inner } 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
}
}

View file

@ -12,19 +12,19 @@ use super::drawable::Drawable;
use super::image::Image; use super::image::Image;
/// A wrapper around a window handle. /// A wrapper around a window handle.
#[derive(Clone, PartialEq, Eq)] #[derive(Clone)]
pub struct Window { pub struct Window<'a> {
pub(super) display: *mut xlib::Display, pub(super) display: &'a Display,
pub(super) inner: xlib::Window, pub(super) inner: xlib::Window,
} }
impl Window { impl<'a> Window<'a> {
/// Create a new window /// Create a new window
pub fn create( pub fn create(
display: &Display, display: &'a Display,
parent: Option<Window>, parent: Option<Window>,
location: Rectangle, location: Rectangle,
) -> Result<Window> { ) -> Result<Window<'a>> {
let parent = match parent { let parent = match parent {
Some(parent) => parent, Some(parent) => parent,
None => display.get_default_root_window()?, None => display.get_default_root_window()?,
@ -47,17 +47,14 @@ impl Window {
) )
}; };
Ok(Window { Ok(Window {
display: display.as_raw(), display,
inner: window, inner: window,
}) })
} }
/// Create a new Window instance from an existing ID /// Create a new Window instance from an existing ID
pub fn create_from_handle(display: &Display, id: u64) -> Result<Window> { pub fn create_from_handle(display: &Display, id: u64) -> Result<Window> {
Ok(Window { Ok(Window { display, inner: id })
display: display.as_raw(),
inner: id,
})
} }
/// Get window attributes. /// Get window attributes.
@ -65,7 +62,7 @@ impl Window {
let attr = unsafe { let attr = unsafe {
libc::malloc(mem::size_of::<xlib::XWindowAttributes>()) as *mut xlib::XWindowAttributes libc::malloc(mem::size_of::<xlib::XWindowAttributes>()) 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 { match result {
0 => Err(Error::GetAttributesError), 0 => Err(Error::GetAttributesError),
_ => Ok(WindowAttributes { _ => Ok(WindowAttributes {
@ -101,7 +98,7 @@ impl Window {
let v = val.as_raw(); let v = val.as_raw();
unsafe { unsafe {
xlib::XChangeProperty( xlib::XChangeProperty(
self.display, self.display.as_raw(),
self.inner, self.inner,
key.as_raw(), key.as_raw(),
xlib::XA_ATOM, xlib::XA_ATOM,
@ -115,7 +112,7 @@ impl Window {
/// "Maps", or shows a window to a display. /// "Maps", or shows a window to a display.
pub fn map(&self) { 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. /// 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. /// If this function is not called, events will not be reported.
pub fn select_input(&self, event_mask: EventMask) { pub fn select_input(&self, event_mask: EventMask) {
debug!("event mask: {:?}", event_mask); 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 { 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 { fn as_drawable(&self) -> xlib::Drawable {
self.inner self.inner
} }
} }
impl Drop for Window { impl<'a> Drop for Window<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { xlib::XDestroyWindow(self.display, self.inner) }; unsafe { xlib::XDestroyWindow(self.display.as_raw(), self.inner) };
} }
} }
/// Window Attributes /// Window Attributes
pub struct WindowAttributes { pub struct WindowAttributes<'a> {
pub(super) display: *mut xlib::Display, pub(super) display: &'a Display,
pub(self) inner: *mut xlib::XWindowAttributes, 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 /// Gets the width of the window
pub fn get_x(&self) -> i32 { pub fn get_x(&self) -> i32 {
unsafe { (*self.inner).x as 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! { bitflags! {
pub struct EventMask: c_ulong { pub struct EventMask: c_ulong {
const NO_EVENT_MASK = 0; const NO_EVENT_MASK = 0;