1 use std::time::Duration; 2 3 use crossterm_winapi::{Console, Handle, InputRecord}; 4 5 use crate::event::{sys::windows::poll::WinApiPoll, Event}; 6 7 #[cfg(feature = "event-stream")] 8 use super::super::sys::Waker; 9 use super::super::{ 10 source::EventSource, 11 sys::windows::parse::{handle_key_event, handle_mouse_event}, 12 timeout::PollTimeout, 13 InternalEvent, Result, 14 }; 15 16 pub(crate) struct WindowsEventSource { 17 console: Console, 18 poll: WinApiPoll, 19 } 20 21 impl WindowsEventSource { new() -> Result<WindowsEventSource>22 pub(crate) fn new() -> Result<WindowsEventSource> { 23 let console = Console::from(Handle::current_in_handle()?); 24 Ok(WindowsEventSource { 25 console, 26 poll: WinApiPoll::new()?, 27 }) 28 } 29 } 30 31 impl EventSource for WindowsEventSource { try_read(&mut self, timeout: Option<Duration>) -> Result<Option<InternalEvent>>32 fn try_read(&mut self, timeout: Option<Duration>) -> Result<Option<InternalEvent>> { 33 let poll_timeout = PollTimeout::new(timeout); 34 35 loop { 36 if let Some(event_ready) = self.poll.poll(poll_timeout.leftover())? { 37 if event_ready && self.console.number_of_console_input_events()? != 0 { 38 let event = match self.console.read_single_input_event()? { 39 InputRecord::KeyEvent(record) => handle_key_event(record)?, 40 InputRecord::MouseEvent(record) => handle_mouse_event(record)?, 41 InputRecord::WindowBufferSizeEvent(record) => { 42 Some(Event::Resize(record.size.x as u16, record.size.y as u16)) 43 } 44 _ => None, 45 }; 46 47 if let Some(event) = event { 48 return Ok(Some(InternalEvent::Event(event))); 49 } 50 } 51 } 52 53 if poll_timeout.elapsed() { 54 return Ok(None); 55 } 56 } 57 } 58 59 #[cfg(feature = "event-stream")] waker(&self) -> Waker60 fn waker(&self) -> Waker { 61 self.poll.waker() 62 } 63 } 64