diff --git a/src/bin/easymacroplay.rs b/src/bin/easymacroplay.rs index 03c18c0..239e06f 100644 --- a/src/bin/easymacroplay.rs +++ b/src/bin/easymacroplay.rs @@ -1,10 +1,14 @@ -use std::ffi::CString; -use std::os::raw::c_int; -use x11::xlib::{XCloseDisplay, XFlush, XOpenDisplay}; +use std::ffi::{CStr, CString}; +use std::os::raw::{c_char, c_int, c_uint}; +use std::process::exit; +use std::slice::from_raw_parts; +use std::thread; +use std::time::Duration; +use x11::xlib::{Display, XCloseDisplay, XDisplayString, XFlush, XKeysymToKeycode, XOpenDisplay, XStringToKeysym, XSync}; use easymacros::add; use clap::Parser; use x11::keysym::{XK_d, XK_Super_L}; -use x11::xtest::{XTestFakeButtonEvent, XTestFakeKeyEvent, XTestFakeMotionEvent, XTestGrabControl}; +use x11::xtest::{XTestFakeButtonEvent, XTestFakeKeyEvent, XTestFakeMotionEvent, XTestGrabControl, XTestQueryExtension}; use x11_keysymdef::lookup_by_name; /// Macro program inspired by xmacro. @@ -19,41 +23,52 @@ struct Args { fn main () { let args = Args::parse(); - // let display_ptr = args.display.as_bytes().as_ptr() as *const i8; - println!("Display name: {}", args.display); - let display_name = CString::new(args.display).unwrap(); - println!("Display name cstr: {:?}", display_name); - let display_ptr: *const u8 = display_name.as_bytes().as_ptr(); - println!("Display name ptr: {:?}", display_ptr); - let display = unsafe { XOpenDisplay(display_ptr as *const i8) }; - println!("Display name ptr: {:?}", display); + let display = get_remote(args.display); - let super_l = lookup_by_name("Super_L").unwrap(); - let d = lookup_by_name("d").unwrap(); + let super_l_str_ptr = b"Super_L\0".as_ptr(); + let super_l_sym = unsafe { XStringToKeysym(super_l_str_ptr as *const i8) }; + let super_l_code = unsafe { XKeysymToKeycode(display, super_l_sym) }; + + let d_str_ptr = b"d\0".as_ptr(); + let d_sym = unsafe { XStringToKeysym(d_str_ptr as *const i8) }; + let d_code = unsafe { XKeysymToKeycode(display, d_sym) }; unsafe { - // XTestFakeKeyEvent(display, super_l.keysym, 1, 0); - // XTestFakeKeyEvent(display, d.keysym, 1, 10); - // - // XTestFakeKeyEvent(display, d.keysym, 0, 20); - // XTestFakeKeyEvent(display, super_l.keysym, 0, 30); - XTestGrabControl(display, c_int::from(false)); - XTestFakeKeyEvent(display, XK_Super_L, c_int::from(true), 0); + XTestFakeKeyEvent(display, super_l_code as c_uint, c_int::from(true), 10); XFlush(display); - XTestFakeKeyEvent(display, XK_d, c_int::from(true), 0); - XFlush(display); - XTestFakeKeyEvent(display, XK_d, c_int::from(false), 0); - XFlush(display); - XTestFakeKeyEvent(display, XK_Super_L, c_int::from(false), 0); + XTestFakeKeyEvent(display, d_code as c_uint, c_int::from(true), 10); XFlush(display); - XTestFakeMotionEvent(display, -1, 200, 200, 0); + XTestFakeKeyEvent(display, d_code as c_uint, c_int::from(false), 10); + XFlush(display); + XTestFakeKeyEvent(display, super_l_code as c_uint, c_int::from(false), 10); XFlush(display); XCloseDisplay(display); } - println!("play: {}", add(5, 10)); } +fn get_remote(dpy_name: String) -> *mut Display { + let dpy_name = CString::new(dpy_name).unwrap(); + let display_ptr: *const u8 = dpy_name.as_bytes().as_ptr(); + let display = unsafe { XOpenDisplay(display_ptr as *const i8) }; + + let mut ev = c_int::default(); + let mut err = c_int::default(); + let mut version = (c_int::default(), c_int::default()); + + if unsafe { XTestQueryExtension(display, &mut ev, &mut err, &mut version.0, &mut version.1) } == 0 { + eprintln!("XTest not supported!"); + unsafe { XCloseDisplay(display) }; + exit(1) + } + + unsafe { + XTestGrabControl(display, c_int::from(true)); + XSync(display, c_int::from(false)); + }; + + display +}