forked from michael/leanshot
move visual to xlib, adding framework for interactive select
This commit is contained in:
parent
9b7121c8bd
commit
92d476df05
11 changed files with 125 additions and 70 deletions
|
@ -9,12 +9,10 @@ extern crate x11;
|
||||||
|
|
||||||
mod errors;
|
mod errors;
|
||||||
mod image;
|
mod image;
|
||||||
mod visual;
|
|
||||||
|
|
||||||
pub use errors::Error;
|
pub use errors::Error;
|
||||||
pub use image::Image;
|
pub use image::Image;
|
||||||
pub use imlib2_sys::{Drawable, Pixmap};
|
pub use imlib2_sys::{Drawable, Pixmap};
|
||||||
pub use visual::Visual;
|
|
||||||
|
|
||||||
/// Set the display for the imlib context.
|
/// Set the display for the imlib context.
|
||||||
pub fn context_set_display(display: *mut x11::xlib::Display) {
|
pub fn context_set_display(display: *mut x11::xlib::Display) {
|
||||||
|
@ -22,6 +20,6 @@ pub fn context_set_display(display: *mut x11::xlib::Display) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the visual for the imlib context.
|
/// Set the visual for the imlib context.
|
||||||
pub fn context_set_visual(visual: Visual) {
|
pub fn context_set_visual(visual: *mut x11::xlib::Visual) {
|
||||||
unsafe { imlib2_sys::imlib_context_set_visual(visual.inner) };
|
unsafe { imlib2_sys::imlib_context_set_visual(visual as *mut imlib2_sys::Visual) };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
use imlib2_sys as im;
|
|
||||||
use x11;
|
|
||||||
|
|
||||||
/// Visual
|
|
||||||
pub struct Visual {
|
|
||||||
pub(crate) inner: *mut im::Visual,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Visual {
|
|
||||||
/// get the default visual for a display
|
|
||||||
pub fn default(display: *mut x11::xlib::_XDisplay, screen: i32) -> Self {
|
|
||||||
let inner = unsafe { im::XDefaultVisual(display as *mut im::_XDisplay, screen) };
|
|
||||||
Visual { inner }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,42 +6,13 @@ use options::{Options, Region};
|
||||||
pub fn capture(opt: &Options) -> Result<(), ScreenshotError> {
|
pub fn capture(opt: &Options) -> Result<(), ScreenshotError> {
|
||||||
let gui = GUI::new()?;
|
let gui = GUI::new()?;
|
||||||
|
|
||||||
// let window_to_capture = match opt.region {
|
|
||||||
// Region::Fullscreen | Region::Selection => gui.display.get_default_root_window()?,
|
|
||||||
// Region::ActiveWindow => gui.get_active_window()?,
|
|
||||||
// };
|
|
||||||
let window_to_capture = match opt.region {
|
let window_to_capture = match opt.region {
|
||||||
Region::ActiveWindow => gui.get_active_window()?,
|
Region::ActiveWindow => gui.get_active_window()?,
|
||||||
_ => gui.display.get_default_root_window()?,
|
_ => gui.display.get_default_root_window()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
// let _clip = match opt.region {
|
|
||||||
// Region::ActiveWindow => {
|
|
||||||
// let win = gui.get_active_window()?;
|
|
||||||
// let attr = win.get_attributes()?;
|
|
||||||
// let width = attr.get_width();
|
|
||||||
// let height = attr.get_height();
|
|
||||||
// let root = gui.display.get_default_root_window()?;
|
|
||||||
// let (x, y, _) = gui.display.translate_coordinates(win, 0, 0, root)?;
|
|
||||||
// Some(Rectangle::new(x as u32, y as u32, width, height))
|
|
||||||
// }
|
|
||||||
// _ => None,
|
|
||||||
// };
|
|
||||||
|
|
||||||
let capture = gui.capture_window(window_to_capture)?;
|
let capture = gui.capture_window(window_to_capture)?;
|
||||||
|
|
||||||
// capture.write_png(&opt.outfile, clip)?;
|
|
||||||
capture.save_image(&opt.outfile)?;
|
capture.save_image(&opt.outfile)?;
|
||||||
|
|
||||||
// let final_capture = match opt.region {
|
|
||||||
// Region::Fullscreen | Region::ActiveWindow => window_capture,
|
|
||||||
// Region::Selection => gui.interactive_select(&window_capture),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if let Region::Selection = opt.region {
|
|
||||||
// let region = gui.interactive_select(&capture)?;
|
|
||||||
// capture.apply_region(®ion);
|
|
||||||
// };
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
11
src/gui.rs
11
src/gui.rs
|
@ -1,8 +1,9 @@
|
||||||
use imlib2::{self, Image as Image2, Visual};
|
use imlib2::{self, Image as Image2};
|
||||||
use xlib::{Display, Image, Window};
|
use xlib::{Display, Image, Window, Visual};
|
||||||
|
|
||||||
use errors::ScreenshotError;
|
use errors::ScreenshotError;
|
||||||
use Rectangle;
|
use Rectangle;
|
||||||
|
use SelectWindow;
|
||||||
|
|
||||||
pub struct GUI {
|
pub struct GUI {
|
||||||
pub(crate) display: Display,
|
pub(crate) display: Display,
|
||||||
|
@ -21,8 +22,11 @@ impl GUI {
|
||||||
let height = attr.get_height() as i32;
|
let height = attr.get_height() as i32;
|
||||||
let root = self.display.get_default_root_window()?;
|
let root = self.display.get_default_root_window()?;
|
||||||
let (x, y, _) = self.display.translate_coordinates(window, 0, 0, root)?;
|
let (x, y, _) = self.display.translate_coordinates(window, 0, 0, root)?;
|
||||||
|
|
||||||
imlib2::context_set_display(self.display.as_raw());
|
imlib2::context_set_display(self.display.as_raw());
|
||||||
imlib2::context_set_visual(Visual::default(self.display.as_raw(), 0));
|
let visual = Visual::default(&self.display, 0);
|
||||||
|
imlib2::context_set_visual(visual.as_raw());
|
||||||
|
|
||||||
Image2::create_from_drawable(window, 0, x, y, width, height, true).map_err(|err| err.into())
|
Image2::create_from_drawable(window, 0, x, y, width, height, true).map_err(|err| err.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +41,7 @@ impl GUI {
|
||||||
/// Brings up an interactive selection GUI.
|
/// Brings up an interactive selection GUI.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn interactive_select(&self, _capture: &Image) -> Result<Rectangle, ScreenshotError> {
|
pub fn interactive_select(&self, _capture: &Image) -> Result<Rectangle, ScreenshotError> {
|
||||||
|
let window = SelectWindow::new(&self.display);
|
||||||
Err(ScreenshotError::Error)
|
Err(ScreenshotError::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -11,27 +11,11 @@ mod capture;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod gui;
|
mod gui;
|
||||||
mod options;
|
mod options;
|
||||||
|
mod window;
|
||||||
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
use xlib::Rectangle;
|
||||||
|
|
||||||
pub use capture::capture;
|
pub use capture::capture;
|
||||||
pub use options::Options;
|
pub use options::Options;
|
||||||
|
pub use window::SelectWindow;
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Rectangle {
|
|
||||||
pub x: u32,
|
|
||||||
pub y: u32,
|
|
||||||
pub width: u32,
|
|
||||||
pub height: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rectangle {
|
|
||||||
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
|
|
||||||
Rectangle {
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
15
src/window.rs
Normal file
15
src/window.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use xlib::{Display, Window, Rectangle};
|
||||||
|
|
||||||
|
use errors::ScreenshotError;
|
||||||
|
|
||||||
|
pub struct SelectWindow {
|
||||||
|
inner: Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SelectWindow {
|
||||||
|
pub fn new(display: &Display) -> Result<Self, ScreenshotError> {
|
||||||
|
// TODO: unhardcode
|
||||||
|
let window = Window::create(display, None, Rectangle::new(0, 0, 1920, 1080))?;
|
||||||
|
Ok(SelectWindow { inner: window })
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ use std::ffi::CString;
|
||||||
|
|
||||||
use x11::xlib as x;
|
use x11::xlib as x;
|
||||||
|
|
||||||
|
use Visual;
|
||||||
use Window;
|
use Window;
|
||||||
use X11Error;
|
use X11Error;
|
||||||
|
|
||||||
|
@ -29,6 +30,12 @@ impl Display {
|
||||||
self.inner
|
self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the default visual
|
||||||
|
pub fn default_visual(&self, screen: i32) -> Visual {
|
||||||
|
let visual = unsafe { x::XDefaultVisual(self.inner, screen) };
|
||||||
|
Visual { inner: visual }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the root window for the given screen.
|
/// Returns the root window for the given screen.
|
||||||
pub fn get_root_window(&self, screen: i32) -> Result<Window, X11Error> {
|
pub fn get_root_window(&self, screen: i32) -> Result<Window, X11Error> {
|
||||||
let inner = unsafe { x::XRootWindow(self.inner, screen) };
|
let inner = unsafe { x::XRootWindow(self.inner, screen) };
|
||||||
|
|
|
@ -13,9 +13,14 @@ extern crate x11;
|
||||||
mod display;
|
mod display;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod image;
|
mod image;
|
||||||
|
mod visual;
|
||||||
|
mod rect;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
pub use display::Display;
|
pub use display::Display;
|
||||||
pub use errors::X11Error;
|
pub use errors::X11Error;
|
||||||
pub use image::{Image, ImageByteOrder, PixBuffer};
|
pub use image::{Image, ImageByteOrder, PixBuffer};
|
||||||
|
pub use visual::Visual;
|
||||||
|
pub use rect::Rectangle;
|
||||||
pub use window::{Window, WindowAttributes};
|
pub use window::{Window, WindowAttributes};
|
||||||
|
|
||||||
|
|
24
xlib/src/rect.rs
Normal file
24
xlib/src/rect.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/// A rectangle.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Rectangle {
|
||||||
|
/// x
|
||||||
|
pub x: u32,
|
||||||
|
/// y
|
||||||
|
pub y: u32,
|
||||||
|
/// width
|
||||||
|
pub width: u32,
|
||||||
|
/// height
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rectangle {
|
||||||
|
/// Create a new Rectangle from u32s
|
||||||
|
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
|
||||||
|
Rectangle {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
xlib/src/visual.rs
Normal file
21
xlib/src/visual.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use x11::xlib as x;
|
||||||
|
|
||||||
|
use Display;
|
||||||
|
|
||||||
|
/// A wrapper around a Visual
|
||||||
|
pub struct Visual {
|
||||||
|
pub(super) inner: *mut x::Visual,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visual {
|
||||||
|
/// Gets the raw handle to the x11 Visual
|
||||||
|
pub fn as_raw(&self) -> *mut x::Visual {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the default visual
|
||||||
|
pub fn default(display: &Display, screen: i32) -> Self {
|
||||||
|
let inner = unsafe { x::XDefaultVisual(display.as_raw(), screen) };
|
||||||
|
Visual { inner }
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,9 @@ use imlib2::Drawable;
|
||||||
use libc;
|
use libc;
|
||||||
use x11::xlib as x;
|
use x11::xlib as x;
|
||||||
|
|
||||||
|
use Display;
|
||||||
use Image;
|
use Image;
|
||||||
|
use Rectangle;
|
||||||
use X11Error;
|
use X11Error;
|
||||||
|
|
||||||
/// A wrapper around a window handle.
|
/// A wrapper around a window handle.
|
||||||
|
@ -20,6 +22,39 @@ pub struct WindowAttributes {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
/// Create a new window
|
||||||
|
pub fn create(
|
||||||
|
display: &Display,
|
||||||
|
parent: Option<Window>,
|
||||||
|
location: Rectangle,
|
||||||
|
) -> Result<Window, X11Error> {
|
||||||
|
let parent = match parent {
|
||||||
|
Some(parent) => parent,
|
||||||
|
None => display.get_default_root_window()?,
|
||||||
|
};
|
||||||
|
let visual = display.default_visual(0);
|
||||||
|
let window = unsafe {
|
||||||
|
x::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,
|
||||||
|
0 as *mut x::XSetWindowAttributes,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
Ok(Window {
|
||||||
|
display: display.as_raw(),
|
||||||
|
inner: window,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Get window attributes.
|
/// Get window attributes.
|
||||||
pub fn get_attributes(&self) -> Result<WindowAttributes, X11Error> {
|
pub fn get_attributes(&self) -> Result<WindowAttributes, X11Error> {
|
||||||
let attr = unsafe {
|
let attr = unsafe {
|
||||||
|
@ -49,6 +84,11 @@ impl Window {
|
||||||
};
|
};
|
||||||
Ok(Image { inner: image })
|
Ok(Image { inner: image })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the raw window handle
|
||||||
|
pub fn as_raw(&self) -> x::Window {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<Drawable> for Window {
|
impl AsRef<Drawable> for Window {
|
||||||
|
|
Loading…
Reference in a new issue