something probably

This commit is contained in:
2025-05-17 15:25:28 -04:00
parent 3d374d7578
commit d4d2896102
5 changed files with 36 additions and 191 deletions

View File

@@ -19,7 +19,6 @@ pub use windows_input::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Event { pub enum Event {
Key(KeyEvent), Key(KeyEvent),
Mouse(MouseEvent),
FocusGained, FocusGained,
FocusLost, FocusLost,
} }
@@ -46,20 +45,8 @@ pub enum KeyEvent {
Null, Null,
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] impl From<KeyEvent> for Event {
pub enum MouseEvent { fn from(value: KeyEvent) -> Self {
Press(MouseButton, u16, u16), Self::Key(value)
Release(u16, u16), }
Hold(u16, u16),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum MouseButton {
Left,
Right,
Middle,
WheelUp,
WheelDown,
WheelLeft,
WheelRight,
} }

View File

@@ -22,7 +22,6 @@ const TIOCGWINSZ: c_ulong = 0x4008_7468;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
const NCCS: usize = 0x14; const NCCS: usize = 0x14;
//
#[repr(C)] #[repr(C)]
#[derive(Default, Debug, Clone, Copy)] #[derive(Default, Debug, Clone, Copy)]
struct Winsize { struct Winsize {

View File

@@ -138,146 +138,10 @@ where
Some(Ok(b'H')) => Some(Event::Key(KeyEvent::Home)), Some(Ok(b'H')) => Some(Event::Key(KeyEvent::Home)),
Some(Ok(b'F')) => Some(Event::Key(KeyEvent::End)), Some(Ok(b'F')) => Some(Event::Key(KeyEvent::End)),
Some(Ok(b'Z')) => Some(Event::Key(KeyEvent::BackTab)), 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, _ => None,
} }
} }
fn try_parse_x10_mouse<I>(iter: &mut I) -> Option<Event>
where
I: Iterator<Item = io::Result<u8>>,
{
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<I>(iter: &mut I) -> Option<Event>
where
I: Iterator<Item = io::Result<u8>>,
{
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::<u16>().ok()?;
let cx = nums.next()?.parse::<u16>().ok()?;
let cy = nums.next()?.parse::<u16>().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<I>(c: u8, iter: &mut I) -> Option<Event>
where
I: Iterator<Item = io::Result<u8>>,
{
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<u16> = 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] #[test]
fn test_parse_utf8() { fn test_parse_utf8() {
let string = "abcéŷ¤£€ù%323"; let string = "abcéŷ¤£€ù%323";

View File

@@ -1,5 +1,4 @@
use std::io::{self, Stdin, Stdout}; use std::io;
use std::os::windows::io::RawHandle;
unsafe extern "system" { unsafe extern "system" {
fn GetStdHandle(std_handle: u32) -> usize; fn GetStdHandle(std_handle: u32) -> usize;

View File

@@ -13,19 +13,27 @@ struct InputRecord {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
union EventRecord { union EventRecord {
key_event: KeyEventRecord, key: KeyEventRecord,
mouse_event: MouseEventRecord, focus: FocusEventRecord,
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct KeyEventRecord { struct KeyEventRecord {
key_down: i32, key_down: i32,
repeat_count: u16,
virtual_key_code: u16, virtual_key_code: u16,
virtual_scan_code: u16,
u_char: CharUnion, u_char: CharUnion,
control_key_state: u32, control_key_state: u32,
} }
#[repr(C)]
#[derive(Copy, Clone)]
struct FocusEventRecord {
set_focus: i32,
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
union CharUnion { union CharUnion {
@@ -33,34 +41,16 @@ union CharUnion {
ascii_char: u8, 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" { unsafe extern "system" {
fn ReadConsoleInputW( fn ReadConsoleInputW(
h_console_input: usize, console_input: usize,
lp_buffer: *mut InputRecord, buffer: *mut InputRecord,
n_length: u32, length: u32,
lp_number_of_events_read: *mut u32, number_of_events_read: *mut u32,
) -> i32; ) -> i32;
fn WaitForMultipleObjects( fn WaitForSingleObject(
n_count: u32, handle: usize,
lp_handles: *mut usize, wait_time_ms: u32,
b_wait_all: i32,
dw_wait_time: u32,
) -> u32; ) -> u32;
} }
@@ -70,8 +60,7 @@ pub fn poll_input(timeout: Duration) -> io::Result<Event> {
let mut read = 0; let mut read = 0;
let wait_time_millis = timeout.as_millis() as u32; let wait_time_millis = timeout.as_millis() as u32;
let mut handles = [handle]; let result = unsafe { WaitForSingleObject(handle, wait_time_millis) };
let result = unsafe { WaitForMultipleObjects(1, handles.as_mut_ptr(), 0, wait_time_millis) };
// The function timed out // The function timed out
if result != 0 { if result != 0 {
@@ -83,14 +72,21 @@ pub fn poll_input(timeout: Duration) -> io::Result<Event> {
if result == 0 { if result == 0 {
return Err(io::Error::last_os_error())?; return Err(io::Error::last_os_error())?;
} }
if record.event_type == 1 { match record.event_type {
let key_event = unsafe { record.event.key_event }; 0x10 => { // Focus Event
if key_event.key_down == 0 { Err(io::ErrorKind::InvalidData.into())
return Ok(Event::Key(KeyEvent::Null)); },
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 { fn parse_key_event(event: &KeyEventRecord) -> KeyEvent {