win32console/structs/
input_event.rs1use crate::structs::coord::Coord;
2use winapi::um::wincon::{FROM_LEFT_1ST_BUTTON_PRESSED, FROM_LEFT_2ND_BUTTON_PRESSED, FROM_LEFT_3RD_BUTTON_PRESSED, FROM_LEFT_4TH_BUTTON_PRESSED, KEY_EVENT_RECORD, MOUSE_EVENT_RECORD, RIGHTMOST_BUTTON_PRESSED};
3use std::convert::TryFrom;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10pub struct KeyEventRecord {
11 pub key_down: bool,
14 pub repeat_count: u16,
19 pub virtual_key_code: u16,
22 pub virtual_scan_code: u16,
25 pub u_char: char,
27 pub control_key_state: ControlKeyState,
29}
30
31#[derive(Debug, Copy, Clone, PartialEq, Eq)]
36pub struct MouseEventRecord {
37 pub mouse_position: Coord,
39 pub button_state: ButtonState,
45 pub control_key_state: ControlKeyState,
47 pub event_flags: EventFlags,
50}
51
52#[derive(Debug, Copy, Clone, PartialEq, Eq)]
56pub struct ButtonState(i32);
57
58#[derive(Debug, Copy, Clone, PartialEq, Eq)]
62pub struct ControlKeyState(u32);
63
64#[repr(u32)]
68#[derive(Debug, Copy, Clone, PartialEq, Eq)]
69pub enum EventFlags {
70 PressOrRelease = 0x0000,
72 MouseMoved = 0x0001,
75 DoubleClick = 0x0002,
78 MouseWheeled = 0x0004,
84 MouseHwheeled = 0x0008,
86}
87
88impl ControlKeyState {
89 pub const RIGHT_ALT_PRESSED: u32 = 0x0001;
91 pub const LEFT_ALT_PRESSED: u32 = 0x0002;
93 pub const RIGHT_CTRL_PRESSED: u32 = 0x0004;
95 pub const LEFT_CTRL_PRESSED: u32 = 0x0008;
97 pub const SHIFT_PRESSED: u32 = 0x0010;
99 pub const NUM_LOCK_ON: u32 = 0x0020;
101 pub const SCROLL_LOCK_ON: u32 = 0x0040;
103 pub const CAPS_LOCK_ON: u32 = 0x0080;
105 pub const ENHANCED_KEY: u32 = 0x0100;
107
108 #[inline]
110 pub fn new(state: u32) -> Self{
111 ControlKeyState(state)
112 }
113
114 #[inline]
138 pub fn has_state(&self, state: u32) -> bool {
139 (state & self.0) != 0
140 }
141
142 #[inline]
143 pub fn get_state(&self) -> u32 {
144 self.0
145 }
146
147 #[inline]
148 pub fn is_alt_pressed(&self) -> bool {
149 self.has_state(ControlKeyState::RIGHT_ALT_PRESSED)
150 || self.has_state(ControlKeyState::LEFT_ALT_PRESSED)
151 }
152
153 #[inline]
154 pub fn is_ctrl_pressed(&self) -> bool {
155 self.has_state(ControlKeyState::RIGHT_CTRL_PRESSED)
156 || self.has_state(ControlKeyState::LEFT_CTRL_PRESSED)
157 }
158
159 #[inline]
160 pub fn is_shift_pressed(&self) -> bool {
161 self.has_state(ControlKeyState::SHIFT_PRESSED)
162 }
163
164 #[inline]
165 pub fn is_num_lock_on(&self) -> bool {
166 self.has_state(ControlKeyState::NUM_LOCK_ON)
167 }
168
169 #[inline]
170 pub fn is_caps_lock_on(&self) -> bool {
171 self.has_state(ControlKeyState::CAPS_LOCK_ON)
172 }
173
174 #[inline]
175 pub fn is_scroll_lock_on(&self) -> bool {
176 self.has_state(ControlKeyState::SCROLL_LOCK_ON)
177 }
178
179 #[inline]
180 pub fn is_enhanced_key(&self) -> bool {
181 self.has_state(ControlKeyState::ENHANCED_KEY)
182 }
183}
184
185impl ButtonState {
186 #[inline]
188 pub fn release_button(&self) -> bool {
189 self.0 == 0
190 }
191
192 #[inline]
194 pub fn left_button(&self) -> bool {
195 self.0 as u32 & FROM_LEFT_1ST_BUTTON_PRESSED != 0
196 }
197
198 #[inline]
200 pub fn right_button(&self) -> bool {
201 self.0 as u32
202 & (RIGHTMOST_BUTTON_PRESSED
203 | FROM_LEFT_3RD_BUTTON_PRESSED
204 | FROM_LEFT_4TH_BUTTON_PRESSED)
205 != 0
206 }
207
208 #[inline]
210 pub fn middle_button(&self) -> bool {
211 self.0 as u32 & FROM_LEFT_2ND_BUTTON_PRESSED != 0
212 }
213
214 #[inline]
216 pub fn scroll_down(&self) -> bool {
217 self.0 < 0
218 }
219
220 #[inline]
222 pub fn scroll_up(&self) -> bool {
223 self.0 > 0
224 }
225
226 #[inline]
228 pub fn get_state(&self) -> i32 {
229 self.0
230 }
231}
232
233impl Into<KEY_EVENT_RECORD> for KeyEventRecord{
234 fn into(self) -> KEY_EVENT_RECORD {
235 KEY_EVENT_RECORD{
236 bKeyDown: self.key_down.into(),
237 wRepeatCount: self.repeat_count,
238 wVirtualKeyCode: self.virtual_key_code,
239 wVirtualScanCode: self.virtual_scan_code,
240 uChar: unsafe {
241 let mut buf = [0u16];
242 self.u_char.encode_utf16(&mut buf);
243 std::mem::transmute(buf)
244 },
245 dwControlKeyState: self.control_key_state.get_state()
246 }
247 }
248}
249
250impl Into<MOUSE_EVENT_RECORD> for MouseEventRecord{
251 fn into(self) -> MOUSE_EVENT_RECORD {
252 MOUSE_EVENT_RECORD{
253 dwMousePosition: self.mouse_position.into(),
254 dwButtonState: self.button_state.get_state() as u32,
255 dwControlKeyState: self.control_key_state.get_state(),
256 dwEventFlags: self.event_flags as u32
257 }
258 }
259}
260
261impl From<KEY_EVENT_RECORD> for KeyEventRecord {
262 #[inline]
263 fn from(record: KEY_EVENT_RECORD) -> Self {
264 KeyEventRecord {
265 key_down: record.bKeyDown != 0,
266 repeat_count: record.wRepeatCount,
267 virtual_key_code: record.wVirtualKeyCode,
268 virtual_scan_code: record.wVirtualScanCode,
269 u_char: unsafe{ char::try_from(*record.uChar.UnicodeChar() as u32).ok().unwrap() },
270 control_key_state: ControlKeyState(record.dwControlKeyState),
271 }
272 }
273}
274
275impl From<u32> for EventFlags {
276 fn from(event: u32) -> Self {
277 match event {
278 0x0000 => EventFlags::PressOrRelease,
279 0x0001 => EventFlags::MouseMoved,
280 0x0002 => EventFlags::DoubleClick,
281 0x0004 => EventFlags::MouseWheeled,
282 0x0008 => EventFlags::MouseHwheeled,
283 _ => panic!("Event flag {} does not exist.", event),
284 }
285 }
286}
287
288impl From<MOUSE_EVENT_RECORD> for MouseEventRecord {
289 #[inline]
290 fn from(event: MOUSE_EVENT_RECORD) -> Self {
291 MouseEventRecord {
292 mouse_position: event.dwMousePosition.into(),
293 button_state: event.dwButtonState.into(),
294 control_key_state: ControlKeyState(event.dwControlKeyState),
295 event_flags: event.dwEventFlags.into(),
296 }
297 }
298}
299
300impl From<u32> for ButtonState {
301 #[inline]
302 fn from(state: u32) -> Self {
303 ButtonState(state as i32)
304 }
305}
306
307#[cfg(test)]
308mod tests{
309 use super::*;
310
311 #[test]
312 fn key_event_into_test(){
313 let mut key_event : KeyEventRecord = unsafe { std::mem::zeroed() };
314 key_event.control_key_state = ControlKeyState::new(4);
315 key_event.u_char = 'a';
316 key_event.virtual_scan_code = 4;
317 key_event.virtual_key_code = 8;
318 key_event.repeat_count = 16;
319 key_event.virtual_scan_code = 32;
320
321 let raw_key_event : KEY_EVENT_RECORD = key_event.into();
322
323 assert_eq!(key_event.virtual_scan_code, raw_key_event.wVirtualScanCode);
324 assert_eq!(key_event.repeat_count, raw_key_event.wRepeatCount);
325 assert_eq!(key_event.virtual_key_code, raw_key_event.wVirtualKeyCode);
326 assert_eq!(key_event.control_key_state.get_state(), raw_key_event.dwControlKeyState);
327 assert_eq!(key_event.key_down, raw_key_event.bKeyDown != 0);
328 assert_eq!(key_event.u_char, unsafe {
329 char::try_from(*raw_key_event.uChar.UnicodeChar() as u32).unwrap()
330 });
331 }
332
333 #[test]
334 fn mouse_event_into_test(){
335 let mouse_event : MouseEventRecord = unsafe { std::mem::zeroed() };
336 let raw_mouse_event : MOUSE_EVENT_RECORD = mouse_event.into();
337
338 assert_eq!(mouse_event.control_key_state.get_state(), raw_mouse_event.dwControlKeyState);
339 assert_eq!(mouse_event.event_flags as u32, raw_mouse_event.dwEventFlags);
340 assert_eq!(mouse_event.button_state.get_state() as u32, raw_mouse_event.dwButtonState);
341 assert_eq!(mouse_event.mouse_position, Coord::from(raw_mouse_event.dwMousePosition));
342 }
343}