Implemented ExecBlock command support.
This commit is contained in:
parent
d4b2353400
commit
4581e8972e
2 changed files with 69 additions and 48 deletions
|
@ -15,6 +15,8 @@ This program is inspired by [**xmacro**](https://github.com/Ortega-Dan/xmacroInc
|
|||
- [x] MotionNotify and button support
|
||||
- [ ] String typing support (Not too high priority, but I'll add it some time probably)
|
||||
- [ ] ExecBlock/ExecNoBlock support (not high priority)
|
||||
- [x] ExecBlock
|
||||
- [ ] ExecNoBlock
|
||||
- [x] Recording macros (xmacro like)
|
||||
- [x] Delay
|
||||
- [x] Keyboard actions
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use clap::Parser;
|
||||
use easymacros::x11_safe_wrapper::{Keysym, XDisplay};
|
||||
use std::ffi::CString;
|
||||
use std::process::exit;
|
||||
use std::process::{Command, exit};
|
||||
use std::time::Duration;
|
||||
use std::{fs, thread};
|
||||
use std::io::stdin;
|
||||
|
||||
/// Macro player module for easymacros. It's partially compatible with xmacro macros, with aim for full compatibility.
|
||||
#[derive(Parser, Debug)]
|
||||
|
@ -11,67 +12,39 @@ use std::{fs, thread};
|
|||
struct Args {
|
||||
/// The file that contains the macro to run.
|
||||
#[clap(value_parser, value_name = "input_file", value_hint = clap::ValueHint::FilePath)]
|
||||
input_file: std::path::PathBuf,
|
||||
input_file: Option<std::path::PathBuf>,
|
||||
/// Display to run the macro on. This uses the $DISPLAY environment variable by default.
|
||||
#[clap(short, long)]
|
||||
display: Option<String>,
|
||||
// xmacro compatibility, currently the only supported input format anyway
|
||||
// #[clap(long)]
|
||||
// xmacro: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
// let xmacro_mode = args.xmacro;
|
||||
|
||||
let input_file_contents =
|
||||
fs::read_to_string(args.input_file).expect("couldn't read macro file");
|
||||
let display = get_remote(args.display);
|
||||
|
||||
for instruction in input_file_contents.lines() {
|
||||
println!("Instruction: {}", instruction);
|
||||
let command: Vec<&str> = instruction.split(' ').collect();
|
||||
if let Some(input_file_path) = args.input_file {
|
||||
let input_file_contents = fs::read_to_string(input_file_path)
|
||||
.expect("Couldn't read macro file");
|
||||
|
||||
match command[0] {
|
||||
"Delay" => thread::sleep(Duration::from_millis(command[1].parse().unwrap())),
|
||||
"ButtonPress" => display.send_fake_buttonpress(command[1].parse().unwrap()),
|
||||
"ButtonRelease" => display.send_fake_buttonrelease(command[1].parse().unwrap()),
|
||||
"MotionNotify" => display
|
||||
.send_fake_motion_event(command[1].parse().unwrap(), command[2].parse().unwrap()),
|
||||
"KeyCodePress" => display.send_fake_keypress_from_code(command[1].parse().unwrap()),
|
||||
"KeyCodeRelease" => display.send_fake_keyrelease_from_code(command[1].parse().unwrap()),
|
||||
"KeySymPress" => display.send_fake_keypress_from_keysym(command[1].parse().unwrap()),
|
||||
"KeySymRelease" => {
|
||||
display.send_fake_keyrelease_from_keysym(command[1].parse().unwrap())
|
||||
}
|
||||
"KeySym" => {
|
||||
let key: Keysym = command[1].parse().unwrap();
|
||||
display.send_fake_keypress_from_keysym(key);
|
||||
display.send_fake_keyrelease_from_keysym(key);
|
||||
}
|
||||
"KeyStrPress" => {
|
||||
display.send_fake_keypress_from_string(CString::new(command[1]).unwrap().as_bytes())
|
||||
}
|
||||
"KeyStrRelease" => display
|
||||
.send_fake_keyrelease_from_string(CString::new(command[1]).unwrap().as_bytes()),
|
||||
"KeyStr" => {
|
||||
let keystring = CString::new(command[1]).unwrap();
|
||||
display.send_fake_keypress_from_string(keystring.as_bytes());
|
||||
display.send_fake_keyrelease_from_string(keystring.as_bytes());
|
||||
}
|
||||
"String" => {
|
||||
println!("Strings are currently not supported.");
|
||||
// for c in instruction[7..].chars() {
|
||||
// display.send_fake_keypress_from_string(CString::new(c.to_string()).unwrap().as_bytes());
|
||||
// display.send_fake_keyrelease_from_string(CString::new(c.to_string()).unwrap().as_bytes());
|
||||
// }
|
||||
}
|
||||
c => {
|
||||
panic!("Unknown command {}", c)
|
||||
}
|
||||
for instruction in input_file_contents.lines() {
|
||||
run_instruction(instruction, &display);
|
||||
}
|
||||
} else {
|
||||
let stdin = stdin();
|
||||
|
||||
loop {
|
||||
let mut line = String::new();
|
||||
stdin.read_line(&mut line).expect("Couldn't read line from stdin");
|
||||
// Without this it crashes because apparently it doesn't properly read the next input line?
|
||||
println!();
|
||||
line = line.trim().to_string();
|
||||
run_instruction(&*line, &display);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
display.close();
|
||||
}
|
||||
|
||||
|
@ -89,3 +62,49 @@ fn get_remote(display_name: Option<String>) -> XDisplay {
|
|||
|
||||
display
|
||||
}
|
||||
|
||||
fn run_instruction(instruction: &str, display: &XDisplay) {
|
||||
let instruction: Vec<&str> = instruction.split(' ').collect();
|
||||
|
||||
match instruction[0] {
|
||||
"Delay" => thread::sleep(Duration::from_millis(instruction[1].parse().unwrap())),
|
||||
"ButtonPress" => display.send_fake_buttonpress(instruction[1].parse().unwrap()),
|
||||
"ButtonRelease" => display.send_fake_buttonrelease(instruction[1].parse().unwrap()),
|
||||
"MotionNotify" => display
|
||||
.send_fake_motion_event(instruction[1].parse().unwrap(), instruction[2].parse().unwrap()),
|
||||
"KeyCodePress" => display.send_fake_keypress_from_code(instruction[1].parse().unwrap()),
|
||||
"KeyCodeRelease" => display.send_fake_keyrelease_from_code(instruction[1].parse().unwrap()),
|
||||
"KeySymPress" => display.send_fake_keypress_from_keysym(instruction[1].parse().unwrap()),
|
||||
"KeySymRelease" => {
|
||||
display.send_fake_keyrelease_from_keysym(instruction[1].parse().unwrap())
|
||||
}
|
||||
"KeySym" => {
|
||||
let key: Keysym = instruction[1].parse().unwrap();
|
||||
display.send_fake_keypress_from_keysym(key);
|
||||
display.send_fake_keyrelease_from_keysym(key);
|
||||
}
|
||||
"KeyStrPress" => {
|
||||
display.send_fake_keypress_from_string(CString::new(instruction[1]).unwrap().as_bytes())
|
||||
}
|
||||
"KeyStrRelease" => display
|
||||
.send_fake_keyrelease_from_string(CString::new(instruction[1]).unwrap().as_bytes()),
|
||||
"KeyStr" => {
|
||||
let keystring = CString::new(instruction[1]).unwrap();
|
||||
display.send_fake_keypress_from_string(keystring.as_bytes());
|
||||
display.send_fake_keyrelease_from_string(keystring.as_bytes());
|
||||
}
|
||||
"String" => {
|
||||
println!("Strings are currently not supported.");
|
||||
}
|
||||
"ExecBlock" => {
|
||||
let mut command = Command::new(instruction[1]);
|
||||
for arg in &instruction[2..] {
|
||||
command.arg(arg);
|
||||
}
|
||||
command.status();
|
||||
}
|
||||
c => {
|
||||
panic!("Unknown command {:?}", instruction)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue