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, mouse_buttons_pressed: MouseButtonsPressed, } impl WindowsEventSource { pub(crate) fn new() -> Result { 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) -> Result> { 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() } }