mirror of
https://github.com/crossterm-rs/crossterm.git
synced 2025-09-27 13:01:23 +00:00
97 lines
3.2 KiB
Rust
97 lines
3.2 KiB
Rust
use std::time::Duration;
|
|
|
|
use crossterm_winapi::{Console, Handle, InputRecord};
|
|
|
|
use crate::event::{
|
|
sys::windows::{parse::MouseButtonsPressed, poll::WinApiPoll},
|
|
Event,
|
|
};
|
|
|
|
#[cfg(feature = "event-stream")]
|
|
use super::super::sys::Waker;
|
|
use super::super::{
|
|
source::EventSource,
|
|
sys::windows::parse::{handle_key_event, handle_mouse_event},
|
|
timeout::PollTimeout,
|
|
InternalEvent, Result,
|
|
};
|
|
|
|
pub(crate) struct WindowsEventSource {
|
|
console: Console,
|
|
poll: WinApiPoll,
|
|
surrogate_buffer: Option<u16>,
|
|
mouse_buttons_pressed: MouseButtonsPressed,
|
|
}
|
|
|
|
impl WindowsEventSource {
|
|
pub(crate) fn new() -> Result<WindowsEventSource> {
|
|
let console = Console::from(Handle::current_in_handle()?);
|
|
Ok(WindowsEventSource {
|
|
console,
|
|
|
|
#[cfg(not(feature = "event-stream"))]
|
|
poll: WinApiPoll::new(),
|
|
#[cfg(feature = "event-stream")]
|
|
poll: WinApiPoll::new()?,
|
|
|
|
surrogate_buffer: None,
|
|
mouse_buttons_pressed: MouseButtonsPressed::default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl EventSource for WindowsEventSource {
|
|
fn try_read(&mut self, timeout: Option<Duration>) -> Result<Option<InternalEvent>> {
|
|
let poll_timeout = PollTimeout::new(timeout);
|
|
|
|
loop {
|
|
if let Some(event_ready) = self.poll.poll(poll_timeout.leftover())? {
|
|
let number = self.console.number_of_console_input_events()?;
|
|
if event_ready && number != 0 {
|
|
let event = match self.console.read_single_input_event()? {
|
|
InputRecord::KeyEvent(record) => {
|
|
handle_key_event(record, &mut self.surrogate_buffer)
|
|
}
|
|
InputRecord::MouseEvent(record) => {
|
|
let mouse_event =
|
|
handle_mouse_event(record, &self.mouse_buttons_pressed);
|
|
self.mouse_buttons_pressed = MouseButtonsPressed {
|
|
left: record.button_state.left_button(),
|
|
right: record.button_state.right_button(),
|
|
middle: record.button_state.middle_button(),
|
|
};
|
|
|
|
mouse_event
|
|
}
|
|
InputRecord::WindowBufferSizeEvent(record) => {
|
|
Some(Event::Resize(record.size.x as u16, record.size.y as u16))
|
|
}
|
|
InputRecord::FocusEvent(record) => {
|
|
let event = if record.set_focus {
|
|
Event::FocusGained
|
|
} else {
|
|
Event::FocusLost
|
|
};
|
|
Some(event)
|
|
}
|
|
_ => None,
|
|
};
|
|
|
|
if let Some(event) = event {
|
|
return Ok(Some(InternalEvent::Event(event)));
|
|
}
|
|
}
|
|
}
|
|
|
|
if poll_timeout.elapsed() {
|
|
return Ok(None);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "event-stream")]
|
|
fn waker(&self) -> Waker {
|
|
self.poll.waker()
|
|
}
|
|
}
|