try build

This commit is contained in:
Michael Zhang 2018-09-10 23:13:33 -05:00
parent 201b2e480f
commit de118c6047
No known key found for this signature in database
GPG key ID: A1B65B603268116B
21 changed files with 15108 additions and 13 deletions

View file

@ -2,8 +2,11 @@ language: rust
sudo: required sudo: required
dist: trusty dist: trusty
script:
- ./ci/check.sh screenshot
before_deploy: before_deploy:
- ./ci/build-release.sh dip ${TRAVIS_TAG}-${TRAVIS_OS_NAME} - ./ci/build-release.sh screenshot ${TRAVIS_TAG}-${TRAVIS_OS_NAME}
deploy: deploy:
- provider: releases - provider: releases

15
Cargo.lock generated
View file

@ -104,6 +104,19 @@ 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]]
name = "imlib2-sys"
version = "0.1.0"
[[package]] [[package]]
name = "inflate" name = "inflate"
version = "0.4.3" version = "0.4.3"
@ -199,6 +212,7 @@ 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",
"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)",
@ -347,6 +361,7 @@ name = "xlib"
version = "0.1.0" version = "0.1.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",
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View file

@ -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 = [".", "xlib"] members = [".", "imlib2", "imlib2/imlib2-sys", "xlib"]
[lib] [lib]
crate-type = ["dylib", "rlib"] crate-type = ["dylib", "rlib"]
@ -13,6 +13,7 @@ crate-type = ["dylib", "rlib"]
[dependencies] [dependencies]
failure = "0.1" failure = "0.1"
png = "0.12" png = "0.12"
imlib2 = { path = "imlib2" }
structopt = "0.2" structopt = "0.2"
time = "0.1" time = "0.1"
xlib = { path = "xlib" } xlib = { path = "xlib" }

View file

@ -1,5 +1,7 @@
FROM ekidd/rust-musl-builder FROM ekidd/rust-musl-builder
RUN sudo apt-get update -y && sudo apt-get install -y libx11-dev libimlib2-dev
COPY . ./ COPY . ./
RUN sudo chown -R rust:rust . RUN sudo chown -R rust:rust .

8
Dockerfile.check Normal file
View file

@ -0,0 +1,8 @@
FROM ekidd/rust-musl-builder
RUN sudo apt-get update -y && sudo apt-get install -y libx11-dev libimlib2-dev
COPY . ./
RUN sudo chown -R rust:rust .
CMD cargo build

33
ci/check.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
#
# Usage: ./build-release <PROJECT> ${TRAVIS_TAG}-${TRAVIS_OS_NAME}
#
# The latest version of this script is available at
# https://github.com/emk/rust-musl-builder/blob/master/examples/build-release
#
# Called by `.travis.yml` to build release binaries. We use
# ekidd/rust-musl-builder to make the Linux binaries so that we can run
# them unchanged on any distro, including tiny distros like Alpine (which
# is heavily used for Docker containers). Other platforms get regular
# binaries, which will generally be dynamically linked against libc.
#
# If you have a platform which supports static linking of libc, and this
# would be generally useful, please feel free to submit patches.
set -euo pipefail
case `uname -s` in
Linux)
echo "Building static binaries using ekidd/rust-musl-builder"
docker build -f Dockerfile.check -t build-"$1"-image .
docker run -it --name build-"$1" build-"$1"-image
docker cp build-"$1":/home/rust/src/target/x86_64-unknown-linux-musl/release/"$1" "$1"
docker rm build-"$1"
docker rmi build-"$1"-image
;;
*)
echo "Building standard release binaries"
cargo build --release
zip -j "$1"-"$2".zip target/release/"$1"
;;
esac

12
imlib2/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[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"] }

7
imlib2/errors.rs Normal file
View file

@ -0,0 +1,7 @@
/// Enumerated error type.
#[allow(missing_docs)]
#[derive(Debug, Fail)]
pub enum Error {
#[fail(display = "error")]
Error,
}

45
imlib2/image.rs Normal file
View file

@ -0,0 +1,45 @@
use std::ffi::CString;
use std::path::Path;
use imlib2_sys as im;
use x11;
use Error;
/// A simple wrapper around Imlib_Image
pub struct Image {
inner: im::Imlib_Image,
}
impl Image {
/// Set the display for the imlib context.
pub fn context_set_display(display: *mut x11::xlib::Display) {
unsafe { im::imlib_context_set_display(display as *mut im::_XDisplay) };
}
/// Creates an Image from a pixmap.
pub fn create_from_drawable(
drawable: impl AsRef<im::Drawable>,
pixmap: im::Pixmap,
x: i32,
y: i32,
width: i32,
height: i32,
grab_x: bool,
) -> Result<Self, Error> {
unsafe { im::imlib_context_set_drawable(*drawable.as_ref()) };
let image = unsafe {
im::imlib_create_image_from_drawable(pixmap, x, y, width, height, if grab_x{ 1 } else { 0 }) as im::Imlib_Image
};
Ok(Image { inner: image })
}
/// Save this image
pub fn save_image(&self, file: impl AsRef<Path>) -> Result<(), Error> {
unsafe { im::imlib_context_set_image((*self).inner) };
let mut error = 0;
let path = CString::new(file.as_ref().to_str().unwrap()).unwrap();
unsafe { im::imlib_save_image_with_error_return(path.as_ptr(), &mut error) };
Ok(())
}
}

View file

@ -0,0 +1,10 @@
[package]
name = "imlib2-sys"
version = "0.1.0"
authors = ["Michael Zhang <failed.down@gmail.com>"]
build = "build.rs"
[lib]
path = "lib.rs"
[build-dependencies]

View file

@ -0,0 +1,3 @@
fn main() {
println!("cargo:rustc-link-lib=Imlib2");
}

14917
imlib2/imlib2-sys/lib.rs Normal file

File diff suppressed because it is too large Load diff

15
imlib2/lib.rs Normal file
View file

@ -0,0 +1,15 @@
//! 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};

View file

@ -2,12 +2,10 @@ use errors::ScreenshotError;
use gui::GUI; use gui::GUI;
use options::{Options, Region}; use options::{Options, Region};
use xlib::Image;
use ImageExt;
use Rectangle; use Rectangle;
pub fn capture(opt: &Options) -> Result<Image, ScreenshotError> { pub fn capture(opt: &Options) -> Result<(), ScreenshotError> {
let gui = GUI::new()?; let gui = GUI::new()?;
// let window_to_capture = match opt.region { // let window_to_capture = match opt.region {
@ -17,7 +15,7 @@ pub fn capture(opt: &Options) -> Result<Image, ScreenshotError> {
let window_to_capture = gui.display.get_default_root_window()?; let window_to_capture = gui.display.get_default_root_window()?;
let capture = gui.capture_window(window_to_capture)?; let capture = gui.capture_window(window_to_capture)?;
let clip = match opt.region { let _clip = match opt.region {
Region::ActiveWindow => { Region::ActiveWindow => {
let win = gui.get_active_window()?; let win = gui.get_active_window()?;
let attr = win.get_attributes()?; let attr = win.get_attributes()?;
@ -35,7 +33,8 @@ pub fn capture(opt: &Options) -> Result<Image, ScreenshotError> {
_ => None, _ => None,
}; };
capture.write_png(&opt.outfile, clip)?; // capture.write_png(&opt.outfile, clip)?;
capture.save_image(&opt.outfile)?;
// let final_capture = match opt.region { // let final_capture = match opt.region {
// Region::Fullscreen | Region::ActiveWindow => window_capture, // Region::Fullscreen | Region::ActiveWindow => window_capture,
@ -47,5 +46,5 @@ pub fn capture(opt: &Options) -> Result<Image, ScreenshotError> {
// capture.apply_region(&region); // capture.apply_region(&region);
// }; // };
Ok(capture) Ok(())
} }

View file

@ -3,6 +3,9 @@ pub enum ScreenshotError {
#[fail(display = "x11 error")] #[fail(display = "x11 error")]
X11Error(#[cause] ::xlib::X11Error), X11Error(#[cause] ::xlib::X11Error),
#[fail(display = "imlib2 error")]
ImlibError(#[cause] ::imlib2::Error),
#[fail(display = "io error")] #[fail(display = "io error")]
IOError(#[cause] ::std::io::Error), IOError(#[cause] ::std::io::Error),
@ -25,6 +28,12 @@ impl From<::xlib::X11Error> for ScreenshotError {
} }
} }
impl From<::imlib2::Error> for ScreenshotError {
fn from(err: ::imlib2::Error) -> Self {
ScreenshotError::ImlibError(err)
}
}
impl From<::png::EncodingError> for ScreenshotError { impl From<::png::EncodingError> for ScreenshotError {
fn from(err: ::png::EncodingError) -> Self { fn from(err: ::png::EncodingError) -> Self {
ScreenshotError::PngEncodingError(err) ScreenshotError::PngEncodingError(err)

View file

@ -1,4 +1,5 @@
use xlib::{Display, Image, Window}; use xlib::{Display, Image, Window};
use imlib2::{Image as Image2,};
use errors::ScreenshotError; use errors::ScreenshotError;
use Rectangle; use Rectangle;
@ -14,14 +15,14 @@ impl GUI {
} }
/// Captures the window and produces a DynamicImage. /// Captures the window and produces a DynamicImage.
pub fn capture_window(&self, window: Window) -> Result<Image, ScreenshotError> { pub fn capture_window(&self, window: Window) -> Result<Image2, ScreenshotError> {
let attr = window.get_attributes()?; let attr = window.get_attributes()?;
let width = attr.get_width(); let width = attr.get_width() as i32;
let height = attr.get_height(); 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)?;
println!("x={} y={} width={} height={}", x, y, width, height); Image2::context_set_display(self.display.as_raw());
window.get_image().map_err(|err| err.into()) Image2::create_from_drawable(window, 0, x, y, width, height, true).map_err(|err| err.into())
} }
/// Get the active window. /// Get the active window.

View file

@ -1,5 +1,6 @@
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
extern crate imlib2;
extern crate png; extern crate png;
#[macro_use] #[macro_use]
extern crate structopt; extern crate structopt;

View file

@ -6,5 +6,6 @@ authors = ["Michael Zhang <failed.down@gmail.com>"]
[dependencies] [dependencies]
failure = "0.1" failure = "0.1"
imlib2 = { path = "../imlib2" }
libc = "0.2" libc = "0.2"
x11 = { version = "2.18", features = ["xlib"] } x11 = { version = "2.18", features = ["xlib"] }

View file

@ -24,6 +24,11 @@ impl Display {
Ok(Display { inner }) Ok(Display { inner })
} }
/// Gets the raw X Display handle
pub fn as_raw(&self) -> *mut x::Display {
self.inner
}
/// 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) };

View file

@ -6,6 +6,7 @@
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
extern crate imlib2;
extern crate libc; extern crate libc;
extern crate x11; extern crate x11;

View file

@ -1,5 +1,6 @@
use std::mem; use std::mem;
use imlib2::Drawable;
use libc; use libc;
use x11::xlib as x; use x11::xlib as x;
@ -50,6 +51,12 @@ impl Window {
} }
} }
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 {