move visual to xlib, adding framework for interactive select

This commit is contained in:
Michael Zhang 2018-09-11 14:08:15 -05:00
parent 9b7121c8bd
commit 92d476df05
No known key found for this signature in database
GPG key ID: A1B65B603268116B
11 changed files with 125 additions and 70 deletions

View file

@ -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) };
}

View file

@ -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 }
}
}

View file

@ -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(&region);
// };
Ok(())
}

View file

@ -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)
}
}

View file

@ -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
View 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 })
}
}

View file

@ -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) };

View file

@ -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
View 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
View 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 }
}
}

View file

@ -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 {