This commit is contained in:
Michael Zhang 2020-10-20 21:11:11 -05:00
parent 5dbbe7be24
commit 4678092bbd
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
9 changed files with 203 additions and 37 deletions

View file

@ -26,6 +26,7 @@ x11 = { version = "2.18" }
thiserror = "1.0.20" thiserror = "1.0.20"
log = "0.4.8" log = "0.4.8"
bitflags = "1.2.1" bitflags = "1.2.1"
derivative = "2.1.1"
[build-dependencies] [build-dependencies]
gl_generator = { version = "0.14.0", optional = true } gl_generator = { version = "0.14.0", optional = true }

View file

@ -3,6 +3,8 @@
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
#[macro_use] #[macro_use]
extern crate derivative;
#[macro_use]
extern crate thiserror; extern crate thiserror;
#[macro_use] #[macro_use]
extern crate log; extern crate log;

17
src/xlib/colormap.rs Normal file
View file

@ -0,0 +1,17 @@
use x11::xlib;
use crate::xlib::{Display, IntoInt};
#[derive(Derivative)]
#[derivative(Debug)]
pub struct Colormap<'a> {
#[derivative(Debug = "ignore")]
pub display: &'a Display,
pub inner: xlib::Colormap,
}
impl<'a> IntoInt for Colormap<'a> {
fn into_int(&self) -> u64 {
self.inner
}
}

View file

@ -1,13 +1,24 @@
use x11::xlib; use x11::xlib;
use crate::xlib::{Display, IntoInt};
/// Mouse pointer /// Mouse pointer
pub struct Cursor { #[derive(Derivative)]
pub(crate) display: *mut xlib::Display, #[derivative(Debug)]
pub(crate) inner: xlib::Cursor, pub struct Cursor<'a> {
#[derivative(Debug = "ignore")]
pub display: &'a Display,
pub inner: xlib::Cursor,
} }
impl Drop for Cursor { impl<'a> Drop for Cursor<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { xlib::XFreeCursor(self.display, self.inner) }; unsafe { xlib::XFreeCursor(self.display.inner, self.inner) };
}
}
impl<'a> IntoInt for Cursor<'a> {
fn into_int(&self) -> u64 {
self.inner
} }
} }

View file

@ -62,7 +62,7 @@ impl Display {
return Err(Error::CreateCursorError); return Err(Error::CreateCursorError);
} }
Ok(Cursor { Ok(Cursor {
display: self.inner, display: self,
inner: cursor, inner: cursor,
}) })
} }

View file

@ -15,7 +15,7 @@ use crate::errors::{Error, Result};
/// ///
/// Images consist of lines of longs in row-major form. /// Images consist of lines of longs in row-major form.
pub struct Image { pub struct Image {
pub(super) inner: *mut xlib::XImage, pub inner: *mut xlib::XImage,
} }
/// Image byte order /// Image byte order
@ -28,26 +28,31 @@ pub enum ImageByteOrder {
impl Image { impl Image {
/// Get the size (in bytes) of the data buffer. /// Get the size (in bytes) of the data buffer.
#[inline]
pub fn get_size(&self) -> usize { pub fn get_size(&self) -> usize {
4 * self.get_width() as usize * self.get_height() as usize 4 * self.get_width() as usize * self.get_height() as usize
} }
/// Get the image width /// Get the image width
#[inline]
pub fn get_width(&self) -> u32 { pub fn get_width(&self) -> u32 {
unsafe { (*self.inner).width as u32 } unsafe { (*self.inner).width as u32 }
} }
/// Get the image height /// Get the image height
#[inline]
pub fn get_height(&self) -> u32 { pub fn get_height(&self) -> u32 {
unsafe { (*self.inner).height as u32 } unsafe { (*self.inner).height as u32 }
} }
/// Get the image depth /// Get the image depth
#[inline]
pub fn get_depth(&self) -> u32 { pub fn get_depth(&self) -> u32 {
unsafe { (*self.inner).depth as u32 } unsafe { (*self.inner).depth as u32 }
} }
/// Get byte order (LSB or MSB) /// Get byte order (LSB or MSB)
#[inline]
pub fn get_byte_order(&self) -> Result<ImageByteOrder> { pub fn get_byte_order(&self) -> Result<ImageByteOrder> {
let byte_order = unsafe { (*self.inner).byte_order }; let byte_order = unsafe { (*self.inner).byte_order };
match byte_order { match byte_order {
@ -109,6 +114,7 @@ impl<'a> PixBuffer<'a> {
/// This uses XImage's get_pixel function to retrieve the pixel value, and then the various /// This uses XImage's get_pixel function to retrieve the pixel value, and then the various
/// red/green/blue masks to actually perform the conversions, and fails (returns `None`) if the /// red/green/blue masks to actually perform the conversions, and fails (returns `None`) if the
/// (x, y) coordinates given aren't actually in the image. /// (x, y) coordinates given aren't actually in the image.
#[inline]
pub fn get_pixel(&self, x: u32, y: u32) -> Option<(u8, u8, u8)> { pub fn get_pixel(&self, x: u32, y: u32) -> Option<(u8, u8, u8)> {
let get_pixel = unsafe { (*self.image.inner).funcs.get_pixel }.unwrap(); let get_pixel = unsafe { (*self.image.inner).funcs.get_pixel }.unwrap();
let pixel = unsafe { get_pixel(self.image.inner, x as i32, y as i32) }; let pixel = unsafe { get_pixel(self.image.inner, x as i32, y as i32) };

View file

@ -2,6 +2,7 @@
mod atom; mod atom;
mod cursor; mod cursor;
mod colormap;
mod display; mod display;
mod drawable; mod drawable;
mod event; mod event;
@ -10,12 +11,61 @@ mod pixmap;
mod visual; mod visual;
mod window; mod window;
use x11::xlib;
pub use self::atom::Atom; pub use self::atom::Atom;
pub use self::cursor::Cursor; pub use self::cursor::Cursor;
pub use self::display::{Display, GetDisplay}; pub use self::display::{Display, GetDisplay};
pub use self::colormap::Colormap;
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::pixmap::Pixmap;
pub use self::visual::{Visual, VisualInfo}; pub use self::visual::{Visual, VisualInfo};
pub use self::window::{EventMask, SetWindowAttributes, Window, WindowAttributes}; pub use self::window::{EventMask, SetWindowAttributes, Window, WindowAttributes};
pub use self::pixmap::PixMap;
#[derive(Debug)]
pub enum Inherit<T> {
Value(T),
CopyFromParent,
}
impl<T> Default for Inherit<T> {
fn default() -> Self {
Inherit::CopyFromParent
}
}
pub trait IntoInt {
fn into_int(&self) -> u64;
}
impl<T: IntoInt> IntoInt for Inherit<T> {
fn into_int(&self) -> u64 {
match self {
Inherit::Value(t) => t.into_int(),
Inherit::CopyFromParent => xlib::CopyFromParent as u64,
}
}
}
#[derive(Debug)]
pub enum Noneable<T> {
Value(T),
None,
}
impl<T> Default for Noneable<T> {
fn default() -> Self {
Noneable::None
}
}
impl<T: IntoInt> IntoInt for Noneable<T> {
fn into_int(&self) -> u64 {
match self {
Noneable::Value(t) => t.into_int(),
Noneable::None => 0,
}
}
}

View file

@ -1,5 +1,7 @@
use x11::xlib; use x11::xlib;
use crate::xlib::{Display, IntoInt};
/// Pixmaps are off-screen resources that are used for various operations, for /// Pixmaps are off-screen resources that are used for various operations, for
/// example, defining cursors as tiling patterns or as the source for certain /// example, defining cursors as tiling patterns or as the source for certain
/// raster operations /// raster operations
@ -7,14 +9,22 @@ use x11::xlib;
/// Most graphics requests can operate either on a window or on a pixmap. A /// Most graphics requests can operate either on a window or on a pixmap. A
/// bitmap is a single bit-plane pixmap. Pixmaps can only be used on the screen /// bitmap is a single bit-plane pixmap. Pixmaps can only be used on the screen
/// on which they were created. /// on which they were created.
#[derive(Debug)] #[derive(Derivative)]
pub struct PixMap { #[derivative(Debug)]
pub(crate) display: *mut xlib::Display, pub struct Pixmap<'a> {
#[derivative(Debug = "ignore")]
pub(crate) display: &'a Display,
pub(crate) inner: xlib::Pixmap, pub(crate) inner: xlib::Pixmap,
} }
impl Drop for PixMap { impl<'a> Drop for Pixmap<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { xlib::XFreePixmap(self.display, self.inner) }; unsafe { xlib::XFreePixmap(self.display.inner, self.inner) };
}
}
impl<'a> IntoInt for Pixmap<'a> {
fn into_int(&self) -> u64 {
self.inner
} }
} }

View file

@ -1,23 +1,17 @@
use std::mem; use std::mem;
use std::os::raw::{c_long, c_ulong}; use std::os::raw::{c_long, c_ulong};
use std::ptr;
use x11::xlib; use x11::xlib;
use crate::errors::{Error, Result}; use crate::errors::{Error, Result};
use crate::rect::Rectangle; use crate::rect::Rectangle;
use crate::xlib::{Colormap, Atom, Cursor, Display, Drawable, GetDisplay, Image, Inherit, IntoInt, Noneable, Pixmap};
use super::atom::Atom;
use super::display::{Display, GetDisplay};
use super::drawable::Drawable;
use super::image::Image;
use super::pixmap::PixMap;
/// A wrapper around a window handle. /// A wrapper around a window handle.
#[derive(Clone)] #[derive(Clone)]
pub struct Window<'a> { pub struct Window<'a> {
pub(crate) display: &'a Display, pub display: &'a Display,
pub(crate) inner: xlib::Window, pub inner: xlib::Window,
} }
impl<'a> Window<'a> { impl<'a> Window<'a> {
@ -219,38 +213,113 @@ bitflags! {
} }
} }
#[derive(Debug, Default)] #[derive(Debug)]
pub struct SetWindowAttributes { pub struct SetWindowAttributes<'a> {
pub background_pixmap: Option<PixMap>, pub background_pixmap: BackgroundPixmap<'a>,
pub background_pixel: c_ulong, pub background_pixel: c_ulong,
pub border_pixmap: Option<PixMap>, pub border_pixmap: Inherit<Pixmap<'a>>,
pub border_pixel: c_ulong, pub border_pixel: c_ulong,
pub bit_gravity: i32,
pub win_gravity: i32,
pub backing_store: BackingStore,
pub backing_planes: u64,
pub backing_pixel: u64,
pub save_under: bool, pub save_under: bool,
pub event_mask: EventMask, pub event_mask: EventMask,
pub do_not_propagate_mask: c_long, pub do_not_propagate_mask: c_long,
pub override_redirect: bool, pub override_redirect: bool,
pub colormap: Inherit<Colormap<'a>>,
pub cursor: Noneable<Cursor<'a>>,
} }
impl SetWindowAttributes { impl<'a> Default for SetWindowAttributes<'a> {
fn default() -> Self {
SetWindowAttributes {
background_pixmap: BackgroundPixmap::default(),
background_pixel: 0,
border_pixmap: Inherit::default(),
border_pixel: 0,
bit_gravity: xlib::ForgetGravity,
win_gravity: xlib::NorthWestGravity,
backing_store: BackingStore::default(),
backing_planes: 0xffffffff,
backing_pixel: 0,
save_under: false,
event_mask: EventMask::empty(),
do_not_propagate_mask: 0,
override_redirect: false,
colormap: Inherit::default(),
cursor: Noneable::default(),
}
}
}
impl<'a> SetWindowAttributes<'a> {
pub fn into_raw(self) -> *mut xlib::XSetWindowAttributes { pub fn into_raw(self) -> *mut xlib::XSetWindowAttributes {
let result = xlib::XSetWindowAttributes { let result = xlib::XSetWindowAttributes {
background_pixmap: unimplemented!(), background_pixmap: self.background_pixmap.into_int(),
background_pixel: self.background_pixel, background_pixel: self.background_pixel,
border_pixmap: unimplemented!(), border_pixmap: self.border_pixmap.into_int(),
border_pixel: unimplemented!(), border_pixel: self.border_pixel,
bit_gravity: unimplemented!(), bit_gravity: self.bit_gravity,
win_gravity: unimplemented!(), win_gravity: self.win_gravity,
backing_store: unimplemented!(), backing_store: self.backing_store.into_raw(),
backing_planes: unimplemented!(), backing_planes: self.backing_planes,
backing_pixel: unimplemented!(), backing_pixel: self.backing_pixel,
save_under: self.save_under.into(), save_under: self.save_under.into(),
event_mask: self.event_mask.bits() as i64, event_mask: self.event_mask.bits() as i64,
do_not_propagate_mask: self.do_not_propagate_mask, do_not_propagate_mask: self.do_not_propagate_mask,
override_redirect: self.override_redirect.into(), override_redirect: self.override_redirect.into(),
colormap: unimplemented!(), colormap: self.colormap.into_int(),
cursor: unimplemented!(), cursor: self.cursor.into_int(),
}; };
Box::into_raw(Box::new(result)) Box::into_raw(Box::new(result))
} }
} }
#[derive(Debug)]
pub enum BackgroundPixmap<'a> {
Background(Pixmap<'a>),
None,
ParentRelative,
}
impl<'a> Default for BackgroundPixmap<'a> {
fn default() -> Self {
BackgroundPixmap::None
}
}
impl<'a> IntoInt for BackgroundPixmap<'a> {
fn into_int(&self) -> u64 {
match self {
BackgroundPixmap::Background(pixmap) => pixmap.inner,
BackgroundPixmap::None => 0,
BackgroundPixmap::ParentRelative => xlib::ParentRelative as u64,
}
}
}
#[derive(Debug)]
pub enum BackingStore {
NotUseful,
WhenMapped,
Always,
}
impl Default for BackingStore {
fn default() -> Self {
BackingStore::NotUseful
}
}
impl BackingStore {
fn into_raw(self) -> i32 {
match self {
BackingStore::NotUseful => xlib::NotUseful,
BackingStore::WhenMapped => xlib::WhenMapped,
BackingStore::Always => xlib::Always,
}
}
}