diff --git a/src/input.rs b/src/input.rs index b6cd9fa..a33c833 100644 --- a/src/input.rs +++ b/src/input.rs @@ -19,7 +19,6 @@ pub use windows_input::*; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum Event { Key(KeyEvent), - Mouse(MouseEvent), FocusGained, FocusLost, } @@ -46,20 +45,8 @@ pub enum KeyEvent { Null, } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum MouseEvent { - Press(MouseButton, u16, u16), - Release(u16, u16), - Hold(u16, u16), -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum MouseButton { - Left, - Right, - Middle, - WheelUp, - WheelDown, - WheelLeft, - WheelRight, +impl From for Event { + fn from(value: KeyEvent) -> Self { + Self::Key(value) + } } diff --git a/src/unix.rs b/src/unix.rs index fa799fd..f8df7d1 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -22,7 +22,6 @@ const TIOCGWINSZ: c_ulong = 0x4008_7468; #[cfg(target_os = "macos")] const NCCS: usize = 0x14; -// #[repr(C)] #[derive(Default, Debug, Clone, Copy)] struct Winsize { diff --git a/src/unix_input.rs b/src/unix_input.rs index dca16e4..1614f87 100644 --- a/src/unix_input.rs +++ b/src/unix_input.rs @@ -138,146 +138,10 @@ where Some(Ok(b'H')) => Some(Event::Key(KeyEvent::Home)), Some(Ok(b'F')) => Some(Event::Key(KeyEvent::End)), Some(Ok(b'Z')) => Some(Event::Key(KeyEvent::BackTab)), - Some(Ok(b'M')) => try_parse_x10_mouse(iter), - Some(Ok(b'<')) => try_parse_xterm_mouse(iter), - Some(Ok(c @ b'0'..=b'9')) => try_parse_rxvt_mouse(c, iter), _ => None, } } -fn try_parse_x10_mouse(iter: &mut I) -> Option -where - I: Iterator>, -{ - let cb = iter.next()?.ok()? - 32; - - let cx = u16::from(iter.next()?.ok()?.saturating_sub(33)); - let cy = u16::from(iter.next()?.ok()?.saturating_sub(33)); - match cb & 0x11 { - 0 => { - if cb & 0x40 != 0 { - Some(Event::Mouse(MouseEvent::Press( - MouseButton::WheelUp, - cx, - cy, - ))) - } else { - Some(Event::Mouse(MouseEvent::Press(MouseButton::Left, cx, cy))) - } - } - 1 => { - if cb & 0x40 != 0 { - Some(Event::Mouse(MouseEvent::Press( - MouseButton::WheelDown, - cx, - cy, - ))) - } else { - Some(Event::Mouse(MouseEvent::Press(MouseButton::Middle, cx, cy))) - } - } - 2 => { - if cb & 0x40 != 0 { - Some(Event::Mouse(MouseEvent::Press( - MouseButton::WheelLeft, - cx, - cy, - ))) - } else { - Some(Event::Mouse(MouseEvent::Press(MouseButton::Right, cx, cy))) - } - } - 3 => { - if cb & 0x40 != 0 { - Some(Event::Mouse(MouseEvent::Press( - MouseButton::WheelRight, - cx, - cy, - ))) - } else { - Some(Event::Mouse(MouseEvent::Release(cx, cy))) - } - } - _ => None, - } -} - -fn try_parse_xterm_mouse(iter: &mut I) -> Option -where - I: Iterator>, -{ - let mut buf = Vec::new(); - let mut character = iter.next()?.ok()?; - while !matches!(character, b'm' | b'M') { - buf.push(character); - character = iter.next()?.ok()?; - } - let str_buf = String::from_utf8(buf).ok()?; - let nums = &mut str_buf.split(';'); - - let cb = nums.next()?.parse::().ok()?; - - let cx = nums.next()?.parse::().ok()?; - let cy = nums.next()?.parse::().ok()?; - - let event = match cb { - 0..=2 | 64..=67 => { - let button = match cb { - 0 => MouseButton::Left, - 1 => MouseButton::Middle, - 2 => MouseButton::Right, - 64 => MouseButton::WheelUp, - 65 => MouseButton::WheelDown, - 66 => MouseButton::WheelLeft, - 67 => MouseButton::WheelRight, - _ => unreachable!(), - }; - match character { - b'M' => MouseEvent::Press(button, cx, cy), - b'm' => MouseEvent::Release(cx, cy), - _ => return None, - } - } - 32 | 3 => MouseEvent::Hold(cx, cy), - _ => return None, - }; - Some(Event::Mouse(event)) -} - -fn try_parse_rxvt_mouse(c: u8, iter: &mut I) -> Option -where - I: Iterator>, -{ - let mut buf = vec![c]; - let mut c = iter.next()?.ok()?; - while !(64..=126).contains(&c) { - buf.push(c); - c = iter.next()?.ok()?; - } - if c == b'M' { - let str_buf = String::from_utf8(buf).ok()?; - - let nums: Vec = str_buf.split(';').map(|n| n.parse().unwrap()).collect(); - - let cb = nums[0]; - let cx = nums[1]; - let cy = nums[2]; - - let event = match cb { - 32 => MouseEvent::Press(MouseButton::Left, cx, cy), - 33 => MouseEvent::Press(MouseButton::Middle, cx, cy), - 34 => MouseEvent::Press(MouseButton::Right, cx, cy), - 35 => MouseEvent::Release(cx, cy), - 64 => MouseEvent::Hold(cx, cy), - 96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy), - _ => return None, - }; - - return Some(Event::Mouse(event)); - } - None -} - #[test] fn test_parse_utf8() { let string = "abcéŷ¤£€ù%323"; diff --git a/src/windows.rs b/src/windows.rs index 4ba4dcf..74b11fa 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -1,5 +1,4 @@ -use std::io::{self, Stdin, Stdout}; -use std::os::windows::io::RawHandle; +use std::io; unsafe extern "system" { fn GetStdHandle(std_handle: u32) -> usize; diff --git a/src/windows_input.rs b/src/windows_input.rs index 7583a92..b02ec4b 100644 --- a/src/windows_input.rs +++ b/src/windows_input.rs @@ -13,19 +13,27 @@ struct InputRecord { #[repr(C)] #[derive(Copy, Clone)] union EventRecord { - key_event: KeyEventRecord, - mouse_event: MouseEventRecord, + key: KeyEventRecord, + focus: FocusEventRecord, } #[repr(C)] #[derive(Copy, Clone)] struct KeyEventRecord { key_down: i32, + repeat_count: u16, virtual_key_code: u16, + virtual_scan_code: u16, u_char: CharUnion, control_key_state: u32, } +#[repr(C)] +#[derive(Copy, Clone)] +struct FocusEventRecord { + set_focus: i32, +} + #[repr(C)] #[derive(Copy, Clone)] union CharUnion { @@ -33,34 +41,16 @@ union CharUnion { ascii_char: u8, } -#[repr(C)] -#[derive(Copy, Clone)] -struct MouseEventRecord { - mouse_position: Coord, - button_state: u32, - control_key_state: u32, - event_flags: u32, -} - -#[repr(C)] -#[derive(Copy, Clone)] -struct Coord { - x: i16, - y: i16, -} - unsafe extern "system" { fn ReadConsoleInputW( - h_console_input: usize, - lp_buffer: *mut InputRecord, - n_length: u32, - lp_number_of_events_read: *mut u32, + console_input: usize, + buffer: *mut InputRecord, + length: u32, + number_of_events_read: *mut u32, ) -> i32; - fn WaitForMultipleObjects( - n_count: u32, - lp_handles: *mut usize, - b_wait_all: i32, - dw_wait_time: u32, + fn WaitForSingleObject( + handle: usize, + wait_time_ms: u32, ) -> u32; } @@ -70,8 +60,7 @@ pub fn poll_input(timeout: Duration) -> io::Result { let mut read = 0; let wait_time_millis = timeout.as_millis() as u32; - let mut handles = [handle]; - let result = unsafe { WaitForMultipleObjects(1, handles.as_mut_ptr(), 0, wait_time_millis) }; + let result = unsafe { WaitForSingleObject(handle, wait_time_millis) }; // The function timed out if result != 0 { @@ -83,14 +72,21 @@ pub fn poll_input(timeout: Duration) -> io::Result { if result == 0 { return Err(io::Error::last_os_error())?; } - if record.event_type == 1 { - let key_event = unsafe { record.event.key_event }; - if key_event.key_down == 0 { - return Ok(Event::Key(KeyEvent::Null)); + match record.event_type { + 0x10 => { // Focus Event + Err(io::ErrorKind::InvalidData.into()) + }, + 0x1 => { // Key Event + let key_event: KeyEventRecord = unsafe { record.event.key }; + if key_event.key_down == 0 { + return Ok(Event::Key(KeyEvent::Null)); + } + Ok(Event::Key(parse_key_event(&key_event))) + }, + _ => { //TODO Make this better + Err(io::ErrorKind::InvalidData.into()) } - return Ok(Event::Key(parse_key_event(&key_event))); } - Err(io::ErrorKind::InvalidData.into()) } fn parse_key_event(event: &KeyEventRecord) -> KeyEvent {