From 24d019fdcb55bb2a93dc05940aeb8cdbb3a85e95 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Tue, 11 Sep 2018 13:21:59 -0500 Subject: [PATCH] works with imlib! --- imlib2/image.rs | 14 +++++---- imlib2/lib.rs | 13 ++++++++ imlib2/visual.rs | 15 ++++++++++ src/capture.rs | 7 +---- src/gui.rs | 5 ++-- src/image.rs | 77 ------------------------------------------------ src/lib.rs | 13 ++++++-- 7 files changed, 51 insertions(+), 93 deletions(-) create mode 100644 imlib2/visual.rs delete mode 100644 src/image.rs diff --git a/imlib2/image.rs b/imlib2/image.rs index 983895e..e40ef81 100644 --- a/imlib2/image.rs +++ b/imlib2/image.rs @@ -12,11 +12,6 @@ pub struct 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, @@ -29,7 +24,14 @@ impl Image { ) -> Result { 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 + 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 }) } diff --git a/imlib2/lib.rs b/imlib2/lib.rs index 0167b07..3d23c22 100644 --- a/imlib2/lib.rs +++ b/imlib2/lib.rs @@ -9,7 +9,20 @@ 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) { + 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: Visual) { + unsafe { imlib2_sys::imlib_context_set_visual(visual.inner) }; +} + diff --git a/imlib2/visual.rs b/imlib2/visual.rs new file mode 100644 index 0000000..66c6ac6 --- /dev/null +++ b/imlib2/visual.rs @@ -0,0 +1,15 @@ +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 } + } +} diff --git a/src/capture.rs b/src/capture.rs index 133cf46..c42b4d4 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -23,12 +23,7 @@ pub fn capture(opt: &Options) -> Result<(), ScreenshotError> { 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 { - x: x as u32, - y: y as u32, - width, - height, - }) + Some(Rectangle::new(x as u32, y as u32, width, height)) } _ => None, }; diff --git a/src/gui.rs b/src/gui.rs index bea490c..aa3b166 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,5 +1,5 @@ +use imlib2::{self, Image as Image2, Visual}; use xlib::{Display, Image, Window}; -use imlib2::{Image as Image2,}; use errors::ScreenshotError; use Rectangle; @@ -21,7 +21,8 @@ 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)?; - Image2::context_set_display(self.display.as_raw()); + imlib2::context_set_display(self.display.as_raw()); + imlib2::context_set_visual(Visual::default(self.display.as_raw(), 0)); Image2::create_from_drawable(window, 0, x, y, width, height, true).map_err(|err| err.into()) } diff --git a/src/image.rs b/src/image.rs deleted file mode 100644 index b879c80..0000000 --- a/src/image.rs +++ /dev/null @@ -1,77 +0,0 @@ -use std::fs::File; -use std::io::BufWriter; -use std::path::Path; - -use png::{self, Encoder, HasParameters}; -use xlib::{Image, ImageByteOrder}; - -use errors::ScreenshotError; -use Rectangle; - -pub trait ImageExt { - fn to_data_buf(&self, rect: Rectangle) -> Result, ScreenshotError>; - fn write_png( - &self, - out: impl AsRef, - rect: Option, - ) -> Result<(), ScreenshotError>; -} - -impl ImageExt for Image { - /// Converts the image buffer into RGB(A). - fn to_data_buf(&self, rect: Rectangle) -> Result, ScreenshotError> { - let (full_width, _) = (self.get_width() as usize, self.get_height() as usize); - let bytes_per_row = 4 * rect.width as usize; - let size = bytes_per_row * rect.height as usize; - let mut buf = vec![1; size]; - let sbuf = self.buffer(); // source buffer - let mut rx = rect.y as usize; - if let ImageByteOrder::LSBFirst = self.get_byte_order()? { - // LSBFirst - while rx < rect.height as usize { - let mut sx = (rx * full_width + rect.x as usize) * 4; // source idx - let mut dx = rx * bytes_per_row; // dest idx - let edx = (rx + 1) * bytes_per_row; - // println!("sx={} dx={} edx={}", sx,dx,edx); - while dx < edx { - buf[dx] = sbuf.get_byte(sx + 2).unwrap() as u8; - buf[dx + 1] = sbuf.get_byte(sx + 1).unwrap() as u8; - buf[dx + 2] = sbuf.get_byte(sx).unwrap() as u8; - buf[dx + 3] = if self.get_depth() == 32 { - sbuf.get_byte(sx + 3).unwrap() as u8 - } else { - 255u8 - }; - sx += 4; - dx += 4; - } - rx += 1; - } - } - Ok(buf) - } - - fn write_png( - &self, - out: impl AsRef, - rect: Option, - ) -> Result<(), ScreenshotError> { - let rect = rect.unwrap_or_else(|| Rectangle { - x: 0, - y: 0, - width: self.get_width(), - height: self.get_height(), - }); - - let file = File::create(out.as_ref())?; - let ref mut out = BufWriter::new(file); - - let mut encoder = Encoder::new(out, rect.width, rect.height); - encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight); - let mut writer = encoder.write_header()?; - - let data = self.to_data_buf(rect)?; - writer.write_image_data(data.as_slice())?; - Ok(()) - } -} diff --git a/src/lib.rs b/src/lib.rs index 394b455..47c2a85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,13 +10,11 @@ extern crate xlib; mod capture; mod errors; mod gui; -mod image; mod options; use structopt::StructOpt; pub use capture::capture; -pub use image::ImageExt; pub use options::Options; #[derive(Debug)] @@ -26,3 +24,14 @@ pub struct Rectangle { 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, + } + } +}