diff --git a/src/bin/emrec.rs b/src/bin/emrec.rs new file mode 100644 index 0000000..78d025e --- /dev/null +++ b/src/bin/emrec.rs @@ -0,0 +1,63 @@ +use core::time; +use std::thread; + +use easymacros::xwrap::{display, key, screen}; + +use x11::xlib; + +use clap::Parser; + +/// Macro recording module for easymacros. Outputs are partially compatible with xmacro. +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + /// The file to record the macro to. Defaults to writing to stdout. + #[clap(value_parser, value_name = "output_file", value_hint = clap::ValueHint::FilePath)] + output_file: Option, + /// Display to run the macro on. This uses the $DISPLAY environment variable by default. + #[clap(short = 'D', long)] + display: Option, + /// Max Delay in milliseconds for macro delays + #[clap(short, long)] + max_delay: Option, + /// Allow delay capturing in recording output. If this flag is set, the program will ignore the max_delay. + #[clap(short, long)] + ignore_delay_capturing: bool, +} + +fn main() -> anyhow::Result<()> { + let args = Args::parse(); + + let mut display = + display::Display::open(args.display.clone()).expect("should be able to open to display"); + + let stop_key = get_stop_key(&mut display); + + dbg!(stop_key); + + Ok(()) +} + +fn get_stop_key(display: &mut display::Display) -> key::Key { + let root = display.default_root_window(); + + display + .grab_keyboard( + root, + false, + display::GrabMode::Sync, + display::GrabMode::Sync, + xlib::CurrentTime, + ) + .expect("keyboard should be available to be grabbed"); + + println!("Press the key you want to use to stop recording the macro."); + + let stop_key = loop { + display.allow_events(display::EventMode::SyncPointer, xlib::CurrentTime); + }; + + thread::sleep(time::Duration::from_secs(3)); + + todo!() +} diff --git a/src/xwrap/key.rs b/src/xwrap/key.rs new file mode 100644 index 0000000..83b6b28 --- /dev/null +++ b/src/xwrap/key.rs @@ -0,0 +1,39 @@ +use x11::xlib; + +use super::{display, error}; + +use anyhow::Result; + +pub use x11::keysym; + +/// Stores a keycode +#[derive(Debug)] +pub struct Key { + code: u32, +} + +impl Key { + /// Creates a `Key` from a keycode and its related display connection. + pub fn from_code(code: xlib::KeyCode, display: &display::Display) -> Result { + let valid_range = display.keycodes()?; + + if valid_range.contains(&code.into()) { + Ok(Key { code: code.into() }) + } else { + Err(error::XError::InvalidKeycodeError(code, valid_range).into()) + } + } + + /// Creates a `Key` from a keysym by converting it into a code internally. + pub fn from_keysym(keysym: xlib::KeySym, display: &display::Display) -> Result> { + let valid_range = display.keycodes()?; + + let code = unsafe { xlib::XKeysymToKeycode(display.ptr, keysym) }; + + Ok(if code == 0 { + None + } else { + Some(Key { code: code.into() }) + }) + } +} diff --git a/src/xwrap/screen.rs b/src/xwrap/screen.rs new file mode 100644 index 0000000..0a5a48c --- /dev/null +++ b/src/xwrap/screen.rs @@ -0,0 +1,15 @@ +use x11::xlib; + +use super::display; + +pub struct Screen { + pub(super) ptr: *mut xlib::Screen, +} + +impl Screen { + pub fn new(screen_nr: i32, display: &display::Display) -> Self { + Self { + ptr: unsafe { xlib::XScreenOfDisplay(display.ptr, screen_nr) }, + } + } +} diff --git a/src/xwrap/window.rs b/src/xwrap/window.rs new file mode 100644 index 0000000..4f4a9c0 --- /dev/null +++ b/src/xwrap/window.rs @@ -0,0 +1,5 @@ +use x11::xlib; + +pub struct Window { + pub(super) wid: xlib::Window, +}