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"
log = "0.4.8"
bitflags = "1.2.1"
derivative = "2.1.1"
[build-dependencies]
gl_generator = { version = "0.14.0", optional = true }

View file

@ -3,6 +3,8 @@
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate derivative;
#[macro_use]
extern crate thiserror;
#[macro_use]
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 crate::xlib::{Display, IntoInt};
/// Mouse pointer
pub struct Cursor {
pub(crate) display: *mut xlib::Display,
pub(crate) inner: xlib::Cursor,
#[derive(Derivative)]
#[derivative(Debug)]
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) {
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);
}
Ok(Cursor {
display: self.inner,
display: self,
inner: cursor,
})
}

View file

@ -15,7 +15,7 @@ use crate::errors::{Error, Result};
///
/// Images consist of lines of longs in row-major form.
pub struct Image {
pub(super) inner: *mut xlib::XImage,
pub inner: *mut xlib::XImage,
}
/// Image byte order
@ -28,26 +28,31 @@ pub enum ImageByteOrder {
impl Image {
/// Get the size (in bytes) of the data buffer.
#[inline]
pub fn get_size(&self) -> usize {
4 * self.get_width() as usize * self.get_height() as usize
}
/// Get the image width
#[inline]
pub fn get_width(&self) -> u32 {
unsafe { (*self.inner).width as u32 }
}
/// Get the image height
#[inline]
pub fn get_height(&self) -> u32 {
unsafe { (*self.inner).height as u32 }
}
/// Get the image depth
#[inline]
pub fn get_depth(&self) -> u32 {
unsafe { (*self.inner).depth as u32 }
}
/// Get byte order (LSB or MSB)
#[inline]
pub fn get_byte_order(&self) -> Result<ImageByteOrder> {
let byte_order = unsafe { (*self.inner).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
/// 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.
#[inline]
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 pixel = unsafe { get_pixel(self.image.inner, x as i32, y as i32) };

View file

@ -2,6 +2,7 @@
mod atom;
mod cursor;
mod colormap;
mod display;
mod drawable;
mod event;
@ -10,12 +11,61 @@ mod pixmap;
mod visual;
mod window;
use x11::xlib;
pub use self::atom::Atom;
pub use self::cursor::Cursor;
pub use self::display::{Display, GetDisplay};
pub use self::colormap::Colormap;
pub use self::drawable::Drawable;
pub use self::event::{Event, EventKind};
pub use self::image::{Image, ImageByteOrder, PixBuffer};
pub use self::pixmap::Pixmap;
pub use self::visual::{Visual, VisualInfo};
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 crate::xlib::{Display, IntoInt};
/// Pixmaps are off-screen resources that are used for various operations, for
/// example, defining cursors as tiling patterns or as the source for certain
/// raster operations
@ -7,14 +9,22 @@ use x11::xlib;
/// 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
/// on which they were created.
#[derive(Debug)]
pub struct PixMap {
pub(crate) display: *mut xlib::Display,
#[derive(Derivative)]
#[derivative(Debug)]
pub struct Pixmap<'a> {
#[derivative(Debug = "ignore")]
pub(crate) display: &'a Display,
pub(crate) inner: xlib::Pixmap,
}
impl Drop for PixMap {
impl<'a> Drop for Pixmap<'a> {
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::os::raw::{c_long, c_ulong};
use std::ptr;
use x11::xlib;
use crate::errors::{Error, Result};
use crate::rect::Rectangle;
use super::atom::Atom;
use super::display::{Display, GetDisplay};
use super::drawable::Drawable;
use super::image::Image;
use super::pixmap::PixMap;
use crate::xlib::{Colormap, Atom, Cursor, Display, Drawable, GetDisplay, Image, Inherit, IntoInt, Noneable, Pixmap};
/// A wrapper around a window handle.
#[derive(Clone)]
pub struct Window<'a> {
pub(crate) display: &'a Display,
pub(crate) inner: xlib::Window,
pub display: &'a Display,
pub inner: xlib::Window,
}
impl<'a> Window<'a> {
@ -219,38 +213,113 @@ bitflags! {
}
}
#[derive(Debug, Default)]
pub struct SetWindowAttributes {
pub background_pixmap: Option<PixMap>,
#[derive(Debug)]
pub struct SetWindowAttributes<'a> {
pub background_pixmap: BackgroundPixmap<'a>,
pub background_pixel: c_ulong,
pub border_pixmap: Option<PixMap>,
pub border_pixmap: Inherit<Pixmap<'a>>,
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 event_mask: EventMask,
pub do_not_propagate_mask: c_long,
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 {
let result = xlib::XSetWindowAttributes {
background_pixmap: unimplemented!(),
background_pixmap: self.background_pixmap.into_int(),
background_pixel: self.background_pixel,
border_pixmap: unimplemented!(),
border_pixel: unimplemented!(),
bit_gravity: unimplemented!(),
win_gravity: unimplemented!(),
backing_store: unimplemented!(),
backing_planes: unimplemented!(),
backing_pixel: unimplemented!(),
border_pixmap: self.border_pixmap.into_int(),
border_pixel: self.border_pixel,
bit_gravity: self.bit_gravity,
win_gravity: self.win_gravity,
backing_store: self.backing_store.into_raw(),
backing_planes: self.backing_planes,
backing_pixel: self.backing_pixel,
save_under: self.save_under.into(),
event_mask: self.event_mask.bits() as i64,
do_not_propagate_mask: self.do_not_propagate_mask,
override_redirect: self.override_redirect.into(),
colormap: unimplemented!(),
cursor: unimplemented!(),
colormap: self.colormap.into_int(),
cursor: self.cursor.into_int(),
};
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,
}
}
}