forked from michael/leanshot
update
This commit is contained in:
parent
505f56766a
commit
6be5db5e57
6 changed files with 93 additions and 71 deletions
17
src/main.rs
17
src/main.rs
|
@ -31,7 +31,6 @@ 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;
|
||||
|
@ -55,29 +54,29 @@ pub fn main() -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
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 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.into_rgb_image();
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -41,11 +41,14 @@ pub trait Platform {
|
|||
fn capture_full_screen(&self) -> Result<HashMap<Self::ScreenId, Self::Image>>;
|
||||
|
||||
/// Open the interactive selection interface
|
||||
fn show_interactive_selection(&self, image: Self::Image) -> Result<Rectangle>;
|
||||
fn show_interactive_selection(
|
||||
&self,
|
||||
image: &HashMap<Self::ScreenId, Self::Image>,
|
||||
) -> Result<Rectangle>;
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
|
|
@ -69,13 +69,25 @@ impl Platform for X11 {
|
|||
.collect())
|
||||
}
|
||||
|
||||
fn show_interactive_selection(&self, image: Self::Image) -> Result<Rectangle> {
|
||||
let window = Window::create(&self.inner, None, Rectangle::new(0, 0, 500, 500))?;
|
||||
fn show_interactive_selection(
|
||||
&self,
|
||||
image: &HashMap<Self::ScreenId, Self::Image>,
|
||||
) -> Result<Rectangle> {
|
||||
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();
|
||||
|
|
|
@ -4,9 +4,12 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|||
#[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,
|
||||
|
||||
|
|
|
@ -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<Event> {
|
||||
let event = unsafe {
|
||||
libc::malloc(::std::mem::size_of::<xlib::XAnyEvent>()) 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
|
||||
|
|
|
@ -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<Self> {
|
||||
Ok(Event {
|
||||
inner: event,
|
||||
kind: EventKind::None,
|
||||
})
|
||||
pub(super) unsafe fn from_raw(event: *mut xlib::XEvent) -> Result<Self> {
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue