From 69e226dcf3b6e9fcc8b52578dd00bca04202b8be Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 28 Jul 2021 16:05:13 -0500 Subject: [PATCH] add x11 stuff --- Cargo.lock | 1 + Cargo.toml | 12 ++++++++++-- src/gui_x11.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/gui_xcb.rs | 8 ++------ src/main.rs | 26 ++++++++++++++++++++++++-- src/rect.rs | 9 ++++++++- 6 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 src/gui_x11.rs diff --git a/Cargo.lock b/Cargo.lock index 82c33a3..d163be9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,6 +185,7 @@ name = "leanshot" version = "0.5.0" dependencies = [ "anyhow", + "cfg-if", "image", "leanshot-x11", "libc", diff --git a/Cargo.toml b/Cargo.toml index 981a256..19ac64f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,13 +10,21 @@ authors = ["Michael Zhang "] [workspace] members = ["x11"] +[features] +default = ["backend-x11", "backend-x11-glx"] +backend-x11 = [] +backend-x11-glx = ["backend-x11"] +backend-xcb = ["xcb-util", "xcb"] + [dependencies] anyhow = "1.0.38" image = { version = "0.23.13", default-features = false, features = ["jpeg", "png"] } leanshot-x11 = { path = "x11" } log = "0.4.14" stderrlog = "0.5.1" -xcb-util = { version = "0.3.0", features = ["image", "cursor"] } -xcb = "0.9.0" structopt = "0.3.21" libc = "0.2.86" + +xcb-util = { version = "0.3.0", features = ["image", "cursor"], optional = true } +xcb = { version = "0.9.0", optional = true } +cfg-if = "1.0.0" diff --git a/src/gui_x11.rs b/src/gui_x11.rs new file mode 100644 index 0000000..399adda --- /dev/null +++ b/src/gui_x11.rs @@ -0,0 +1,47 @@ +use std::path::Path; + +use anyhow::Result; +use x11::xlib::Display; + +use crate::gui_trait::{Capture, Gui}; +use crate::rect::Rectangle; + +pub struct X11Gui { + conn: Display, +} + +impl X11Gui { + pub fn new() -> Result { + let disp = Display::connect(None)?; + Ok(X11Gui { conn: disp }) + } +} + +impl Gui for X11Gui { + type Capture = ScreenCapture; + fn capture_entire_screen(&self) -> Result<::Capture, anyhow::Error> { + todo!() + } + fn interactive_select( + &self, + _: &::Capture, + ) -> Result, anyhow::Error> { + todo!() + } +} + +pub struct ScreenCapture {} + +impl Capture for ScreenCapture { + fn save_to(&self, _: impl AsRef) -> Result<(), anyhow::Error> { + todo!() + } + + fn save_cropped_to( + &self, + _: impl AsRef, + _: Option, + ) -> Result<(), anyhow::Error> { + todo!() + } +} diff --git a/src/gui_xcb.rs b/src/gui_xcb.rs index 0385a7b..fc0c69a 100644 --- a/src/gui_xcb.rs +++ b/src/gui_xcb.rs @@ -205,12 +205,8 @@ impl Gui for XcbGui { ); xproto::poly_rectangle(&self.conn, window_id, window_gc, &[rect.into()]); - let rect2 = Rectangle::new( - rect.x + 1, - rect.y + 1, - rect.width - 2, - rect.height - 2, - ); + let rect2 = + Rectangle::new(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); xproto::change_gc( &self.conn, window_gc, diff --git a/src/main.rs b/src/main.rs index 365794f..43a7431 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,17 @@ extern crate anyhow; extern crate leanshot_x11 as x11; +#[cfg(all(feature = "backend-x11", feature = "backend-xcb"))] +compile_error!("don't enable both x11 and xcb backends"); + mod gui_trait; + +#[cfg(feature = "backend-xcb")] mod gui_xcb; + +#[cfg(feature = "backend-x11")] +mod gui_x11; + mod rect; mod singleton; @@ -18,7 +27,6 @@ use anyhow::Result; use structopt::StructOpt; use crate::gui_trait::{Capture, Gui}; -use crate::gui_xcb::XcbGui; fn main() -> Result<()> { let opt = Options::from_args(); @@ -29,7 +37,21 @@ fn main() -> Result<()> { .init() .unwrap(); - let gui = XcbGui::new()?; + let gui = get_gui()?; + run(&opt, gui) +} + +#[cfg(feature = "backend-xcb")] +fn get_gui() -> Result { + crate::gui_xcb::XcbGui::new() +} + +#[cfg(feature = "backend-x11")] +fn get_gui() -> Result { + crate::gui_x11::X11Gui::new() +} + +fn run(opt: &Options, gui: impl Gui) -> Result<()> { let capture = gui.capture_entire_screen()?; match opt.region { diff --git a/src/rect.rs b/src/rect.rs index 8dfd306..c479cad 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -8,10 +8,16 @@ pub struct Rectangle { impl Rectangle { pub fn new(x: T, y: T, width: U, height: U) -> Self { - Rectangle { x, y, width, height } + Rectangle { + x, + y, + width, + height, + } } } +#[cfg(feature = "backend-xcb")] impl From for Rectangle { fn from(rect: xcb::xproto::Rectangle) -> Self { Rectangle { @@ -23,6 +29,7 @@ impl From for Rectangle { } } +#[cfg(feature = "backend-xcb")] impl Into for Rectangle { fn into(self) -> xcb::xproto::Rectangle { xcb::xproto::Rectangle::new(self.x, self.y, self.width, self.height)