diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..70f9eae --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[registries.crates-io] +protocol = "sparse" diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 4fffb2f..63d1d01 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /Cargo.lock +.direnv diff --git a/Cargo.toml b/Cargo.toml index a114ddc..d4c124f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,11 +22,11 @@ xinput = ["x11/xinput"] [dependencies] libc = "0.2" -x11 = { version = "2.18" } -thiserror = "1.0.20" -log = "0.4.8" -bitflags = "1.2.1" -derivative = "2.1.1" +x11 = { version = "2.21" } +thiserror = "1.0.47" +log = "0.4.20" +bitflags = "2.4.0" +derivative = "2.2.0" [build-dependencies] gl_generator = { version = "0.14.0", optional = true } diff --git a/build.rs b/build.rs index 65c090b..91a97c0 100644 --- a/build.rs +++ b/build.rs @@ -6,13 +6,13 @@ use std::path::Path; use gl_generator::{Api, Fallbacks, GlobalGenerator, Profile, Registry}; fn main() { - #[cfg(feature = "glx")] - { - let dest = env::var("OUT_DIR").unwrap(); - let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap(); + #[cfg(feature = "glx")] + { + let dest = env::var("OUT_DIR").unwrap(); + let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap(); - Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, []) - .write_bindings(GlobalGenerator, &mut file) - .unwrap(); - } + Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, []) + .write_bindings(GlobalGenerator, &mut file) + .unwrap(); + } } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1501aef --- /dev/null +++ b/flake.lock @@ -0,0 +1,111 @@ +{ + "nodes": { + "fenix": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1692512345, + "narHash": "sha256-ztOkYlG6LgS5AyjcQG3XWX3MRBQCHmTVlW3rhd2UdJs=", + "owner": "nix-community", + "repo": "fenix", + "rev": "75907b374bd1b95fe7ebaa482e4872caae9da081", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1692447944, + "narHash": "sha256-fkJGNjEmTPvqBs215EQU4r9ivecV5Qge5cF/QDLVn3U=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d680ded26da5cf104dd2735a51e88d2d8f487b4d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1663551060, + "narHash": "sha256-e2SR4cVx9p7aW/XnVsGsWZBplApA9ZJUjc0fejJhnYo=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8a5b9ee7b7a2b38267c9481f5c629c015108ab0d", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "fenix": "fenix", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_2" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1692456871, + "narHash": "sha256-ribQkxEbMMb8vcBMKvcrPHFftMmlaF3HIAbJty9fDeY=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "83b3ba1b8191c065bb0dacc79e5896f7f21e4611", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c2975e3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + inputs = { fenix.url = "github:nix-community/fenix"; }; + + outputs = { self, nixpkgs, flake-utils, fenix }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ fenix.overlays.default ]; + }; + + toolchain = pkgs.fenix.stable; + + flakePkgs = rec { }; + in rec { + packages = flake-utils.lib.flattenTree flakePkgs; + + devShell = pkgs.mkShell { + inputsFrom = with packages; [ ]; + + packages = (with pkgs; [ + cargo-watch + cargo-deny + cargo-edit + cargo-expand + + pkg-config + xlibsWrapper + + # Get the nightly version of rustfmt so we can wrap comments + pkgs.fenix.default.rustfmt + ]) ++ (with toolchain; [ cargo clippy rustc rustfmt ]); + }; + }); +} diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..a3be6a8 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +max_width = 80 +tab_spaces = 2 +wrap_comments = true diff --git a/src/errors.rs b/src/errors.rs index 5cb66ee..b6d8770 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,33 +4,33 @@ pub type Result = std::result::Result; #[allow(missing_docs)] #[derive(Debug, Error)] pub enum Error { - #[error("invalid image byte order: {0}")] - InvalidByteOrder(i32), + #[error("invalid image byte order: {0}")] + InvalidByteOrder(i32), - #[error("invalid event type: {0}")] - InvalidEventType(i32), + #[error("invalid event type: {0}")] + InvalidEventType(i32), - #[error("failed to get attributes")] - GetAttributesError, + #[error("failed to get attributes")] + GetAttributesError, - #[error("failed to create cursor")] - CreateCursorError, + #[error("failed to create cursor")] + CreateCursorError, - #[error("failed to open display")] - DisplayOpenError, + #[error("failed to open display")] + DisplayOpenError, - #[error("failed to get window")] - GetWindowError, + #[error("failed to get window")] + GetWindowError, - #[error("failed to translate coordinates")] - TranslateCoordinatesError, + #[error("failed to translate coordinates")] + TranslateCoordinatesError, - #[error("utf8 decoding error: {0}")] - Utf8(#[from] std::str::Utf8Error), + #[error("utf8 decoding error: {0}")] + Utf8(#[from] std::str::Utf8Error), - #[error("nul error: {0}")] - Nul(#[from] std::ffi::NulError), + #[error("nul error: {0}")] + Nul(#[from] std::ffi::NulError), - #[error("error")] - Error, + #[error("error")] + Error, } diff --git a/src/ffi.rs b/src/ffi.rs index 44fcea5..1b97254 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -4,12 +4,12 @@ use std::os::raw::c_char; use crate::Result; pub unsafe fn string_from_c_char_star(ptr: *mut c_char) -> Result { - let c_str = CStr::from_ptr(ptr); - let s = c_str.to_str()?; - Ok(s.to_owned()) + let c_str = CStr::from_ptr(ptr); + let s = c_str.to_str()?; + Ok(s.to_owned()) } pub fn c_char_star_from_string(s: impl AsRef) -> Result<*mut c_char> { - let c_str = CString::new(s.as_ref().as_bytes())?; - Ok(c_str.into_raw()) + let c_str = CString::new(s.as_ref().as_bytes())?; + Ok(c_str.into_raw()) } diff --git a/src/glx/context.rs b/src/glx/context.rs index f3023bf..3b102a6 100644 --- a/src/glx/context.rs +++ b/src/glx/context.rs @@ -3,18 +3,18 @@ use x11::glx; use crate::xlib::Display; pub struct GlxContext<'a> { - pub(super) display: &'a Display, - pub(super) ctx: glx::GLXContext, + pub(super) display: &'a Display, + pub(super) ctx: glx::GLXContext, } impl<'a> GlxContext<'a> { - pub fn as_raw(&self) -> glx::GLXContext { - self.ctx - } + pub fn as_raw(&self) -> glx::GLXContext { + self.ctx + } } impl<'a> Drop for GlxContext<'a> { - fn drop(&mut self) { - unsafe { glx::glXDestroyContext(self.display.as_raw(), self.ctx) }; - } + fn drop(&mut self) { + unsafe { glx::glXDestroyContext(self.display.as_raw(), self.ctx) }; + } } diff --git a/src/glx/drawable.rs b/src/glx/drawable.rs index 7b3242b..69c2936 100644 --- a/src/glx/drawable.rs +++ b/src/glx/drawable.rs @@ -3,14 +3,14 @@ use x11::xlib; use crate::xlib::Window; pub enum GlxDrawable<'a> { - Window(Window<'a>), - // TODO: pixmap + Window(Window<'a>), + // TODO: pixmap } impl<'a> GlxDrawable<'a> { - pub fn as_raw(&self) -> xlib::XID { - match self { - GlxDrawable::Window(window) => window.as_raw(), - } + 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 ccd143e..a77c0ec 100644 --- a/src/glx/mod.rs +++ b/src/glx/mod.rs @@ -13,54 +13,58 @@ pub use self::context::GlxContext; pub use self::drawable::GlxDrawable; pub trait GlxExtension { - /// Checks if glx is available in this implementation. - fn query_glx_extension(&self) -> Result; + /// Checks if glx is available in this implementation. + fn query_glx_extension(&self) -> Result; - fn create_context( - &self, - visual_info: &VisualInfo, - 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 make_current(&self, drawable: GlxDrawable, ctx: GlxContext) -> Result<()>; - fn choose_visual(&self, screen: i32) -> Result; + fn choose_visual(&self, screen: i32) -> Result; } impl GlxExtension for Display { - fn query_glx_extension(&self) -> Result { - let result = unsafe { glx::glXQueryExtension(self.inner, 0 as *mut _, 0 as *mut _) }; - Ok(result == 1) - } + fn query_glx_extension(&self) -> Result { + let result = + unsafe { glx::glXQueryExtension(self.inner, 0 as *mut _, 0 as *mut _) }; + Ok(result == 1) + } - 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(), - visual_info.as_raw(), - share_list, - direct.into(), - ) - }; - Ok(GlxContext { display: self, ctx }) - } + 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(), + 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 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)) - } + 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/lib.rs b/src/lib.rs index fa9f188..49f84db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ pub extern crate x11; #[cfg(feature = "glx")] mod gl { - include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } #[cfg(feature = "glx")] pub mod glx; diff --git a/src/rect.rs b/src/rect.rs index b77ad36..cb17714 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -1,35 +1,35 @@ /// A rectangle. #[derive(Debug)] pub struct Rectangle { - /// x - pub x: i32, - /// y - pub y: i32, - /// width - pub width: u32, - /// height - pub height: u32, + /// x + pub x: i32, + /// y + pub y: i32, + /// width + pub width: u32, + /// height + pub height: u32, } impl Rectangle { - /// Create a new Rectangle from u32s - pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self { - Rectangle { - x, - y, - width, - height, - } + /// Create a new Rectangle from u32s + pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self { + Rectangle { + x, + y, + width, + height, } + } } impl From<(i32, i32, u32, u32)> for Rectangle { - fn from((x, y, width, height): (i32, i32, u32, u32)) -> Self { - Rectangle { - x, - y, - width, - height, - } + fn from((x, y, width, height): (i32, i32, u32, u32)) -> Self { + Rectangle { + x, + y, + width, + height, } + } } diff --git a/src/xinerama/screen_info.rs b/src/xinerama/screen_info.rs index a5909ca..1496d6a 100644 --- a/src/xinerama/screen_info.rs +++ b/src/xinerama/screen_info.rs @@ -4,61 +4,63 @@ use crate::errors::Result; use crate::xlib::Display; pub struct ScreensInfo { - inner: *mut xinerama::XineramaScreenInfo, - heads: isize, + inner: *mut xinerama::XineramaScreenInfo, + heads: isize, } impl ScreensInfo { - pub fn query(display: &Display) -> Result { - let mut heads = 0; - let inner = unsafe { xinerama::XineramaQueryScreens(display.inner, &mut heads as *mut _) }; - // TODO: check for error - Ok(ScreensInfo { - inner, - heads: heads as isize, - }) - } + pub fn query(display: &Display) -> Result { + let mut heads = 0; + let inner = unsafe { + xinerama::XineramaQueryScreens(display.inner, &mut heads as *mut _) + }; + // TODO: check for error + Ok(ScreensInfo { + inner, + heads: heads as isize, + }) + } - pub fn iter(&self) -> ScreenInfoIter { - ScreenInfoIter(self, 0) - } + pub fn iter(&self) -> ScreenInfoIter { + ScreenInfoIter(self, 0) + } } impl Drop for ScreensInfo { - fn drop(&mut self) { - unsafe { x11::xlib::XFree(self.inner as *mut _) }; - } + fn drop(&mut self) { + unsafe { x11::xlib::XFree(self.inner as *mut _) }; + } } pub struct ScreenInfoIter<'a>(&'a ScreensInfo, isize); pub struct ScreenInfo { - pub x: i16, - pub y: i16, - pub width: i16, - pub height: i16, + pub x: i16, + pub y: i16, + pub width: i16, + pub height: i16, } impl<'a> Iterator for ScreenInfoIter<'a> { - type Item = (i32, ScreenInfo); - fn next(&mut self) -> Option { - if self.1 >= self.0.heads { - return None; - } - - let screen = unsafe { self.0.inner.offset(self.1) }; - self.1 += 1; - - unsafe { - Some(( - (*screen).screen_number as i32, - ScreenInfo { - x: (*screen).x_org as i16, - y: (*screen).y_org as i16, - width: (*screen).width as i16, - height: (*screen).height as i16, - }, - )) - } + type Item = (i32, ScreenInfo); + fn next(&mut self) -> Option { + if self.1 >= self.0.heads { + return None; } + + let screen = unsafe { self.0.inner.offset(self.1) }; + self.1 += 1; + + unsafe { + Some(( + (*screen).screen_number as i32, + ScreenInfo { + x: (*screen).x_org as i16, + y: (*screen).y_org as i16, + width: (*screen).width as i16, + height: (*screen).height as i16, + }, + )) + } + } } diff --git a/src/xlib/atom.rs b/src/xlib/atom.rs index 469ab5b..5e6c724 100644 --- a/src/xlib/atom.rs +++ b/src/xlib/atom.rs @@ -8,29 +8,38 @@ use super::display::Display; /// A unique string or intger pub struct Atom { - inner: xlib::Atom, + inner: xlib::Atom, } impl Atom { - /// Create a new atom using a string - pub fn new(display: &Display, val: impl AsRef, only_if_exists: bool) -> Result { - let val = { - let v = val.as_ref(); - let s = CString::new(v).unwrap(); - s.as_ptr() - }; - let inner = - unsafe { xlib::XInternAtom(display.as_raw(), val, if only_if_exists { 1 } else { 0 }) }; - Ok(Atom { inner }) - } + /// Create a new atom using a string + pub fn new( + display: &Display, + val: impl AsRef, + only_if_exists: bool, + ) -> Result { + let val = { + let v = val.as_ref(); + let s = CString::new(v).unwrap(); + s.as_ptr() + }; + let inner = unsafe { + xlib::XInternAtom( + display.as_raw(), + val, + if only_if_exists { 1 } else { 0 }, + ) + }; + Ok(Atom { inner }) + } - /// Create a new Atom object from an existing handle - pub fn from(handle: xlib::Atom) -> Self { - Atom { inner: handle } - } + /// Create a new Atom object from an existing handle + pub fn from(handle: xlib::Atom) -> Self { + Atom { inner: handle } + } - /// Get the handle - pub fn as_raw(&self) -> xlib::Atom { - self.inner - } + /// Get the handle + pub fn as_raw(&self) -> xlib::Atom { + self.inner + } } diff --git a/src/xlib/colormap.rs b/src/xlib/colormap.rs index 29e74db..baf85d4 100644 --- a/src/xlib/colormap.rs +++ b/src/xlib/colormap.rs @@ -5,13 +5,13 @@ use crate::xlib::{Display, IntoInt}; #[derive(Derivative)] #[derivative(Debug)] pub struct Colormap<'a> { - #[derivative(Debug = "ignore")] - pub display: &'a Display, - pub inner: xlib::Colormap, + #[derivative(Debug = "ignore")] + pub display: &'a Display, + pub inner: xlib::Colormap, } impl<'a> IntoInt for Colormap<'a> { - fn into_int(&self) -> u64 { - self.inner - } + fn into_int(&self) -> u64 { + self.inner + } } diff --git a/src/xlib/cursor.rs b/src/xlib/cursor.rs index d9388ef..2138434 100644 --- a/src/xlib/cursor.rs +++ b/src/xlib/cursor.rs @@ -6,19 +6,19 @@ use crate::xlib::{Display, IntoInt}; #[derive(Derivative)] #[derivative(Debug)] pub struct Cursor<'a> { - #[derivative(Debug = "ignore")] - pub display: &'a Display, - pub inner: xlib::Cursor, + #[derivative(Debug = "ignore")] + pub display: &'a Display, + pub inner: xlib::Cursor, } impl<'a> Drop for Cursor<'a> { - fn drop(&mut self) { - unsafe { xlib::XFreeCursor(self.display.inner, self.inner) }; - } + fn drop(&mut self) { + unsafe { xlib::XFreeCursor(self.display.inner, self.inner) }; + } } impl<'a> IntoInt for Cursor<'a> { - fn into_int(&self) -> u64 { - self.inner - } + fn into_int(&self) -> u64 { + self.inner + } } diff --git a/src/xlib/display.rs b/src/xlib/display.rs index 861267f..3e112ae 100644 --- a/src/xlib/display.rs +++ b/src/xlib/display.rs @@ -15,231 +15,235 @@ use super::window::Window; /// A connection to an X server. pub struct Display { - pub(crate) inner: *mut xlib::Display, + pub(crate) inner: *mut xlib::Display, } pub struct Grab(pub(crate) *mut xlib::Display); /// Something that's part of a display. pub trait GetDisplay { - /// Get the current display - fn get_display(&self) -> *mut xlib::Display; + /// Get the current display + fn get_display(&self) -> *mut xlib::Display; } impl Display { - /// Opens a new connection to an X server. - /// - /// On POSIX-conformant systems, the display name or DISPLAY environment - /// variable can be a string in the format: - /// - /// hostname:number.screen_number - pub fn connect(display_name: impl AsRef) -> Result { - let display_name = CString::new(display_name.as_ref()).unwrap(); - let inner = unsafe { xlib::XOpenDisplay(display_name.as_ptr()) }; - if inner.is_null() { - return Err(Error::DisplayOpenError); - } - Ok(Display { inner }) + /// Opens a new connection to an X server. + /// + /// On POSIX-conformant systems, the display name or DISPLAY environment + /// variable can be a string in the format: + /// + /// hostname:number.screen_number + pub fn connect(display_name: impl AsRef) -> Result { + let display_name = CString::new(display_name.as_ref()).unwrap(); + let inner = unsafe { xlib::XOpenDisplay(display_name.as_ptr()) }; + if inner.is_null() { + return Err(Error::DisplayOpenError); } + Ok(Display { inner }) + } - /// Create a Display for an existing connection - pub fn from_handle(handle: u64) -> Self { - Display { - inner: handle as *mut xlib::Display, - } + /// Create a Display for an existing connection + pub fn from_handle(handle: u64) -> Self { + Display { + inner: handle as *mut xlib::Display, } + } - /// Grab - pub fn grab(&self) -> Grab { - unsafe { xlib::XGrabServer(self.inner) }; - Grab(self.inner) + /// Grab + pub fn grab(&self) -> Grab { + unsafe { xlib::XGrabServer(self.inner) }; + Grab(self.inner) + } + + /// Wrapper around XCreateFontCursor + pub fn create_font_cursor(&self, shape: u32) -> Result { + let cursor = + unsafe { xlib::XCreateFontCursor(self.inner, shape) as xlib::Cursor }; + if cursor == 0 { + return Err(Error::CreateCursorError); } + Ok(Cursor { + display: self, + inner: cursor, + }) + } - /// Wrapper around XCreateFontCursor - pub fn create_font_cursor(&self, shape: u32) -> Result { - let cursor = unsafe { xlib::XCreateFontCursor(self.inner, shape) as xlib::Cursor }; - if cursor == 0 { - return Err(Error::CreateCursorError); - } - Ok(Cursor { - display: self, - inner: cursor, - }) + /// Get the next event, blocks until an event is reached. + pub fn next_event(&self) -> Result { + debug!("fishing for next event..."); + let mut event = MaybeUninit::uninit(); + let ptr = event.as_mut_ptr(); + unsafe { xlib::XNextEvent(self.inner, ptr) }; + // TODO: check to make sure this isn't null + let event = unsafe { event.assume_init() }; + debug!("event: {:?}", event); + unsafe { Event::from_raw(event) } + } + + /// Returns the number of events that are still pending + pub fn pending(&self) -> Result { + Ok(unsafe { xlib::XPending(self.inner) }) + } + + /// Gets the raw X Display handle + pub fn as_raw(&self) -> *mut xlib::Display { + self.inner + } + + /// Gets the default visual + pub fn default_visual(&self, screen: i32) -> Visual { + let visual = unsafe { xlib::XDefaultVisual(self.inner, screen) }; + Visual { inner: visual } + } + + /// Returns the root window for the given screen. + pub fn get_root_window(&self, screen: i32) -> Result { + let inner = unsafe { xlib::XRootWindow(self.inner, screen) }; + if inner == 0 { + return Err(Error::GetWindowError); } + let window = Window { + display: self, + inner, + }; + Ok(window) + } - /// Get the next event, blocks until an event is reached. - pub fn next_event(&self) -> Result { - debug!("fishing for next event..."); - let mut event = MaybeUninit::uninit(); - let ptr = event.as_mut_ptr(); - unsafe { xlib::XNextEvent(self.inner, ptr) }; - // TODO: check to make sure this isn't null - let event = unsafe { event.assume_init() }; - debug!("event: {:?}", event); - unsafe { Event::from_raw(event) } + /// Returns the root window for the default screen. + pub fn get_default_root_window(&self) -> Result { + let inner = unsafe { xlib::XDefaultRootWindow(self.inner) }; + if inner == 0 { + return Err(Error::GetWindowError); } + let window = Window { + display: self, + inner, + }; + Ok(window) + } - /// Returns the number of events that are still pending - pub fn pending(&self) -> Result { - Ok(unsafe { xlib::XPending(self.inner) }) + /// Translate coordinates relative to w1 to coordinates relative to w2. + /// If the coordinates are contained in a mapped child of the destination + /// window, the third return value will hold that child window. + pub fn translate_coordinates( + &self, + w1: Window, + x: i32, + y: i32, + w2: Window, + ) -> Result<(i32, i32, Option)> { + let mut rx = 0; + let mut ry = 0; + let mut child_return: xlib::Window = 0; + let status = unsafe { + xlib::XTranslateCoordinates( + self.inner, + w1.inner, + w2.inner, + x, + y, + &mut rx, + &mut ry, + &mut child_return, + ) + }; + if status == 0 { + return Err(Error::TranslateCoordinatesError); } + let child = match child_return { + 0 => None, + val => Some(Window { + display: self, + inner: val, + }), + }; + Ok((rx, ry, child)) + } - /// Gets the raw X Display handle - pub fn as_raw(&self) -> *mut xlib::Display { - self.inner - } + /// Sync + pub fn sync(&self, discard: bool) { + unsafe { xlib::XSync(self.inner, if discard { 1 } else { 0 }) }; + } - /// Gets the default visual - pub fn default_visual(&self, screen: i32) -> Visual { - let visual = unsafe { xlib::XDefaultVisual(self.inner, screen) }; - Visual { inner: visual } - } + /// Returns the focus window and the current focus state. + pub fn get_input_focus(&self) -> Result<(Window, i32)> { + let mut focus_return: xlib::Window = 0; + let mut revert_to_return = 0; + unsafe { + xlib::XGetInputFocus(self.inner, &mut focus_return, &mut revert_to_return) + }; + let window = Window { + display: self, + inner: focus_return, + }; + return Ok((window, revert_to_return)); + } - /// Returns the root window for the given screen. - pub fn get_root_window(&self, screen: i32) -> Result { - let inner = unsafe { xlib::XRootWindow(self.inner, screen) }; - if inner == 0 { - return Err(Error::GetWindowError); - } - let window = Window { - display: self, - inner, - }; - Ok(window) - } + /// Query extension + pub fn query_extension(&self, name: impl AsRef) -> Result<()> { + let name = ffi::c_char_star_from_string(name)?; + let major_opcode_return = ptr::null_mut(); + let first_event_return = ptr::null_mut(); + let first_error_return = ptr::null_mut(); + let _result = unsafe { + xlib::XQueryExtension( + self.inner, + name, + major_opcode_return, + first_event_return, + first_error_return, + ) + }; + // TODO: check reuslt - /// Returns the root window for the default screen. - pub fn get_default_root_window(&self) -> Result { - let inner = unsafe { xlib::XDefaultRootWindow(self.inner) }; - if inner == 0 { - return Err(Error::GetWindowError); - } - let window = Window { - display: self, - inner, - }; - Ok(window) - } + unimplemented!() + } - /// Translate coordinates relative to w1 to coordinates relative to w2. - /// If the coordinates are contained in a mapped child of the destination window, the third return - /// value will hold that child window. - pub fn translate_coordinates( - &self, - w1: Window, - x: i32, - y: i32, - w2: Window, - ) -> Result<(i32, i32, Option)> { - let mut rx = 0; - let mut ry = 0; - let mut child_return: xlib::Window = 0; - let status = unsafe { - xlib::XTranslateCoordinates( - self.inner, - w1.inner, - w2.inner, - x, - y, - &mut rx, - &mut ry, - &mut child_return, - ) - }; - if status == 0 { - return Err(Error::TranslateCoordinatesError); - } - let child = match child_return { - 0 => None, - val => Some(Window { - display: self, - inner: val, - }), - }; - Ok((rx, ry, child)) - } - - /// Sync - pub fn sync(&self, discard: bool) { - unsafe { xlib::XSync(self.inner, if discard { 1 } else { 0 }) }; - } - - /// Returns the focus window and the current focus state. - pub fn get_input_focus(&self) -> Result<(Window, i32)> { - let mut focus_return: xlib::Window = 0; - let mut revert_to_return = 0; - unsafe { xlib::XGetInputFocus(self.inner, &mut focus_return, &mut revert_to_return) }; - let window = Window { - display: self, - inner: focus_return, - }; - return Ok((window, revert_to_return)); - } - - /// Query extension - pub fn query_extension(&self, name: impl AsRef) -> Result<()> { - let name = ffi::c_char_star_from_string(name)?; - let major_opcode_return = ptr::null_mut(); - let first_event_return = ptr::null_mut(); - let first_error_return = ptr::null_mut(); - let _result = unsafe { - xlib::XQueryExtension( - self.inner, - name, - major_opcode_return, - first_event_return, - first_error_return, - ) - }; - // TODO: check reuslt - - unimplemented!() - } - - /// List extensions - pub fn list_extensions(&self) -> Result { - let nextensions_return = ptr::null_mut(); - let result = unsafe { xlib::XListExtensions(self.inner, nextensions_return) }; - // TODO: check result null - // TODO: check nextensions_return - let nextensions_return = unsafe { *nextensions_return } as isize; - Ok(ListExtensions(&self, result, nextensions_return)) - } + /// List extensions + pub fn list_extensions(&self) -> Result { + let nextensions_return = ptr::null_mut(); + let result = + unsafe { xlib::XListExtensions(self.inner, nextensions_return) }; + // TODO: check result null + // TODO: check nextensions_return + let nextensions_return = unsafe { *nextensions_return } as isize; + Ok(ListExtensions(&self, result, nextensions_return)) + } } impl Drop for Display { - fn drop(&mut self) { - unsafe { xlib::XCloseDisplay(self.inner) }; - } + fn drop(&mut self) { + unsafe { xlib::XCloseDisplay(self.inner) }; + } } impl Drop for Grab { - fn drop(&mut self) { - unsafe { xlib::XUngrabServer(self.0) }; - } + fn drop(&mut self) { + unsafe { xlib::XUngrabServer(self.0) }; + } } pub struct ListExtensions<'a>(&'a Display, *mut *mut c_char, isize); impl<'a> ListExtensions<'a> { - pub fn iter(&self) -> ListExtensionsIter { - ListExtensionsIter(self, 0) - } + pub fn iter(&self) -> ListExtensionsIter { + ListExtensionsIter(self, 0) + } } pub struct ListExtensionsIter<'a>(&'a ListExtensions<'a>, isize); impl<'a> Iterator for ListExtensionsIter<'a> { - type Item = String; - fn next(&mut self) -> Option { - if self.1 >= (self.0).2 { - return None; - } - - // TODO: check for null - let base = unsafe { *(self.0).1.offset(self.1) }; - let s = unsafe { ffi::string_from_c_char_star(base).unwrap() }; - // TODO: don't unwrap here - Some(s) + type Item = String; + fn next(&mut self) -> Option { + if self.1 >= (self.0).2 { + return None; } + + // TODO: check for null + let base = unsafe { *(self.0).1.offset(self.1) }; + let s = unsafe { ffi::string_from_c_char_star(base).unwrap() }; + // TODO: don't unwrap here + Some(s) + } } diff --git a/src/xlib/drawable.rs b/src/xlib/drawable.rs index 60be2cb..1f9e245 100644 --- a/src/xlib/drawable.rs +++ b/src/xlib/drawable.rs @@ -8,23 +8,23 @@ use super::image::Image; /// Anything that's drawable pub trait Drawable: GetDisplay { - /// Get drawable handle - fn as_drawable(&self) -> xlib::Drawable; + /// Get drawable handle + fn as_drawable(&self) -> xlib::Drawable; - /// Capture a snapshot of this drawable, clipped by rect. - fn get_image(&self, rect: Rectangle) -> Result { - let image = unsafe { - xlib::XGetImage( - self.get_display(), - self.as_drawable(), - rect.x as i32, - rect.y as i32, - rect.width, - rect.height, - 0xffffffff, - xlib::ZPixmap, - ) - }; - Ok(Image { inner: image }) - } + /// Capture a snapshot of this drawable, clipped by rect. + fn get_image(&self, rect: Rectangle) -> Result { + let image = unsafe { + xlib::XGetImage( + self.get_display(), + self.as_drawable(), + rect.x as i32, + rect.y as i32, + rect.width, + rect.height, + 0xffffffff, + xlib::ZPixmap, + ) + }; + Ok(Image { inner: image }) + } } diff --git a/src/xlib/event.rs b/src/xlib/event.rs index bed1819..a1b9e88 100644 --- a/src/xlib/event.rs +++ b/src/xlib/event.rs @@ -5,33 +5,33 @@ use crate::errors::{Error, Result}; /// An x11 Event #[derive(Debug)] pub struct Event { - inner: xlib::XEvent, - kind: EventKind, + inner: xlib::XEvent, + kind: EventKind, } /// Type of event #[derive(Debug)] pub enum EventKind { - KeyPress(KeyEvent), - KeyRelease(KeyEvent), + KeyPress(KeyEvent), + KeyRelease(KeyEvent), } impl Event { - /// Returns the EventKind of this event - pub fn kind(&self) -> &EventKind { - &self.kind - } + /// Returns the EventKind of this event + pub fn kind(&self) -> &EventKind { + &self.kind + } - pub(super) unsafe fn from_raw(event: xlib::XEvent) -> Result { - let inner = event; - debug!("event type: {:?}", event.type_); - let kind = match event.type_ { - xlib::KeyPress => EventKind::KeyPress(KeyEvent(event.key)), - xlib::KeyRelease => EventKind::KeyRelease(KeyEvent(event.key)), - other => return Err(Error::InvalidEventType(other)), - }; - Ok(Event { inner, kind }) - } + pub(super) unsafe fn from_raw(event: xlib::XEvent) -> Result { + let inner = event; + debug!("event type: {:?}", event.type_); + let kind = match event.type_ { + xlib::KeyPress => EventKind::KeyPress(KeyEvent(event.key)), + xlib::KeyRelease => EventKind::KeyRelease(KeyEvent(event.key)), + other => return Err(Error::InvalidEventType(other)), + }; + Ok(Event { inner, kind }) + } } #[derive(Debug)] diff --git a/src/xlib/image.rs b/src/xlib/image.rs index b686d15..144b4d8 100644 --- a/src/xlib/image.rs +++ b/src/xlib/image.rs @@ -4,10 +4,11 @@ use crate::errors::{Error, Result}; /// A handle to an XImage /// -/// Xlib provides some structures to perform operations on images. However, because there are -/// different in-memory representations, working with images is actually totally fucked. If you -/// want to maintain your sanity, do NOT pry into the raw data buffer of an Image. Instead, index -/// into the image using `PixBuffer::get_pixel` which already performs the conversion and returns a +/// Xlib provides some structures to perform operations on images. However, +/// because there are different in-memory representations, working with images +/// is actually totally fucked. If you want to maintain your sanity, do NOT pry +/// into the raw data buffer of an Image. Instead, index into the image using +/// `PixBuffer::get_pixel` which already performs the conversion and returns a /// tuple of RGB values. /// /// Peeking into the raw data buffer of an Image @@ -15,118 +16,119 @@ use crate::errors::{Error, Result}; /// /// Images consist of lines of longs in row-major form. pub struct Image { - pub inner: *mut xlib::XImage, + pub inner: *mut xlib::XImage, } /// Image byte order pub enum ImageByteOrder { - /// Least significant byte first - LSBFirst, - /// Most significant byte first - MSBFirst, + /// Least significant byte first + LSBFirst, + /// Most significant byte first + MSBFirst, } 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 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 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 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 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 { - let byte_order = unsafe { (*self.inner).byte_order }; - match byte_order { - xlib::LSBFirst => Ok(ImageByteOrder::LSBFirst), - xlib::MSBFirst => Ok(ImageByteOrder::MSBFirst), - order => Err(Error::InvalidByteOrder(order)), - } + /// Get byte order (LSB or MSB) + #[inline] + pub fn get_byte_order(&self) -> Result { + let byte_order = unsafe { (*self.inner).byte_order }; + match byte_order { + xlib::LSBFirst => Ok(ImageByteOrder::LSBFirst), + xlib::MSBFirst => Ok(ImageByteOrder::MSBFirst), + order => Err(Error::InvalidByteOrder(order)), } + } - fn get_rgb_masks(&self) -> (u64, u64, u64) { - let red_mask = unsafe { (*self.inner).red_mask }; - let green_mask = unsafe { (*self.inner).green_mask }; - let blue_mask = unsafe { (*self.inner).blue_mask }; - (red_mask, blue_mask, green_mask) - } + fn get_rgb_masks(&self) -> (u64, u64, u64) { + let red_mask = unsafe { (*self.inner).red_mask }; + let green_mask = unsafe { (*self.inner).green_mask }; + let blue_mask = unsafe { (*self.inner).blue_mask }; + (red_mask, blue_mask, green_mask) + } - /// Produces a PixBuffer. - pub fn buffer(&self) -> PixBuffer { - let size = self.get_size(); - let buf = unsafe { (*self.inner).data as *mut u8 }; - let masks = self.get_rgb_masks(); - PixBuffer { - buf, - size, - masks, - image: self, - } + /// Produces a PixBuffer. + pub fn buffer(&self) -> PixBuffer { + let size = self.get_size(); + let buf = unsafe { (*self.inner).data as *mut u8 }; + let masks = self.get_rgb_masks(); + PixBuffer { + buf, + size, + masks, + image: self, } + } } impl Drop for Image { - fn drop(&mut self) { - unsafe { xlib::XDestroyImage(self.inner) }; - } + fn drop(&mut self) { + unsafe { xlib::XDestroyImage(self.inner) }; + } } /// The buffer pointed to by an XImage. pub struct PixBuffer<'a> { - /// The raw pointer to the buffer - pub buf: *mut u8, + /// The raw pointer to the buffer + pub buf: *mut u8, - /// The size of the buffer - pub size: usize, + /// The size of the buffer + pub size: usize, - /// Rgb masks - pub masks: (u64, u64, u64), + /// Rgb masks + pub masks: (u64, u64, u64), - pub image: &'a Image, + pub image: &'a Image, } impl<'a> PixBuffer<'a> { - /// Retrieve a direct reference to the internal buffer. - pub fn get_buffer(&self) -> &[u8] { - unsafe { std::slice::from_raw_parts(self.buf, self.size) } - } + /// Retrieve a direct reference to the internal buffer. + pub fn get_buffer(&self) -> &[u8] { + unsafe { std::slice::from_raw_parts(self.buf, self.size) } + } - /// Gets the rgb value of a particular pixel, after performing conversion - /// - /// 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) }; + /// Gets the rgb value of a particular pixel, after performing conversion + /// + /// 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) }; - let red_mask = unsafe { (*self.image.inner).red_mask }; - let green_mask = unsafe { (*self.image.inner).green_mask }; - let blue_mask = unsafe { (*self.image.inner).blue_mask }; + let red_mask = unsafe { (*self.image.inner).red_mask }; + let green_mask = unsafe { (*self.image.inner).green_mask }; + let blue_mask = unsafe { (*self.image.inner).blue_mask }; - let red = ((pixel & red_mask) >> 16) as u8; - let green = ((pixel & green_mask) >> 8) as u8; - let blue = ((pixel & blue_mask) >> 0) as u8; + let red = ((pixel & red_mask) >> 16) as u8; + let green = ((pixel & green_mask) >> 8) as u8; + let blue = ((pixel & blue_mask) >> 0) as u8; - Some((red, green, blue)) - } + Some((red, green, blue)) + } } diff --git a/src/xlib/mod.rs b/src/xlib/mod.rs index 0d97e9f..15ebc04 100644 --- a/src/xlib/mod.rs +++ b/src/xlib/mod.rs @@ -1,8 +1,8 @@ //! The core of x11 mod atom; -mod cursor; mod colormap; +mod cursor; mod display; mod drawable; mod event; @@ -14,58 +14,60 @@ mod window; use x11::xlib; pub use self::atom::Atom; +pub use self::colormap::Colormap; 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::window::{ + EventMask, SetWindowAttributes, Window, WindowAttributes, +}; #[derive(Debug)] pub enum Inherit { - Value(T), - CopyFromParent, + Value(T), + CopyFromParent, } impl Default for Inherit { - fn default() -> Self { - Inherit::CopyFromParent - } + fn default() -> Self { + Inherit::CopyFromParent + } } pub trait IntoInt { - fn into_int(&self) -> u64; + fn into_int(&self) -> u64; } impl IntoInt for Inherit { - fn into_int(&self) -> u64 { - match self { - Inherit::Value(t) => t.into_int(), - Inherit::CopyFromParent => xlib::CopyFromParent as u64, - } + fn into_int(&self) -> u64 { + match self { + Inherit::Value(t) => t.into_int(), + Inherit::CopyFromParent => xlib::CopyFromParent as u64, } + } } #[derive(Debug)] pub enum Noneable { - Value(T), - None, + Value(T), + None, } impl Default for Noneable { - fn default() -> Self { - Noneable::None - } + fn default() -> Self { + Noneable::None + } } impl IntoInt for Noneable { - fn into_int(&self) -> u64 { - match self { - Noneable::Value(t) => t.into_int(), - Noneable::None => 0, - } + fn into_int(&self) -> u64 { + match self { + Noneable::Value(t) => t.into_int(), + Noneable::None => 0, } + } } diff --git a/src/xlib/pixmap.rs b/src/xlib/pixmap.rs index 2f00f2c..efdf8ac 100644 --- a/src/xlib/pixmap.rs +++ b/src/xlib/pixmap.rs @@ -12,19 +12,19 @@ use crate::xlib::{Display, IntoInt}; #[derive(Derivative)] #[derivative(Debug)] pub struct Pixmap<'a> { - #[derivative(Debug = "ignore")] - pub(crate) display: &'a Display, - pub(crate) inner: xlib::Pixmap, + #[derivative(Debug = "ignore")] + pub(crate) display: &'a Display, + pub(crate) inner: xlib::Pixmap, } impl<'a> Drop for Pixmap<'a> { - fn drop(&mut self) { - unsafe { xlib::XFreePixmap(self.display.inner, self.inner) }; - } + fn drop(&mut self) { + unsafe { xlib::XFreePixmap(self.display.inner, self.inner) }; + } } impl<'a> IntoInt for Pixmap<'a> { - fn into_int(&self) -> u64 { - self.inner - } + fn into_int(&self) -> u64 { + self.inner + } } diff --git a/src/xlib/visual.rs b/src/xlib/visual.rs index 78b1ad0..2291723 100644 --- a/src/xlib/visual.rs +++ b/src/xlib/visual.rs @@ -4,32 +4,32 @@ use super::display::Display; /// A wrapper around a Visual pub struct Visual { - pub(super) inner: *mut xlib::Visual, + pub(super) inner: *mut xlib::Visual, } impl Visual { - /// Gets the raw handle to the x11 Visual - pub fn as_raw(&self) -> *mut xlib::Visual { - self.inner - } + /// Gets the raw handle to the x11 Visual + pub fn as_raw(&self) -> *mut xlib::Visual { + self.inner + } - /// Gets the default visual - pub fn default(display: &Display, screen: i32) -> Self { - let inner = unsafe { xlib::XDefaultVisual(display.as_raw(), screen) }; - Visual { inner } - } + /// Gets the default visual + pub fn default(display: &Display, screen: i32) -> Self { + let inner = unsafe { xlib::XDefaultVisual(display.as_raw(), screen) }; + Visual { inner } + } } pub struct VisualInfo { - pub(super) inner: *mut xlib::XVisualInfo, + pub(super) inner: *mut xlib::XVisualInfo, } impl VisualInfo { - pub fn from_raw(inner: *mut xlib::XVisualInfo) -> Self { - VisualInfo { inner } - } + pub fn from_raw(inner: *mut xlib::XVisualInfo) -> Self { + VisualInfo { inner } + } - pub fn as_raw(&self) -> *mut xlib::XVisualInfo { - self.inner - } + pub fn as_raw(&self) -> *mut xlib::XVisualInfo { + self.inner + } } diff --git a/src/xlib/window.rs b/src/xlib/window.rs index 75063d3..047d78b 100644 --- a/src/xlib/window.rs +++ b/src/xlib/window.rs @@ -5,184 +5,196 @@ use x11::xlib; use crate::errors::{Error, Result}; use crate::rect::Rectangle; -use crate::xlib::{Colormap, Atom, Cursor, Display, Drawable, GetDisplay, Image, Inherit, IntoInt, Noneable, Pixmap}; +use crate::xlib::{ + Atom, Colormap, Cursor, Display, Drawable, GetDisplay, Image, Inherit, + IntoInt, Noneable, Pixmap, +}; /// A wrapper around a window handle. #[derive(Clone)] pub struct Window<'a> { - pub display: &'a Display, - pub inner: xlib::Window, + pub display: &'a Display, + pub inner: xlib::Window, } impl<'a> Window<'a> { - /// Create a new window - pub fn create( - display: &'a Display, - parent: Option, - location: Rectangle, - set_attributes: SetWindowAttributes, - ) -> Result> { - let parent = match parent { - Some(parent) => parent, - None => display.get_default_root_window()?, - }; - let visual = display.default_visual(0); - let window = unsafe { - xlib::XCreateWindow( - display.as_raw(), - parent.as_raw(), - location.x as i32, - location.y as i32, - location.width, - location.height, - 0, - 0, - 0, - visual.as_raw(), - 0, - set_attributes.into_raw(), - ) - }; - Ok(Window { - display, - inner: window, - }) - } + /// Create a new window + pub fn create( + display: &'a Display, + parent: Option, + location: Rectangle, + set_attributes: SetWindowAttributes, + ) -> Result> { + let parent = match parent { + Some(parent) => parent, + None => display.get_default_root_window()?, + }; + let visual = display.default_visual(0); + let window = unsafe { + xlib::XCreateWindow( + display.as_raw(), + parent.as_raw(), + location.x as i32, + location.y as i32, + location.width, + location.height, + 0, + 0, + 0, + visual.as_raw(), + 0, + set_attributes.into_raw(), + ) + }; + Ok(Window { + 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, inner: id }) - } + /// Create a new Window instance from an existing ID + pub fn create_from_handle(display: &Display, id: u64) -> Result { + Ok(Window { display, inner: id }) + } - /// Get window attributes. - pub fn get_attributes(&self) -> Result { - let attr = unsafe { - libc::malloc(mem::size_of::()) as *mut xlib::XWindowAttributes - }; - let result = unsafe { xlib::XGetWindowAttributes(self.display.as_raw(), self.inner, attr) }; - match result { - 0 => Err(Error::GetAttributesError), - _ => Ok(WindowAttributes { - display: self.display, - inner: attr, - }), - } + /// Get window attributes. + pub fn get_attributes(&self) -> Result { + let attr = unsafe { + libc::malloc(mem::size_of::()) + as *mut xlib::XWindowAttributes + }; + let result = unsafe { + xlib::XGetWindowAttributes(self.display.as_raw(), self.inner, attr) + }; + match result { + 0 => Err(Error::GetAttributesError), + _ => Ok(WindowAttributes { + display: self.display, + inner: attr, + }), } + } - /// Get the raw window handle - pub fn as_raw(&self) -> xlib::Window { - self.inner - } + /// Get the raw window handle + pub fn as_raw(&self) -> xlib::Window { + self.inner + } - /// Gets the image from this window using XGetImage. - pub fn get_image(&self) -> Result { - let attr = self.get_attributes()?; - Drawable::get_image( - self, - Rectangle::new( - attr.get_x(), - attr.get_y(), - attr.get_width(), - attr.get_height(), - ), - ) - } + /// Gets the image from this window using XGetImage. + pub fn get_image(&self) -> Result { + let attr = self.get_attributes()?; + Drawable::get_image( + self, + Rectangle::new( + attr.get_x(), + attr.get_y(), + attr.get_width(), + attr.get_height(), + ), + ) + } - /// Change window property - // TODO: make it more general - pub fn change_property(&self, key: &Atom, val: &Atom) { - use std::mem::transmute; - let v = val.as_raw(); - unsafe { - xlib::XChangeProperty( - self.display.as_raw(), - self.inner, - key.as_raw(), - xlib::XA_ATOM, - 32, - xlib::PropModeReplace, - transmute(&v), - 1, - ); - } + /// Change window property + // TODO: make it more general + pub fn change_property(&self, key: &Atom, val: &Atom) { + use std::mem::transmute; + let v = val.as_raw(); + unsafe { + xlib::XChangeProperty( + self.display.as_raw(), + self.inner, + key.as_raw(), + xlib::XA_ATOM, + 32, + xlib::PropModeReplace, + transmute(&v), + 1, + ); } + } - /// "Maps", or shows a window to a display. - pub fn map(&self) { - unsafe { xlib::XMapWindow(self.display.as_raw(), self.inner) }; - } + /// "Maps", or shows a window to a display. + pub fn map(&self) { + unsafe { xlib::XMapWindow(self.display.as_raw(), self.inner) }; + } - /// Requests for events from the server matching a particular event mask. - /// - /// 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.as_raw(), self.inner, event_mask.bits as i64) }; - } + /// Requests for events from the server matching a particular event mask. + /// + /// 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.as_raw(), + self.inner, + event_mask.bits() as i64, + ) + }; + } } impl<'a> GetDisplay for Window<'a> { - fn get_display(&self) -> *mut xlib::Display { - self.display.as_raw() - } + fn get_display(&self) -> *mut xlib::Display { + self.display.as_raw() + } } impl<'a> Drawable for Window<'a> { - fn as_drawable(&self) -> xlib::Drawable { - self.inner - } + fn as_drawable(&self) -> xlib::Drawable { + self.inner + } } impl<'a> Drop for Window<'a> { - fn drop(&mut self) { - unsafe { xlib::XDestroyWindow(self.display.as_raw(), self.inner) }; - } + fn drop(&mut self) { + unsafe { xlib::XDestroyWindow(self.display.as_raw(), self.inner) }; + } } /// Window Attributes pub struct WindowAttributes<'a> { - pub(super) display: &'a Display, - pub(self) inner: *mut xlib::XWindowAttributes, + pub(super) display: &'a Display, + pub(self) inner: *mut xlib::XWindowAttributes, } impl<'a> WindowAttributes<'a> { - /// Gets the width of the window - pub fn get_x(&self) -> i32 { - unsafe { (*self.inner).x as i32 } - } + /// Gets the width of the window + pub fn get_x(&self) -> i32 { + unsafe { (*self.inner).x as i32 } + } - /// Gets the height of the window - pub fn get_y(&self) -> i32 { - unsafe { (*self.inner).y as i32 } - } + /// Gets the height of the window + pub fn get_y(&self) -> i32 { + unsafe { (*self.inner).y as i32 } + } - /// Gets the width of the window - pub fn get_width(&self) -> u32 { - unsafe { (*self.inner).width as u32 } - } + /// Gets the width of the window + pub fn get_width(&self) -> u32 { + unsafe { (*self.inner).width as u32 } + } - /// Gets the height of the window - pub fn get_height(&self) -> u32 { - unsafe { (*self.inner).height as u32 } - } + /// Gets the height of the window + pub fn get_height(&self) -> u32 { + unsafe { (*self.inner).height as u32 } + } - /// Get the root window of this window - pub fn get_root(&self) -> Window { - Window { - display: self.display, - inner: unsafe { (*self.inner).root }, - } + /// Get the root window of this window + pub fn get_root(&self) -> Window { + Window { + display: self.display, + inner: unsafe { (*self.inner).root }, } + } } impl<'a> Drop for WindowAttributes<'a> { - fn drop(&mut self) { - unsafe { libc::free(self.inner as *mut libc::c_void) }; - } + fn drop(&mut self) { + unsafe { libc::free(self.inner as *mut libc::c_void) }; + } } bitflags! { - #[derive(Default)] + #[derive(Default, Debug)] pub struct EventMask: c_ulong { const NO_EVENT_MASK = 0; const KEY_PRESS_MASK = (1<<0); @@ -215,111 +227,111 @@ bitflags! { #[derive(Debug)] pub struct SetWindowAttributes<'a> { - pub background_pixmap: BackgroundPixmap<'a>, - pub background_pixel: c_ulong, - pub border_pixmap: Inherit>, - 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>, - pub cursor: Noneable>, + pub background_pixmap: BackgroundPixmap<'a>, + pub background_pixel: c_ulong, + pub border_pixmap: Inherit>, + 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>, + pub cursor: Noneable>, } 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(), - } + 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: self.background_pixmap.into_int(), - background_pixel: self.background_pixel, - 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: self.colormap.into_int(), - cursor: self.cursor.into_int(), - }; + pub fn into_raw(self) -> *mut xlib::XSetWindowAttributes { + let result = xlib::XSetWindowAttributes { + background_pixmap: self.background_pixmap.into_int(), + background_pixel: self.background_pixel, + 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: self.colormap.into_int(), + 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, + Background(Pixmap<'a>), + None, + ParentRelative, } impl<'a> Default for BackgroundPixmap<'a> { - fn default() -> Self { - BackgroundPixmap::None - } + 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, - } + 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, + NotUseful, + WhenMapped, + Always, } impl Default for BackingStore { - fn default() -> Self { - BackingStore::NotUseful - } + 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, - } + fn into_raw(self) -> i32 { + match self { + BackingStore::NotUseful => xlib::NotUseful, + BackingStore::WhenMapped => xlib::WhenMapped, + BackingStore::Always => xlib::Always, } + } } diff --git a/src/xrender/picture.rs b/src/xrender/picture.rs index 8a2023e..8ec365e 100644 --- a/src/xrender/picture.rs +++ b/src/xrender/picture.rs @@ -3,5 +3,5 @@ pub struct Picture {} impl Picture {} impl Drop for Picture { - fn drop(&mut self) {} + fn drop(&mut self) {} }