update
This commit is contained in:
parent
0e34bffc86
commit
f96529bcc7
3 changed files with 207 additions and 9 deletions
94
Cargo.lock
generated
94
Cargo.lock
generated
|
@ -42,6 +42,19 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
|
@ -119,12 +132,30 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dmenu_facade"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "372af688af899981cb3d9d0b23de762c906d6367325d3a7304f7ad90c4b74d0f"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide 0.4.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.1"
|
||||
|
@ -144,6 +175,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.12"
|
||||
|
@ -282,6 +319,21 @@ dependencies = [
|
|||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "procfs"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"flate2",
|
||||
"hex",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.0"
|
||||
|
@ -323,7 +375,10 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
name = "shutter-rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"dmenu_facade",
|
||||
"image",
|
||||
"procfs",
|
||||
"x11",
|
||||
]
|
||||
|
||||
|
@ -338,12 +393,51 @@ dependencies = [
|
|||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2bb9fc8309084dd7cd651336673844c1d47f8ef6d2091ec160b27f5c4aa277"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "x11"
|
||||
version = "2.18.2"
|
||||
|
|
|
@ -8,4 +8,7 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
image = "0.23.12"
|
||||
x11 = { version = "2.18", features = [ "xlib", "xss" ] }
|
||||
x11 = { version = "2.18", features = [ "xlib" ] }
|
||||
dmenu_facade = "0.3.0"
|
||||
chrono = "0.4.19"
|
||||
procfs = "0.9.1"
|
||||
|
|
115
src/main.rs
115
src/main.rs
|
@ -1,7 +1,12 @@
|
|||
use dmenu_facade::*;
|
||||
use x11::xlib;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::{c_int,c_ulong,c_uchar};
|
||||
use image::{RgbaImage};
|
||||
use std::convert::TryInto;
|
||||
use std::process::{Stdio,Command};
|
||||
use std::ffi::{CStr,CString};
|
||||
use chrono::{DateTime, Local, SecondsFormat};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Position {
|
||||
|
@ -11,8 +16,85 @@ struct Position {
|
|||
width: u32,
|
||||
}
|
||||
|
||||
fn get_focus_win_name() -> String {
|
||||
unsafe {
|
||||
let display: *mut xlib::Display = xlib::XOpenDisplay(std::ptr::null());
|
||||
|
||||
let mut revert_to_ret: MaybeUninit<c_int> = MaybeUninit::uninit();
|
||||
let mut window: MaybeUninit<c_ulong> = MaybeUninit::uninit();
|
||||
let mut text: MaybeUninit<xlib::XTextProperty> = MaybeUninit::uninit();
|
||||
|
||||
xlib::XGetInputFocus(display, window.as_mut_ptr(), revert_to_ret.as_mut_ptr());
|
||||
let mut window = window.assume_init();
|
||||
|
||||
xlib::XGetWMName(display, window, text.as_mut_ptr());
|
||||
|
||||
let mut text = text.assume_init();
|
||||
let c_str = CStr::from_ptr(text.value as *mut i8);
|
||||
let str_slice = c_str.to_str().unwrap();
|
||||
|
||||
xlib::XCloseDisplay(display);
|
||||
|
||||
str_slice.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_wm_win_pid() -> Option<u64> {
|
||||
|
||||
unsafe {
|
||||
let display: *mut xlib::Display = xlib::XOpenDisplay(std::ptr::null());
|
||||
|
||||
let mut revert_to_ret: MaybeUninit<c_int> = MaybeUninit::uninit();
|
||||
let mut window: MaybeUninit<c_ulong> = MaybeUninit::uninit();
|
||||
let mut text: MaybeUninit<xlib::XTextProperty> = MaybeUninit::uninit();
|
||||
|
||||
xlib::XGetInputFocus(display, window.as_mut_ptr(), revert_to_ret.as_mut_ptr());
|
||||
let mut window = window.assume_init();
|
||||
|
||||
let pid_str = CString::new("_NET_WM_PID").unwrap();
|
||||
let atom = xlib::XInternAtom(display, pid_str.as_ptr() as *const i8, 0);
|
||||
|
||||
let mut retrieved_atom: MaybeUninit<c_ulong> = MaybeUninit::uninit();
|
||||
let mut format: MaybeUninit<c_int> = MaybeUninit::uninit();
|
||||
let mut n_items: MaybeUninit<c_ulong> = MaybeUninit::uninit();
|
||||
let mut bytes_after: MaybeUninit<c_ulong> = MaybeUninit::uninit();
|
||||
let mut ptr: *mut c_uchar = 0 as *mut c_uchar;
|
||||
|
||||
if xlib::XGetWindowProperty(display, window, atom, 0, 1, 0, xlib::XA_CARDINAL,
|
||||
retrieved_atom.as_mut_ptr(),
|
||||
format.as_mut_ptr(),
|
||||
n_items.as_mut_ptr(),
|
||||
bytes_after.as_mut_ptr(),
|
||||
&mut ptr) == 0 {
|
||||
let t = ptr as *mut c_ulong;
|
||||
Some(*t)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_process_name() -> Option<String> {
|
||||
let pid = get_wm_win_pid()?;
|
||||
let p = procfs::process::Process::new(pid as i32).unwrap();
|
||||
Some(String::from(p.exe().unwrap().file_name()?.to_str()?))
|
||||
}
|
||||
|
||||
fn get_name_proposals() -> Vec<String> {
|
||||
let now: DateTime<Local> = Local::now();
|
||||
let formatted_now = now.format("%F %T");
|
||||
let mut window_name = get_focus_win_name();
|
||||
let process_name = get_process_name().unwrap();
|
||||
window_name.truncate(10);
|
||||
|
||||
vec!(format!("{}.png", formatted_now),
|
||||
format!("{} ({}).png", formatted_now, window_name),
|
||||
format!("{} ({}).png", formatted_now, process_name))
|
||||
}
|
||||
|
||||
fn screenshot(pos: &Position) {
|
||||
let len: usize = (pos.height as usize)*(pos.width as usize)*4;
|
||||
|
||||
let mut data: Vec<u8> = unsafe {
|
||||
let display: *mut xlib::Display = xlib::XOpenDisplay(std::ptr::null());
|
||||
let root_window = xlib::XDefaultRootWindow(display);
|
||||
|
@ -25,18 +107,20 @@ fn screenshot(pos: &Position) {
|
|||
pos.height,
|
||||
xlib::XAllPlanes(),
|
||||
xlib::ZPixmap);
|
||||
|
||||
Vec::<u8>::from_raw_parts((*ximg).data as *mut _, len, len)
|
||||
};
|
||||
|
||||
let mut c = 0;
|
||||
|
||||
while c < len {
|
||||
// for some reason, instead of storing RGBA data, x11 store BGRA data,
|
||||
// we need to fix that before passing that to image lib
|
||||
data.swap(c,c+2);
|
||||
c+=4;
|
||||
}
|
||||
|
||||
let img = RgbaImage::from_raw(pos.width, pos.height, data).unwrap();
|
||||
|
||||
img.save("empty.png").unwrap();
|
||||
}
|
||||
|
||||
|
@ -86,6 +170,7 @@ fn select_zone() -> Option<Position> {
|
|||
dash_offset: 0,
|
||||
dashes: 0,
|
||||
};
|
||||
|
||||
let gcv_mask = xlib::GCSubwindowMode | xlib::GCLineWidth | xlib::GCForeground | xlib::GCFunction;
|
||||
|
||||
let mut old_coord = (0,0);
|
||||
|
@ -96,8 +181,8 @@ fn select_zone() -> Option<Position> {
|
|||
loop {
|
||||
while xlib::XPending(display) > 0 {
|
||||
let mut e: MaybeUninit<xlib::XEvent> = MaybeUninit::uninit();
|
||||
xlib::XNextEvent(display, e.as_mut_ptr());
|
||||
|
||||
xlib::XNextEvent(display, e.as_mut_ptr());
|
||||
let event = e.assume_init();
|
||||
|
||||
match event.type_ {
|
||||
|
@ -146,6 +231,7 @@ fn select_zone() -> Option<Position> {
|
|||
|
||||
xlib::XDrawRectangle(display, root_window, gc, pos.origin_x, pos.origin_y, pos.width, pos.height);
|
||||
xlib::XFlush(display);
|
||||
xlib::XCloseDisplay(display);
|
||||
return Some(pos);
|
||||
}
|
||||
_ => { println!("type unknown: {}", event.type_); }
|
||||
|
@ -158,10 +244,25 @@ fn select_zone() -> Option<Position> {
|
|||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = select_zone();
|
||||
println!("{:?}", s);
|
||||
if let Some(select) = s {
|
||||
screenshot(&select);
|
||||
fn show_interactive_menu() {
|
||||
let items = vec!["test", "test2"];
|
||||
let chosen = DMenu::default()
|
||||
.execute(&items);
|
||||
//Prints selected item to stdout
|
||||
if let Ok(item) = chosen {
|
||||
println!("{}", item);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
/*let a = get_focus_win_name();
|
||||
println!("{:?}", get_name_proposals());
|
||||
println!("{:?}", get_wm_win_pid());
|
||||
println!("{:?}", get_process_name());*/
|
||||
//let s = select_zone();
|
||||
//println!("{:?}", s);
|
||||
//if let Some(select) = s {
|
||||
// screenshot(&select);
|
||||
//}
|
||||
show_interactive_menu();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue