forked from michael/leanshot
move shit around
This commit is contained in:
parent
92d476df05
commit
dc9d6d3dc3
28 changed files with 252 additions and 162 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -104,15 +104,6 @@ dependencies = [
|
||||||
"synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "imlib2"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"imlib2-sys 0.1.0",
|
|
||||||
"x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "imlib2-sys"
|
name = "imlib2-sys"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -212,11 +203,12 @@ name = "screenshot"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"imlib2 0.1.0",
|
"imlib2-sys 0.1.0",
|
||||||
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"xlib 0.1.0",
|
"x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -356,16 +348,6 @@ dependencies = [
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xlib"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"imlib2 0.1.0",
|
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
|
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
|
|
|
@ -5,7 +5,7 @@ version = "0.3.0"
|
||||||
authors = ["Michael Zhang <failed.down@gmail.com>"]
|
authors = ["Michael Zhang <failed.down@gmail.com>"]
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [".", "imlib2", "imlib2/imlib2-sys", "xlib"]
|
members = [".", "imlib2-sys"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["dylib", "rlib"]
|
crate-type = ["dylib", "rlib"]
|
||||||
|
@ -13,7 +13,8 @@ crate-type = ["dylib", "rlib"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
png = "0.12"
|
png = "0.12"
|
||||||
imlib2 = { path = "imlib2" }
|
imlib2-sys = { path = "imlib2-sys" }
|
||||||
|
libc = "0.2"
|
||||||
structopt = "0.2"
|
structopt = "0.2"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
xlib = { path = "xlib" }
|
x11 = { version = "2.18", features = ["xlib"] }
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "imlib2"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Michael Zhang <failed.down@gmail.com>"]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "lib.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
failure = "0.1"
|
|
||||||
imlib2-sys = { path = "imlib2-sys" }
|
|
||||||
x11 = { version = "2.18", features = ["xlib"] }
|
|
|
@ -1,25 +0,0 @@
|
||||||
//! Safe-ish bindings to imlib2 (at least the only parts I need).
|
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate failure;
|
|
||||||
extern crate imlib2_sys;
|
|
||||||
extern crate x11;
|
|
||||||
|
|
||||||
mod errors;
|
|
||||||
mod image;
|
|
||||||
|
|
||||||
pub use errors::Error;
|
|
||||||
pub use image::Image;
|
|
||||||
pub use imlib2_sys::{Drawable, Pixmap};
|
|
||||||
|
|
||||||
/// Set the display for the imlib context.
|
|
||||||
pub fn context_set_display(display: *mut x11::xlib::Display) {
|
|
||||||
unsafe { imlib2_sys::imlib_context_set_display(display as *mut imlib2_sys::_XDisplay) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the visual for the imlib context.
|
|
||||||
pub fn context_set_visual(visual: *mut x11::xlib::Visual) {
|
|
||||||
unsafe { imlib2_sys::imlib_context_set_visual(visual as *mut imlib2_sys::Visual) };
|
|
||||||
}
|
|
|
@ -11,7 +11,7 @@ pub fn capture(opt: &Options) -> Result<(), ScreenshotError> {
|
||||||
_ => gui.display.get_default_root_window()?,
|
_ => gui.display.get_default_root_window()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let capture = gui.capture_window(window_to_capture)?;
|
let capture = gui.capture_window(&opt, window_to_capture)?;
|
||||||
capture.save_image(&opt.outfile)?;
|
capture.save_image(&opt.outfile)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
45
src/gui.rs
45
src/gui.rs
|
@ -1,9 +1,11 @@
|
||||||
use imlib2::{self, Image as Image2};
|
use imlib2::{self, Image as Image2};
|
||||||
use xlib::{Display, Image, Window, Visual};
|
use xlib::{Display, EventKind, Visual, Window};
|
||||||
|
|
||||||
use errors::ScreenshotError;
|
use errors::ScreenshotError;
|
||||||
|
use Options;
|
||||||
use Rectangle;
|
use Rectangle;
|
||||||
use SelectWindow;
|
use SelectWindow;
|
||||||
|
use Region;
|
||||||
|
|
||||||
pub struct GUI {
|
pub struct GUI {
|
||||||
pub(crate) display: Display,
|
pub(crate) display: Display,
|
||||||
|
@ -15,19 +17,31 @@ impl GUI {
|
||||||
Ok(GUI { display })
|
Ok(GUI { display })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Captures the window and produces a DynamicImage.
|
/// Captures the window and produces an Image.
|
||||||
pub fn capture_window(&self, window: Window) -> Result<Image2, ScreenshotError> {
|
pub fn capture_window(&self, opt: &Options, window: Window) -> Result<Image2, ScreenshotError> {
|
||||||
let attr = window.get_attributes()?;
|
let attr = window.get_attributes()?;
|
||||||
let width = attr.get_width() as i32;
|
let mut width = attr.get_width();
|
||||||
let height = attr.get_height() as i32;
|
let mut height = attr.get_height();
|
||||||
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 (mut x, mut y, _) = self.display.translate_coordinates(window, 0, 0, root)?;
|
||||||
|
|
||||||
imlib2::context_set_display(self.display.as_raw());
|
imlib2::context_set_display(&self.display);
|
||||||
let visual = Visual::default(&self.display, 0);
|
let visual = Visual::default(&self.display, 0);
|
||||||
imlib2::context_set_visual(visual.as_raw());
|
imlib2::context_set_visual(&visual);
|
||||||
|
|
||||||
Image2::create_from_drawable(window, 0, x, y, width, height, true).map_err(|err| err.into())
|
match opt.region {
|
||||||
|
Region::Selection => {
|
||||||
|
let region = self.interactive_select()?;
|
||||||
|
x = region.x;
|
||||||
|
y = region.y;
|
||||||
|
width = region.width;
|
||||||
|
height = region.height;
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
|
||||||
|
Image2::create_from_drawable(window, 0, x, y, width as i32, height as i32, true)
|
||||||
|
.map_err(|err| err.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the active window.
|
/// Get the active window.
|
||||||
|
@ -40,8 +54,19 @@ 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) -> Result<Rectangle, ScreenshotError> {
|
||||||
let window = SelectWindow::new(&self.display);
|
let window = SelectWindow::new(&self.display);
|
||||||
|
let root = self.display.get_default_root_window()?;
|
||||||
|
|
||||||
|
let root_im = root.get_image();
|
||||||
|
|
||||||
|
let mut done = 0;
|
||||||
|
while done == 0 && self.display.pending()? > 0 {
|
||||||
|
let ev = self.display.next_event()?;
|
||||||
|
match ev.kind() {
|
||||||
|
EventKind::None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(ScreenshotError::Error)
|
Err(ScreenshotError::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ use std::ffi::CString;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use imlib2_sys as im;
|
use imlib2_sys as im;
|
||||||
use x11;
|
|
||||||
|
|
||||||
use Error;
|
use imlib2::Error;
|
||||||
|
use xlib::Drawable;
|
||||||
|
|
||||||
/// A simple wrapper around Imlib_Image
|
/// A simple wrapper around Imlib_Image
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
|
@ -14,7 +14,7 @@ pub struct Image {
|
||||||
impl Image {
|
impl Image {
|
||||||
/// Creates an Image from a pixmap.
|
/// Creates an Image from a pixmap.
|
||||||
pub fn create_from_drawable(
|
pub fn create_from_drawable(
|
||||||
drawable: impl AsRef<im::Drawable>,
|
drawable: impl Drawable,
|
||||||
pixmap: im::Pixmap,
|
pixmap: im::Pixmap,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
|
@ -22,7 +22,7 @@ impl Image {
|
||||||
height: i32,
|
height: i32,
|
||||||
grab_x: bool,
|
grab_x: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
unsafe { im::imlib_context_set_drawable(*drawable.as_ref()) };
|
unsafe { im::imlib_context_set_drawable(drawable.as_drawable()) };
|
||||||
let image = unsafe {
|
let image = unsafe {
|
||||||
im::imlib_create_image_from_drawable(
|
im::imlib_create_image_from_drawable(
|
||||||
pixmap,
|
pixmap,
|
||||||
|
@ -33,15 +33,21 @@ impl Image {
|
||||||
if grab_x { 1 } else { 0 },
|
if grab_x { 1 } else { 0 },
|
||||||
) as im::Imlib_Image
|
) as im::Imlib_Image
|
||||||
};
|
};
|
||||||
|
unsafe { im::imlib_context_set_image(image) };
|
||||||
Ok(Image { inner: image })
|
Ok(Image { inner: image })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save this image
|
/// Save this image
|
||||||
pub fn save_image(&self, file: impl AsRef<Path>) -> Result<(), Error> {
|
pub fn save_image(&self, file: impl AsRef<Path>) -> Result<(), Error> {
|
||||||
unsafe { im::imlib_context_set_image((*self).inner) };
|
|
||||||
let mut error = 0;
|
let mut error = 0;
|
||||||
let path = CString::new(file.as_ref().to_str().unwrap()).unwrap();
|
let path = CString::new(file.as_ref().to_str().unwrap()).unwrap();
|
||||||
unsafe { im::imlib_save_image_with_error_return(path.as_ptr(), &mut error) };
|
unsafe { im::imlib_save_image_with_error_return(path.as_ptr(), &mut error) };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for Image {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { im::imlib_free_image() };
|
||||||
|
}
|
||||||
|
}
|
26
src/imlib2/mod.rs
Normal file
26
src/imlib2/mod.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//! Safe-ish bindings to imlib2 (at least the only parts I need).
|
||||||
|
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
mod errors;
|
||||||
|
mod image;
|
||||||
|
|
||||||
|
use imlib2_sys;
|
||||||
|
|
||||||
|
pub use self::errors::Error;
|
||||||
|
pub use self::image::Image;
|
||||||
|
pub use imlib2_sys::{Drawable, Pixmap};
|
||||||
|
|
||||||
|
use xlib::{Display, Visual};
|
||||||
|
|
||||||
|
/// Set the display for the imlib context.
|
||||||
|
pub fn context_set_display(display: &Display) {
|
||||||
|
unsafe {
|
||||||
|
imlib2_sys::imlib_context_set_display(display.as_raw() as *mut imlib2_sys::_XDisplay)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the visual for the imlib context.
|
||||||
|
pub fn context_set_visual(visual: &Visual) {
|
||||||
|
unsafe { imlib2_sys::imlib_context_set_visual(visual.as_raw() as *mut imlib2_sys::Visual) };
|
||||||
|
}
|
13
src/lib.rs
13
src/lib.rs
|
@ -1,11 +1,14 @@
|
||||||
|
#![feature(try_from)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
extern crate imlib2;
|
extern crate imlib2_sys;
|
||||||
|
extern crate libc;
|
||||||
extern crate png;
|
extern crate png;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate structopt;
|
extern crate structopt;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate xlib;
|
extern crate x11;
|
||||||
|
|
||||||
mod capture;
|
mod capture;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
@ -13,9 +16,13 @@ mod gui;
|
||||||
mod options;
|
mod options;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
pub mod imlib2;
|
||||||
|
pub mod xlib;
|
||||||
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use xlib::Rectangle;
|
use xlib::Rectangle;
|
||||||
|
use errors::ScreenshotError;
|
||||||
|
|
||||||
pub use capture::capture;
|
pub use capture::capture;
|
||||||
pub use options::Options;
|
pub use options::{Options, Region};
|
||||||
pub use window::SelectWindow;
|
pub use window::SelectWindow;
|
||||||
|
|
|
@ -8,6 +8,5 @@ use structopt::StructOpt;
|
||||||
|
|
||||||
pub fn main() -> Result<(), Error> {
|
pub fn main() -> Result<(), Error> {
|
||||||
let opt = Options::from_args();
|
let opt = Options::from_args();
|
||||||
// let image = capture(&opt)?;
|
|
||||||
capture(&opt).map(|_| ()).map_err(|err| err.into())
|
capture(&opt).map(|_| ()).map_err(|err| err.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
use ScreenshotError;
|
||||||
|
|
||||||
pub enum Region {
|
pub enum Region {
|
||||||
#[structopt(name = "fullscreen")]
|
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
|
|
||||||
#[structopt(name = "window")]
|
|
||||||
ActiveWindow,
|
ActiveWindow,
|
||||||
|
|
||||||
#[structopt(name = "select")]
|
|
||||||
Selection,
|
Selection,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[structopt(subcommand)]
|
#[structopt(parse(try_from_str = "Region::from_str"))]
|
||||||
pub region: Region,
|
pub region: Region,
|
||||||
|
|
||||||
#[structopt(short = "o", long = "out", parse(from_os_str))]
|
#[structopt(short = "o", long = "out", parse(from_os_str))]
|
||||||
|
@ -23,3 +19,14 @@ pub struct Options {
|
||||||
#[structopt(short = "c")]
|
#[structopt(short = "c")]
|
||||||
pub clipboard: bool,
|
pub clipboard: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Region {
|
||||||
|
pub fn from_str(x: &str) -> Result<Self, ScreenshotError> {
|
||||||
|
match x {
|
||||||
|
"fullscreen" => Ok(Region::Fullscreen),
|
||||||
|
"window" => Ok(Region::ActiveWindow),
|
||||||
|
"select" | "selection" => Ok(Region::Selection),
|
||||||
|
_ => Err(ScreenshotError::Error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use xlib::{Display, Window, Rectangle};
|
use xlib::{Display, Rectangle, Window};
|
||||||
|
|
||||||
use errors::ScreenshotError;
|
use errors::ScreenshotError;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
use libc;
|
||||||
use x11::xlib as x;
|
use x11::xlib as x;
|
||||||
|
|
||||||
use Visual;
|
use xlib::{Event, Visual, Window, X11Error};
|
||||||
use Window;
|
|
||||||
use X11Error;
|
|
||||||
|
|
||||||
/// A connection to an X server.
|
/// A connection to an X server.
|
||||||
pub struct Display {
|
pub struct Display {
|
||||||
inner: *mut x::Display,
|
inner: *mut x::Display,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Something that's part of a display.
|
||||||
|
pub trait GetDisplay {
|
||||||
|
/// Get the current display
|
||||||
|
fn get_display(&self) -> *mut x::Display;
|
||||||
|
}
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
/// Opens a new connection to an X server.
|
/// Opens a new connection to an X server.
|
||||||
///
|
///
|
||||||
|
@ -25,6 +30,18 @@ impl Display {
|
||||||
Ok(Display { inner })
|
Ok(Display { inner })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the next event, blocks until an event is reached.
|
||||||
|
pub fn next_event(&self) -> Result<Event, X11Error> {
|
||||||
|
let event =
|
||||||
|
unsafe { libc::malloc(::std::mem::size_of::<x::XAnyEvent>()) as *mut x::XAnyEvent };
|
||||||
|
Event::from_raw(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of events that are still pending
|
||||||
|
pub fn pending(&self) -> Result<i32, X11Error> {
|
||||||
|
Ok(unsafe { x::XPending(self.inner) })
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the raw X Display handle
|
/// Gets the raw X Display handle
|
||||||
pub fn as_raw(&self) -> *mut x::Display {
|
pub fn as_raw(&self) -> *mut x::Display {
|
||||||
self.inner
|
self.inner
|
26
src/xlib/drawable.rs
Normal file
26
src/xlib/drawable.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use x11::xlib as x;
|
||||||
|
|
||||||
|
use xlib::{GetDisplay, Image, Rectangle, X11Error};
|
||||||
|
|
||||||
|
/// Anything that's drawable
|
||||||
|
pub trait Drawable: GetDisplay {
|
||||||
|
/// Get drawable handle
|
||||||
|
fn as_drawable(&self) -> x::Drawable;
|
||||||
|
|
||||||
|
/// Capture a snapshot of this drawable, clipped by rect.
|
||||||
|
fn get_image(&self, rect: Rectangle) -> Result<Image, X11Error> {
|
||||||
|
let image = unsafe {
|
||||||
|
x::XGetImage(
|
||||||
|
self.get_display(),
|
||||||
|
self.as_drawable(),
|
||||||
|
rect.x as i32,
|
||||||
|
rect.y as i32,
|
||||||
|
rect.width,
|
||||||
|
rect.height,
|
||||||
|
0xffffffff,
|
||||||
|
x::ZPixmap,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
Ok(Image { inner: image })
|
||||||
|
}
|
||||||
|
}
|
36
src/xlib/event.rs
Normal file
36
src/xlib/event.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use libc;
|
||||||
|
use x11::xlib as x;
|
||||||
|
|
||||||
|
use xlib::X11Error;
|
||||||
|
|
||||||
|
/// An x11 Event
|
||||||
|
pub struct Event {
|
||||||
|
inner: *mut x::XAnyEvent,
|
||||||
|
kind: EventKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Type of event
|
||||||
|
pub enum EventKind {
|
||||||
|
/// None event
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Event {
|
||||||
|
/// Returns the EventKind of this event
|
||||||
|
pub fn kind(&self) -> &EventKind {
|
||||||
|
&self.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn from_raw(event: *mut x::XAnyEvent) -> Result<Self, X11Error> {
|
||||||
|
Ok(Event {
|
||||||
|
inner: event,
|
||||||
|
kind: EventKind::None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Event {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { libc::free(self.inner as *mut libc::c_void) };
|
||||||
|
}
|
||||||
|
}
|
2
src/xlib/gc.rs
Normal file
2
src/xlib/gc.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/// Graphics context
|
||||||
|
pub struct GC {}
|
|
@ -1,6 +1,6 @@
|
||||||
use x11::xlib as x;
|
use x11::xlib as x;
|
||||||
|
|
||||||
use X11Error;
|
use xlib::X11Error;
|
||||||
|
|
||||||
/// A handle to an XImage.
|
/// A handle to an XImage.
|
||||||
pub struct Image {
|
pub struct Image {
|
25
src/xlib/mod.rs
Normal file
25
src/xlib/mod.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//! Safe-ish bindings to parts of x11's xlib module.
|
||||||
|
//!
|
||||||
|
//! I need this for my project.
|
||||||
|
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
mod display;
|
||||||
|
mod drawable;
|
||||||
|
mod errors;
|
||||||
|
mod event;
|
||||||
|
mod gc;
|
||||||
|
mod image;
|
||||||
|
mod rect;
|
||||||
|
mod visual;
|
||||||
|
mod window;
|
||||||
|
|
||||||
|
pub use self::display::{Display, GetDisplay};
|
||||||
|
pub use self::drawable::Drawable;
|
||||||
|
pub use self::errors::X11Error;
|
||||||
|
pub use self::event::{Event, EventKind};
|
||||||
|
pub use self::gc::GC;
|
||||||
|
pub use self::image::{Image, ImageByteOrder, PixBuffer};
|
||||||
|
pub use self::rect::Rectangle;
|
||||||
|
pub use self::visual::Visual;
|
||||||
|
pub use self::window::{Window, WindowAttributes};
|
|
@ -2,9 +2,9 @@
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Rectangle {
|
pub struct Rectangle {
|
||||||
/// x
|
/// x
|
||||||
pub x: u32,
|
pub x: i32,
|
||||||
/// y
|
/// y
|
||||||
pub y: u32,
|
pub y: i32,
|
||||||
/// width
|
/// width
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
/// height
|
/// height
|
||||||
|
@ -13,7 +13,7 @@ pub struct Rectangle {
|
||||||
|
|
||||||
impl Rectangle {
|
impl Rectangle {
|
||||||
/// Create a new Rectangle from u32s
|
/// Create a new Rectangle from u32s
|
||||||
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
|
pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
|
@ -1,6 +1,6 @@
|
||||||
use x11::xlib as x;
|
use x11::xlib as x;
|
||||||
|
|
||||||
use Display;
|
use xlib::Display;
|
||||||
|
|
||||||
/// A wrapper around a Visual
|
/// A wrapper around a Visual
|
||||||
pub struct Visual {
|
pub struct Visual {
|
|
@ -1,13 +1,10 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use imlib2::Drawable;
|
// use imlib2::Drawable;
|
||||||
use libc;
|
use libc;
|
||||||
use x11::xlib as x;
|
use x11::xlib as x;
|
||||||
|
|
||||||
use Display;
|
use xlib::{Display, Drawable, GetDisplay, Image, Rectangle, X11Error};
|
||||||
use Image;
|
|
||||||
use Rectangle;
|
|
||||||
use X11Error;
|
|
||||||
|
|
||||||
/// A wrapper around a window handle.
|
/// A wrapper around a window handle.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
@ -67,36 +64,44 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Capture a snapshot of this window.
|
|
||||||
pub fn get_image(&self) -> Result<Image, X11Error> {
|
|
||||||
let attr = self.get_attributes()?;
|
|
||||||
let image = unsafe {
|
|
||||||
x::XGetImage(
|
|
||||||
self.display,
|
|
||||||
self.inner,
|
|
||||||
attr.get_x(),
|
|
||||||
attr.get_y(),
|
|
||||||
attr.get_width(),
|
|
||||||
attr.get_height(),
|
|
||||||
0xffffffff,
|
|
||||||
x::ZPixmap,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
Ok(Image { inner: image })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the raw window handle
|
/// Get the raw window handle
|
||||||
pub fn as_raw(&self) -> x::Window {
|
pub fn as_raw(&self) -> x::Window {
|
||||||
self.inner
|
self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get image
|
||||||
|
pub fn get_image(&self) -> Result<Image, X11Error> {
|
||||||
|
let attr = self.get_attributes()?;
|
||||||
|
Drawable::get_image(
|
||||||
|
self,
|
||||||
|
Rectangle::new(
|
||||||
|
attr.get_x(),
|
||||||
|
attr.get_y(),
|
||||||
|
attr.get_width(),
|
||||||
|
attr.get_height(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<Drawable> for Window {
|
impl GetDisplay for Window {
|
||||||
fn as_ref(&self) -> &Drawable {
|
fn get_display(&self) -> *mut x::Display {
|
||||||
&self.inner
|
self.display
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drawable for Window {
|
||||||
|
fn as_drawable(&self) -> x::Drawable {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl AsRef<Drawable> for Window {
|
||||||
|
// fn as_ref(&self) -> &Drawable {
|
||||||
|
// &self.inner
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl WindowAttributes {
|
impl WindowAttributes {
|
||||||
/// Gets the width of the window
|
/// Gets the width of the window
|
||||||
pub fn get_x(&self) -> i32 {
|
pub fn get_x(&self) -> i32 {
|
|
@ -1,11 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "xlib"
|
|
||||||
description = "Safe-ish bindings to xlib (or at least the parts that I need)"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Michael Zhang <failed.down@gmail.com>"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
failure = "0.1"
|
|
||||||
imlib2 = { path = "../imlib2" }
|
|
||||||
libc = "0.2"
|
|
||||||
x11 = { version = "2.18", features = ["xlib"] }
|
|
|
@ -1,26 +0,0 @@
|
||||||
//! Safe-ish bindings to parts of x11's xlib module.
|
|
||||||
//!
|
|
||||||
//! I need this for my project.
|
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate failure;
|
|
||||||
extern crate imlib2;
|
|
||||||
extern crate libc;
|
|
||||||
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};
|
|
||||||
|
|
Loading…
Reference in a new issue