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]
name = "safex11"
version = "0.0.3"
version = "0.0.4"
description = "Safe, high-level x11 bindings"
license-file = "LICENSE"
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 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<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 {
@ -19,12 +30,33 @@ impl GlxExtension for Display {
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
.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<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);
}
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));

View file

@ -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};

View file

@ -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
}
}

View file

@ -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<Window>,
location: Rectangle,
) -> Result<Window> {
) -> Result<Window<'a>> {
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<Window> {
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::<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 {
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;