From 6be5db5e573c2b50bab35e933016dd136274f319 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sun, 28 Jun 2020 00:34:50 -0500 Subject: [PATCH] update --- src/main.rs | 87 ++++++++++++++++++++--------------------- src/platform/mod.rs | 7 +++- src/platform/x11.rs | 22 ++++++++--- x11/src/errors.rs | 5 ++- x11/src/xlib/display.rs | 9 +++-- x11/src/xlib/event.rs | 34 +++++++++------- 6 files changed, 93 insertions(+), 71 deletions(-) diff --git a/src/main.rs b/src/main.rs index 667d54a..d560966 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,52 +31,51 @@ pub fn main() -> Result<()> { Region::Fullscreen | Region::Selection => { let mut image = gui.capture_full_screen()?; - if let Region::Fullscreen = opt.region { - // calculate the full size of the image - let mut min_x = 0; - let mut min_y = 0; - let mut max_x = 0; - let mut max_y = 0; - for (i, (_, screen)) in screen_layout.iter().enumerate() { - let left = screen.x; - let right = screen.x + screen.width as i16; - let top = screen.y; - let bottom = screen.y + screen.height as i16; - if i == 0 { - min_x = left; - min_y = top; - max_x = right; - max_y = bottom; - } else { - min_x = min_x.min(left); - min_y = min_y.min(top); - max_x = max_x.max(right); - max_y = max_y.max(bottom); - } + // calculate the full size of the image + let mut min_x = 0; + let mut min_y = 0; + let mut max_x = 0; + let mut max_y = 0; + for (i, (_, screen)) in screen_layout.iter().enumerate() { + let left = screen.x; + let right = screen.x + screen.width as i16; + let top = screen.y; + let bottom = screen.y + screen.height as i16; + if i == 0 { + min_x = left; + min_y = top; + max_x = right; + max_y = bottom; + } else { + min_x = min_x.min(left); + min_y = min_y.min(top); + max_x = max_x.max(right); + max_y = max_y.max(bottom); } - - debug!( - "full virtual screen rect : ({}, {}) to ({}, {})", - min_x, min_y, max_x, max_y - ); - - // make a new image - let width = (max_x - min_x) as u32; - let height = (max_y - min_y) as u32; - let mut base_image = RgbImage::new(width, height); - - // copy all of the images into it - for (id, image) in gui.capture_full_screen()? { - let screen = screen_layout.get(&id).expect("shouldn't fail"); - let x = (screen.x + min_x) as u32; - let y = (screen.y + min_y) as u32; - let image = image.into_rgb_image(); - imageops::overlay(&mut base_image, &image, x, y); - } - - // save the image - base_image.save(&opt.outfile); } + + // make a new image + let width = (max_x - min_x) as u32; + let height = (max_y - min_y) as u32; + let mut base_image = RgbImage::new(width, height); + + // copy all of the images into it + let images = gui.capture_full_screen()?; + for (id, image) in images.iter() { + let screen = screen_layout.get(&id).expect("shouldn't fail"); + let x = (screen.x + min_x) as u32; + let y = (screen.y + min_y) as u32; + let image = image.to_rgb_image(); + imageops::overlay(&mut base_image, &image, x, y); + } + + if let Region::Selection = opt.region { + // bring up the interactive selection + let rect = gui.show_interactive_selection(&images)?; + } + + // save the image + base_image.save(&opt.outfile); } }; diff --git a/src/platform/mod.rs b/src/platform/mod.rs index f6e476e..4efae84 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -41,11 +41,14 @@ pub trait Platform { fn capture_full_screen(&self) -> Result>; /// Open the interactive selection interface - fn show_interactive_selection(&self, image: Self::Image) -> Result; + fn show_interactive_selection( + &self, + image: &HashMap, + ) -> Result; } /// Set of functions platform-specific images must implement pub trait Image { /// Convert the image into an image::RgbImage - fn into_rgb_image(self) -> RgbImage; + fn to_rgb_image(&self) -> RgbImage; } diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 9239ad1..657266c 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -69,13 +69,25 @@ impl Platform for X11 { .collect()) } - fn show_interactive_selection(&self, image: Self::Image) -> Result { - let window = Window::create(&self.inner, None, Rectangle::new(0, 0, 500, 500))?; + fn show_interactive_selection( + &self, + image: &HashMap, + ) -> Result { + let root_window = self.inner.get_default_root_window()?; + let window = Window::create( + &self.inner, + Some(root_window), + Rectangle::new(0, 0, 500, 500), + )?; window.map(); - let mut running = false; + while true { + let event = self.inner.next_event()?; + debug!("event: {:?}", event); + + // quit + } - while running {} unimplemented!() } } @@ -83,7 +95,7 @@ impl Platform for X11 { pub struct Image(x11::xlib::Image); impl ImageT for Image { - fn into_rgb_image(self) -> RgbImage { + fn to_rgb_image(&self) -> RgbImage { let width = self.0.get_width(); let height = self.0.get_height(); let pixbuf = self.0.buffer(); diff --git a/x11/src/errors.rs b/x11/src/errors.rs index a8d5c24..db4f989 100644 --- a/x11/src/errors.rs +++ b/x11/src/errors.rs @@ -4,9 +4,12 @@ pub type Result = std::result::Result; #[allow(missing_docs)] #[derive(Debug, Error)] pub enum Error { - #[error("invalid image byte order")] + #[error("invalid image byte order: {0}")] InvalidByteOrder(i32), + #[error("invalid event type: {0}")] + InvalidEventType(i32), + #[error("failed to get attributes")] GetAttributesError, diff --git a/x11/src/xlib/display.rs b/x11/src/xlib/display.rs index a5b6331..bf0ec09 100644 --- a/x11/src/xlib/display.rs +++ b/x11/src/xlib/display.rs @@ -1,4 +1,5 @@ use std::ffi::CString; +use std::ptr; use x11::xlib; @@ -63,10 +64,10 @@ impl Display { /// Get the next event, blocks until an event is reached. pub fn next_event(&self) -> Result { - let event = unsafe { - libc::malloc(::std::mem::size_of::()) as *mut xlib::XAnyEvent - }; - Event::from_raw(event) + let event = ptr::null_mut(); + unsafe { xlib::XNextEvent(self.inner, event) }; + // TODO: check to make sure this isn't null + unsafe { Event::from_raw(event) } } /// Returns the number of events that are still pending diff --git a/x11/src/xlib/event.rs b/x11/src/xlib/event.rs index 4bc5542..8bc6f45 100644 --- a/x11/src/xlib/event.rs +++ b/x11/src/xlib/event.rs @@ -1,23 +1,19 @@ use x11::xlib; -use crate::errors::Result; +use crate::errors::{Error, Result}; /// An x11 Event +#[derive(Debug)] pub struct Event { - inner: *mut xlib::XAnyEvent, + inner: *mut xlib::XEvent, kind: EventKind, } /// Type of event +#[derive(Debug)] pub enum EventKind { - /// A mouse button was pressed - ButtonPress, - - /// A mouse button was released - ButtonRelease, - - /// None event - None, + KeyPress(KeyEvent), + KeyRelease(KeyEvent), } impl Event { @@ -26,11 +22,16 @@ impl Event { &self.kind } - pub(super) fn from_raw(event: *mut xlib::XAnyEvent) -> Result { - Ok(Event { - inner: event, - kind: EventKind::None, - }) + pub(super) unsafe fn from_raw(event: *mut xlib::XEvent) -> Result { + let inner = event; + let event = unsafe { *event }; + debug!("event type: {:?}", event.type_); + let kind = match event.type_ { + xlib::KeyPress => EventKind::KeyPress(KeyEvent(event.key)), + xlib::KeyRelease => EventKind::KeyRelease(KeyEvent(event.key)), + other => return Err(Error::InvalidEventType(other)), + }; + Ok(Event { inner, kind }) } } @@ -39,3 +40,6 @@ impl Drop for Event { unsafe { libc::free(self.inner as *mut libc::c_void) }; } } + +#[derive(Debug)] +pub struct KeyEvent(xlib::XKeyEvent);