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 image;
|
||||
mod visual;
|
||||
|
||||
pub use errors::Error;
|
||||
pub use image::Image;
|
||||
pub use imlib2_sys::{Drawable, Pixmap};
|
||||
pub use visual::Visual;
|
||||
|
||||
/// Set the display for the imlib context.
|
||||
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.
|
||||
pub fn context_set_visual(visual: Visual) {
|
||||
unsafe { imlib2_sys::imlib_context_set_visual(visual.inner) };
|
||||
pub fn context_set_visual(visual: *mut x11::xlib::Visual) {
|
||||
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> {
|
||||
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 {
|
||||
Region::ActiveWindow => gui.get_active_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)?;
|
||||
|
||||
// capture.write_png(&opt.outfile, clip)?;
|
||||
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(())
|
||||
}
|
||||
|
|
11
src/gui.rs
11
src/gui.rs
|
@ -1,8 +1,9 @@
|
|||
use imlib2::{self, Image as Image2, Visual};
|
||||
use xlib::{Display, Image, Window};
|
||||
use imlib2::{self, Image as Image2};
|
||||
use xlib::{Display, Image, Window, Visual};
|
||||
|
||||
use errors::ScreenshotError;
|
||||
use Rectangle;
|
||||
use SelectWindow;
|
||||
|
||||
pub struct GUI {
|
||||
pub(crate) display: Display,
|
||||
|
@ -21,8 +22,11 @@ impl GUI {
|
|||
let height = attr.get_height() as i32;
|
||||
let root = self.display.get_default_root_window()?;
|
||||
let (x, y, _) = self.display.translate_coordinates(window, 0, 0, root)?;
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
|
@ -37,6 +41,7 @@ impl GUI {
|
|||
/// Brings up an interactive selection GUI.
|
||||
#[allow(dead_code)]
|
||||
pub fn interactive_select(&self, _capture: &Image) -> Result<Rectangle, ScreenshotError> {
|
||||
let window = SelectWindow::new(&self.display);
|
||||
Err(ScreenshotError::Error)
|
||||
}
|
||||
}
|
||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -11,27 +11,11 @@ mod capture;
|
|||
mod errors;
|
||||
mod gui;
|
||||
mod options;
|
||||
mod window;
|
||||
|
||||
use structopt::StructOpt;
|
||||
use xlib::Rectangle;
|
||||
|
||||
pub use capture::capture;
|
||||
pub use options::Options;
|
||||
|
||||
#[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,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use window::SelectWindow;
|
||||
|
|
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 Visual;
|
||||
use Window;
|
||||
use X11Error;
|
||||
|
||||
|
@ -29,6 +30,12 @@ impl Display {
|
|||
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.
|
||||
pub fn get_root_window(&self, screen: i32) -> Result<Window, X11Error> {
|
||||
let inner = unsafe { x::XRootWindow(self.inner, screen) };
|
||||
|
|
|
@ -13,9 +13,14 @@ extern crate x11;
|
|||
mod display;
|
||||
mod errors;
|
||||
mod image;
|
||||
mod visual;
|
||||
mod rect;
|
||||
mod window;
|
||||
|
||||
pub use display::Display;
|
||||
pub use errors::X11Error;
|
||||
pub use image::{Image, ImageByteOrder, PixBuffer};
|
||||
pub use visual::Visual;
|
||||
pub use rect::Rectangle;
|
||||
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 x11::xlib as x;
|
||||
|
||||
use Display;
|
||||
use Image;
|
||||
use Rectangle;
|
||||
use X11Error;
|
||||
|
||||
/// A wrapper around a window handle.
|
||||
|
@ -20,6 +22,39 @@ pub struct WindowAttributes {
|
|||
}
|
||||
|
||||
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.
|
||||
pub fn get_attributes(&self) -> Result<WindowAttributes, X11Error> {
|
||||
let attr = unsafe {
|
||||
|
@ -49,6 +84,11 @@ impl Window {
|
|||
};
|
||||
Ok(Image { inner: image })
|
||||
}
|
||||
|
||||
/// Get the raw window handle
|
||||
pub fn as_raw(&self) -> x::Window {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Drawable> for Window {
|
||||
|
|
Loading…
Reference in a new issue