Implemented "String" playing! Should now be compatible with xmacro yay

This commit is contained in:
Schrottkatze 2022-07-03 16:52:53 +02:00
parent c695d803e0
commit e28a69d29e
5 changed files with 347 additions and 24 deletions

View file

@ -1,10 +1,12 @@
use clap::Parser;
use easymacros::x11_safe_wrapper::{Keysym, XDisplay};
use easymacros::x11_safe_wrapper::{Keysym, string_to_keysym, XDisplay};
use std::ffi::CString;
use std::process::{Command, exit};
use std::time::Duration;
use std::{fs, thread};
use std::io::stdin;
use x11::keysym::XK_Shift_L;
use easymacros::chartbl::CHARTBL;
/// Macro player module for easymacros. It's partially compatible with xmacro macros, with aim for full compatibility.
#[derive(Parser, Debug)]
@ -64,51 +66,84 @@ fn get_remote(display_name: Option<String>) -> XDisplay {
}
fn run_instruction(instruction: &str, dpy: &XDisplay) {
let instruction: Vec<&str> = instruction.split(' ').collect();
let instruction_split: Vec<&str> = instruction.split(' ').collect();
match instruction[0] {
"Delay" => thread::sleep(Duration::from_millis(instruction[1].parse().unwrap())),
"ButtonPress" => dpy.send_fake_buttonpress(instruction[1].parse().unwrap()),
"ButtonRelease" => dpy.send_fake_buttonrelease(instruction[1].parse().unwrap()),
match instruction_split[0] {
"Delay" => thread::sleep(Duration::from_millis(instruction_split[1].parse().unwrap())),
"ButtonPress" => dpy.send_fake_buttonpress(instruction_split[1].parse().unwrap()),
"ButtonRelease" => dpy.send_fake_buttonrelease(instruction_split[1].parse().unwrap()),
"MotionNotify" => dpy
.send_fake_motion_event(instruction[1].parse().unwrap(), instruction[2].parse().unwrap()),
"KeyCodePress" => dpy.send_fake_keypress_from_code(instruction[1].parse().unwrap()),
"KeyCodeRelease" => dpy.send_fake_keyrelease_from_code(instruction[1].parse().unwrap()),
"KeySymPress" => dpy.send_fake_keypress_from_keysym(instruction[1].parse().unwrap()),
.send_fake_motion_event(instruction_split[1].parse().unwrap(), instruction_split[2].parse().unwrap()),
"KeyCodePress" => dpy.send_fake_keypress_from_code(instruction_split[1].parse().unwrap()),
"KeyCodeRelease" => dpy.send_fake_keyrelease_from_code(instruction_split[1].parse().unwrap()),
"KeySymPress" => dpy.send_fake_keypress_from_keysym(instruction_split[1].parse().unwrap()),
"KeySymRelease" => {
dpy.send_fake_keyrelease_from_keysym(instruction[1].parse().unwrap())
dpy.send_fake_keyrelease_from_keysym(instruction_split[1].parse().unwrap())
}
"KeySym" => {
let key: Keysym = instruction[1].parse().unwrap();
let key: Keysym = instruction_split[1].parse().unwrap();
dpy.send_fake_keypress_from_keysym(key);
dpy.send_fake_keyrelease_from_keysym(key);
}
"KeyStrPress" => {
dpy.send_fake_keypress_from_string(CString::new(instruction[1]).unwrap().as_bytes())
dpy.send_fake_keypress_from_string(CString::new(instruction_split[1]).unwrap().as_bytes())
}
"KeyStrRelease" => dpy
.send_fake_keyrelease_from_string(CString::new(instruction[1]).unwrap().as_bytes()),
.send_fake_keyrelease_from_string(CString::new(instruction_split[1]).unwrap().as_bytes()),
"KeyStr" => {
let keystring = CString::new(instruction[1]).unwrap();
let keystring = CString::new(instruction_split[1]).unwrap();
dpy.send_fake_keypress_from_string(keystring.as_bytes());
dpy.send_fake_keyrelease_from_string(keystring.as_bytes());
}
"String" => {
println!("Strings are currently not supported.");
for c in instruction["String".len()+1..].chars() {
send_char(dpy, c);
}
}
"ExecBlock" | "ExecNoBlock" => {
let mut command = Command::new(instruction[1]);
for arg in &instruction[2..] {
let mut command = Command::new(instruction_split[1]);
for arg in &instruction_split[2..] {
command.arg(arg);
}
if instruction[0] == "ExecBlock" {
if instruction_split[0] == "ExecBlock" {
command.status();
} else {
command.spawn();
}
}
c => {
panic!("Unknown command {:?}", instruction)
panic!("Unknown command {:?}", instruction_split)
}
}
}
fn send_char(dpy: &XDisplay, c: char) {
let keysym = string_to_keysym(CHARTBL[c as usize].as_ref());
let keycode = dpy.keysym_to_keycode(keysym);
if keycode == 0 {
eprintln!("No keycode found for character '{}'", c);
return;
}
let map_ks = dpy.get_keyboard_mapping(keycode, 1);
if unsafe { map_ks[0] } == 0 {
eprintln!("XGetKeyboardMapping failed (keycode: {})", keycode);
return;
}
let (ks_lower, ks_upper) = dpy.convert_case(keysym);
let mut shift_needed = true;
if keysym == map_ks[0] && (keysym == ks_lower && keysym == ks_upper) {
shift_needed = false;
}
if keysym == ks_lower && keysym != ks_upper {
shift_needed = false;
}
if shift_needed { dpy.send_fake_keypress_from_keysym(XK_Shift_L as Keysym); }
dpy.send_fake_keypress_from_code(keycode);
dpy.send_fake_keyrelease_from_code(keycode);
if shift_needed { dpy.send_fake_keyrelease_from_keysym(XK_Shift_L as Keysym); }
}