leanshot/src/gui.rs

82 lines
2.5 KiB
Rust
Raw Normal View History

use imlib2::{self, Image as Image2};
2018-09-11 21:58:16 +00:00
use xlib::{Display, EventKind, Visual, Window};
2018-09-10 06:52:54 +00:00
use errors::ScreenshotError;
2018-09-11 21:58:16 +00:00
use Options;
2018-09-10 06:52:54 +00:00
use Rectangle;
2018-09-11 21:58:16 +00:00
use Region;
2018-09-11 22:25:50 +00:00
use SelectWindow;
2018-09-10 06:52:54 +00:00
pub struct GUI {
2018-09-11 01:31:25 +00:00
pub(crate) display: Display,
2018-09-10 06:52:54 +00:00
}
impl GUI {
2018-09-10 08:15:42 +00:00
pub fn new() -> Result<Self, ScreenshotError> {
2018-09-11 01:31:25 +00:00
let display = Display::connect(":0")?;
2018-09-10 08:15:42 +00:00
Ok(GUI { display })
2018-09-10 06:52:54 +00:00
}
2018-09-11 21:58:16 +00:00
/// Captures the window and produces an Image.
pub fn capture_window(&self, opt: &Options, window: Window) -> Result<Image2, ScreenshotError> {
2018-09-11 02:23:11 +00:00
let attr = window.get_attributes()?;
2018-09-11 21:58:16 +00:00
let mut width = attr.get_width();
let mut height = attr.get_height();
2018-09-11 02:23:11 +00:00
let root = self.display.get_default_root_window()?;
2018-09-11 21:58:16 +00:00
let (mut x, mut y, _) = self.display.translate_coordinates(window, 0, 0, root)?;
2018-09-11 21:58:16 +00:00
imlib2::context_set_display(&self.display);
let visual = Visual::default(&self.display, 0);
2018-09-11 21:58:16 +00:00
imlib2::context_set_visual(&visual);
2018-09-11 21:58:16 +00:00
match opt.region {
Region::Selection => {
let region = self.interactive_select()?;
x = region.x;
y = region.y;
width = region.width;
height = region.height;
2018-09-11 22:25:50 +00:00
}
_ => (),
2018-09-11 21:58:16 +00:00
}
Image2::create_from_drawable(window, 0, x, y, width as i32, height as i32, true)
.map_err(|err| err.into())
2018-09-10 06:52:54 +00:00
}
/// Get the active window.
2018-09-11 01:31:25 +00:00
pub fn get_active_window(&self) -> Result<Window, ScreenshotError> {
2018-09-11 01:44:07 +00:00
self.display
.get_input_focus()
.map(|(window, _)| window)
.map_err(|err| err.into())
2018-09-10 06:52:54 +00:00
}
/// Brings up an interactive selection GUI.
2018-09-11 21:58:16 +00:00
pub fn interactive_select(&self) -> Result<Rectangle, ScreenshotError> {
let window = SelectWindow::new(&self.display);
2018-09-11 21:58:16 +00:00
let root = self.display.get_default_root_window()?;
let root_im = root.get_image();
let mut done = 0;
2018-09-11 22:25:50 +00:00
let mut button_press = false;
2018-09-11 21:58:16 +00:00
while done == 0 && self.display.pending()? > 0 {
let ev = self.display.next_event()?;
match ev.kind() {
2018-09-11 22:25:50 +00:00
EventKind::ButtonPress => {
button_press = true;
}
EventKind::ButtonRelease => {
if button_press {
done = 1;
}
button_press = false;
}
2018-09-11 22:05:25 +00:00
_ => (),
2018-09-11 21:58:16 +00:00
}
}
2018-09-10 06:52:54 +00:00
Err(ScreenshotError::Error)
}
}