extern crate x11;
use std::ptr;
pub use x11::xlib;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum KeyCode {
Esc,
Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Num0,
Minus,
Equals,
Q,
W,
E,
R,
T,
Y,
U,
I,
O,
P,
LeftBracket,
RightBracket,
A,
S,
D,
F,
G,
H,
J,
K,
L,
Semicolon,
Apostrophe,
Backtick,
Backslash,
Z,
X,
C,
V,
B,
N,
M,
Comma,
Period,
Slash,
Enter,
Space,
ShiftL,
ShiftR,
ControlL,
ControlR,
AltL,
AltR,
SuperL,
SuperR,
CapsLock,
Tab,
Backspace,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Print,
ScrollLock,
Pause,
Insert,
Delete,
Home,
End,
PageUp,
PageDown,
LeftArrow,
RightArrow,
UpArrow,
DownArrow,
NumLock,
KpEnter,
KpAdd,
KpSubtract,
KpMultiply,
KpDivide,
Kp0,
Kp1,
Kp2,
Kp3,
Kp4,
Kp5,
Kp6,
Kp7,
Kp8,
Kp9,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MouseButton {
Left,
Middle,
Right,
ScrollUp,
ScrollDown,
ScrollLeft,
ScrollRight,
ExtraButton1,
ExtraButton2,
}
impl KeyCode {
pub fn to_x11_keycode(&self) -> u8 {
match self {
KeyCode::Esc => 9,
KeyCode::Num1 => 10,
KeyCode::Num2 => 11,
KeyCode::Num3 => 12,
KeyCode::Num4 => 13,
KeyCode::Num5 => 14,
KeyCode::Num6 => 15,
KeyCode::Num7 => 16,
KeyCode::Num8 => 17,
KeyCode::Num9 => 18,
KeyCode::Num0 => 19,
KeyCode::Minus => 20,
KeyCode::Equals => 21,
KeyCode::Q => 24,
KeyCode::W => 25,
KeyCode::E => 26,
KeyCode::R => 27,
KeyCode::T => 28,
KeyCode::Y => 29,
KeyCode::U => 30,
KeyCode::I => 31,
KeyCode::O => 32,
KeyCode::P => 33,
KeyCode::LeftBracket => 34,
KeyCode::RightBracket => 35,
KeyCode::A => 38,
KeyCode::S => 39,
KeyCode::D => 40,
KeyCode::F => 41,
KeyCode::G => 42,
KeyCode::H => 43,
KeyCode::J => 44,
KeyCode::K => 45,
KeyCode::L => 46,
KeyCode::Semicolon => 47,
KeyCode::Apostrophe => 48,
KeyCode::Backtick => 49,
KeyCode::Backslash => 51,
KeyCode::Z => 52,
KeyCode::X => 53,
KeyCode::C => 54,
KeyCode::V => 55,
KeyCode::B => 56,
KeyCode::N => 57,
KeyCode::M => 58,
KeyCode::Comma => 59,
KeyCode::Period => 60,
KeyCode::Slash => 61,
KeyCode::Enter => 36,
KeyCode::Space => 65,
KeyCode::ShiftL => 50,
KeyCode::ShiftR => 62,
KeyCode::ControlL => 37,
KeyCode::ControlR => 105,
KeyCode::AltL => 64,
KeyCode::AltR => 108,
KeyCode::SuperL => 133,
KeyCode::SuperR => 134,
KeyCode::CapsLock => 66,
KeyCode::Tab => 23,
KeyCode::Backspace => 22,
KeyCode::F1 => 67,
KeyCode::F2 => 68,
KeyCode::F3 => 69,
KeyCode::F4 => 70,
KeyCode::F5 => 71,
KeyCode::F6 => 72,
KeyCode::F7 => 73,
KeyCode::F8 => 74,
KeyCode::F9 => 75,
KeyCode::F10 => 76,
KeyCode::F11 => 95,
KeyCode::F12 => 96,
KeyCode::Print => 107,
KeyCode::ScrollLock => 78,
KeyCode::Pause => 127,
KeyCode::Insert => 118,
KeyCode::Delete => 119,
KeyCode::Home => 110,
KeyCode::End => 115,
KeyCode::PageUp => 112,
KeyCode::PageDown => 117,
KeyCode::LeftArrow => 113,
KeyCode::RightArrow => 114,
KeyCode::UpArrow => 111,
KeyCode::DownArrow => 116,
KeyCode::NumLock => 77,
KeyCode::KpEnter => 104,
KeyCode::KpAdd => 86,
KeyCode::KpSubtract => 82,
KeyCode::KpMultiply => 63,
KeyCode::KpDivide => 106,
KeyCode::Kp0 => 90,
KeyCode::Kp1 => 87,
KeyCode::Kp2 => 88,
KeyCode::Kp3 => 89,
KeyCode::Kp4 => 83,
KeyCode::Kp5 => 84,
KeyCode::Kp6 => 85,
KeyCode::Kp7 => 79,
KeyCode::Kp8 => 80,
KeyCode::Kp9 => 81,
}
}
}
impl MouseButton {
pub fn to_x11_buttoncode(&self) -> u8 {
match self {
MouseButton::Left => 1,
MouseButton::Middle => 2,
MouseButton::Right => 3,
MouseButton::ScrollUp => 4,
MouseButton::ScrollDown => 5,
MouseButton::ScrollLeft => 6,
MouseButton::ScrollRight => 7,
MouseButton::ExtraButton1 => 8,
MouseButton::ExtraButton2 => 9,
}
}
}
pub fn getkey(kc: KeyCode) -> bool {
unsafe {
let display = xlib::XOpenDisplay(ptr::null());
if display.is_null() {
eprintln!("Unable to open X display");
return false;
}
let mut keys: [u8; 32] = [0; 32];
xlib::XQueryKeymap(display, keys.as_mut_ptr() as *mut i8);
let mut min_keycode: i32 = 0;
let mut max_keycode: i32 = 0;
xlib::XDisplayKeycodes(display, &mut min_keycode, &mut max_keycode);
let mut pressed_keys: Vec<u8> = Vec::new();
for keycode in min_keycode..=max_keycode {
let byte_index = (keycode / 8) as usize;
let bit_index = (keycode % 8) as usize;
if (keys[byte_index] & (1 << bit_index)) != 0 {
pressed_keys.push(keycode as u8);
}
}
xlib::XCloseDisplay(display);
pressed_keys.contains(&kc.to_x11_keycode())
}
}
pub fn getmousebutton(button: MouseButton) -> bool {
unsafe {
let display = xlib::XOpenDisplay(ptr::null());
if display.is_null() {
eprintln!("Unable to open X display");
return false;
}
let root = xlib::XDefaultRootWindow(display);
let mut root_return: xlib::Window = 0;
let mut child_return: xlib::Window = 0;
let mut root_x_return: i32 = 0;
let mut root_y_return: i32 = 0;
let mut win_x_return: i32 = 0;
let mut win_y_return: i32 = 0;
let mut mask_return: u32 = 0;
let status = xlib::XQueryPointer(
display,
root,
&mut root_return,
&mut child_return,
&mut root_x_return,
&mut root_y_return,
&mut win_x_return,
&mut win_y_return,
&mut mask_return,
);
if status == 0 {
eprintln!("XQueryPointer failed");
xlib::XCloseDisplay(display);
return false;
}
let mut pressed_buttons: Vec<u8> = Vec::new();
if mask_return & xlib::Button1Mask != 0 {
pressed_buttons.push(1);
}
if mask_return & xlib::Button2Mask != 0 {
pressed_buttons.push(2);
}
if mask_return & xlib::Button3Mask != 0 {
pressed_buttons.push(3);
}
if mask_return & xlib::Button4Mask != 0 {
pressed_buttons.push(4);
}
if mask_return & xlib::Button5Mask != 0 {
pressed_buttons.push(5);
}
if mask_return & xlib::Button5Mask != 0 {
pressed_buttons.push(6);
}
if mask_return & (1 << 8) != 0 { pressed_buttons.push(6);
}
if mask_return & (1 << 9) != 0 { pressed_buttons.push(7);
}
if mask_return & (1 << 10) != 0 { pressed_buttons.push(8);
}
if mask_return & (1 << 11) != 0 { pressed_buttons.push(9);
}
xlib::XCloseDisplay(display);
pressed_buttons.contains(&button.to_x11_buttoncode())
}
}