1use std::char;
2use std::ffi::OsString;
3use std::mem::MaybeUninit;
4use std::os::windows::ffi::OsStringExt;
5use std::sync::atomic::AtomicU32;
6use std::sync::atomic::Ordering::Relaxed;
7use std::sync::{Mutex, MutexGuard};
8
9use windows_sys::Win32::Foundation::{HWND, LPARAM, WPARAM};
10use windows_sys::Win32::System::SystemServices::LANG_KOREAN;
11use windows_sys::Win32::UI::Input::KeyboardAndMouse::{
12 GetAsyncKeyState, GetKeyState, GetKeyboardLayout, GetKeyboardState, MapVirtualKeyExW,
13 MAPVK_VK_TO_VSC_EX, MAPVK_VSC_TO_VK_EX, VIRTUAL_KEY, VK_ABNT_C2, VK_ADD, VK_CAPITAL, VK_CLEAR,
14 VK_CONTROL, VK_DECIMAL, VK_DELETE, VK_DIVIDE, VK_DOWN, VK_END, VK_F4, VK_HOME, VK_INSERT,
15 VK_LCONTROL, VK_LEFT, VK_LMENU, VK_LSHIFT, VK_LWIN, VK_MENU, VK_MULTIPLY, VK_NEXT, VK_NUMLOCK,
16 VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
17 VK_NUMPAD8, VK_NUMPAD9, VK_PRIOR, VK_RCONTROL, VK_RETURN, VK_RIGHT, VK_RMENU, VK_RSHIFT,
18 VK_RWIN, VK_SCROLL, VK_SHIFT, VK_SUBTRACT, VK_UP,
19};
20use windows_sys::Win32::UI::TextServices::HKL;
21use windows_sys::Win32::UI::WindowsAndMessaging::{
22 PeekMessageW, MSG, PM_NOREMOVE, WM_CHAR, WM_DEADCHAR, WM_KEYDOWN, WM_KEYFIRST, WM_KEYLAST,
23 WM_KEYUP, WM_KILLFOCUS, WM_SETFOCUS, WM_SYSCHAR, WM_SYSDEADCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP,
24};
25
26use smol_str::SmolStr;
27use tracing::{trace, warn};
28use unicode_segmentation::UnicodeSegmentation;
29
30use crate::event::{ElementState, KeyEvent};
31use crate::keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKey, NativeKeyCode, PhysicalKey};
32use crate::platform_impl::platform::event_loop::ProcResult;
33use crate::platform_impl::platform::keyboard_layout::{
34 Layout, LayoutCache, WindowsModifiers, LAYOUT_CACHE,
35};
36use crate::platform_impl::platform::{loword, primarylangid, KeyEventExtra};
37
38pub type ExScancode = u16;
39
40pub struct MessageAsKeyEvent {
41 pub event: KeyEvent,
42 pub is_synthetic: bool,
43}
44
45pub struct KeyEventBuilder {
66 event_info: Mutex<Option<PartialKeyEventInfo>>,
67 pending: PendingEventQueue<MessageAsKeyEvent>,
68}
69impl Default for KeyEventBuilder {
70 fn default() -> Self {
71 KeyEventBuilder { event_info: Mutex::new(None), pending: Default::default() }
72 }
73}
74impl KeyEventBuilder {
75 pub(crate) fn process_message(
79 &self,
80 hwnd: HWND,
81 msg_kind: u32,
82 wparam: WPARAM,
83 lparam: LPARAM,
84 result: &mut ProcResult,
85 ) -> Vec<MessageAsKeyEvent> {
86 enum MatchResult {
87 Nothing,
88 TokenToRemove(PendingMessageToken),
89 MessagesToDispatch(Vec<MessageAsKeyEvent>),
90 }
91
92 let mut matcher = || -> MatchResult {
93 match msg_kind {
94 WM_SETFOCUS => {
95 let kbd_state = get_async_kbd_state();
97 let key_events = Self::synthesize_kbd_state(ElementState::Pressed, &kbd_state);
98 MatchResult::MessagesToDispatch(self.pending.complete_multi(key_events))
99 },
100 WM_KILLFOCUS => {
101 let kbd_state = get_kbd_state();
103 let key_events = Self::synthesize_kbd_state(ElementState::Released, &kbd_state);
104 MatchResult::MessagesToDispatch(self.pending.complete_multi(key_events))
105 },
106 WM_KEYDOWN | WM_SYSKEYDOWN => {
107 if msg_kind == WM_SYSKEYDOWN && wparam as VIRTUAL_KEY == VK_F4 {
108 return MatchResult::Nothing;
111 }
112 let pending_token = self.pending.add_pending();
113 *result = ProcResult::Value(0);
114
115 let next_msg = next_kbd_msg(hwnd);
116
117 let mut layouts = LAYOUT_CACHE.lock().unwrap();
118 let mut finished_event_info = Some(PartialKeyEventInfo::from_message(
119 wparam,
120 lparam,
121 ElementState::Pressed,
122 &mut layouts,
123 ));
124 let mut event_info = self.event_info.lock().unwrap();
125 *event_info = None;
126 if let Some(next_msg) = next_msg {
127 let next_msg_kind = next_msg.message;
128 let next_belongs_to_this = !matches!(
129 next_msg_kind,
130 WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP | WM_SYSKEYUP
131 );
132 if next_belongs_to_this {
133 *event_info = finished_event_info.take();
136 } else {
137 let (_, layout) = layouts.get_current_layout();
138 let is_fake = {
139 let curr_event = finished_event_info.as_ref().unwrap();
140 is_current_fake(curr_event, next_msg, layout)
141 };
142 if is_fake {
143 finished_event_info = None;
144 }
145 }
146 }
147 if let Some(event_info) = finished_event_info {
148 let ev = event_info.finalize();
149 return MatchResult::MessagesToDispatch(self.pending.complete_pending(
150 pending_token,
151 MessageAsKeyEvent { event: ev, is_synthetic: false },
152 ));
153 }
154 MatchResult::TokenToRemove(pending_token)
155 },
156 WM_DEADCHAR | WM_SYSDEADCHAR => {
157 let pending_token = self.pending.add_pending();
158 *result = ProcResult::Value(0);
159 let event_info = self.event_info.lock().unwrap().take().unwrap();
162 let ev = event_info.finalize();
163 MatchResult::MessagesToDispatch(self.pending.complete_pending(
164 pending_token,
165 MessageAsKeyEvent { event: ev, is_synthetic: false },
166 ))
167 },
168 WM_CHAR | WM_SYSCHAR => {
169 let mut event_info = self.event_info.lock().unwrap();
170 if event_info.is_none() {
171 trace!(
172 "Received a CHAR message but no `event_info` was available. The \
173 message is probably IME, returning."
174 );
175 return MatchResult::Nothing;
176 }
177 let pending_token = self.pending.add_pending();
178 *result = ProcResult::Value(0);
179 let is_high_surrogate = (0xd800..=0xdbff).contains(&wparam);
180 let is_low_surrogate = (0xdc00..=0xdfff).contains(&wparam);
181
182 let is_utf16 = is_high_surrogate || is_low_surrogate;
183
184 if is_utf16 {
185 if let Some(ev_info) = event_info.as_mut() {
186 ev_info.utf16parts.push(wparam as u16);
187 }
188 } else {
189 let utf16parts = match event_info.as_mut() {
192 Some(ev_info) => &mut ev_info.utf16parts,
193 None => {
194 warn!("The event_info was None when it was expected to be some");
195 return MatchResult::TokenToRemove(pending_token);
196 },
197 };
198 let start_offset = utf16parts.len();
199 let new_size = utf16parts.len() + 2;
200 utf16parts.resize(new_size, 0);
201 if let Some(ch) = char::from_u32(wparam as u32) {
202 let encode_len = ch.encode_utf16(&mut utf16parts[start_offset..]).len();
203 let new_size = start_offset + encode_len;
204 utf16parts.resize(new_size, 0);
205 }
206 }
207 std::mem::drop(event_info);
210 let next_msg = next_kbd_msg(hwnd);
211 let more_char_coming = next_msg
212 .map(|m| matches!(m.message, WM_CHAR | WM_SYSCHAR))
213 .unwrap_or(false);
214 if more_char_coming {
215 MatchResult::TokenToRemove(pending_token)
218 } else {
219 let mut event_info = self.event_info.lock().unwrap();
220 let mut event_info = match event_info.take() {
221 Some(ev_info) => ev_info,
222 None => {
223 warn!("The event_info was None when it was expected to be some");
224 return MatchResult::TokenToRemove(pending_token);
225 },
226 };
227 let mut layouts = LAYOUT_CACHE.lock().unwrap();
228 let kbd_state = get_kbd_state();
231 let mod_state = WindowsModifiers::active_modifiers(&kbd_state);
232
233 let (_, layout) = layouts.get_current_layout();
234 let ctrl_on = if layout.has_alt_graph {
235 let alt_on = mod_state.contains(WindowsModifiers::ALT);
236 !alt_on && mod_state.contains(WindowsModifiers::CONTROL)
237 } else {
238 mod_state.contains(WindowsModifiers::CONTROL)
239 };
240
241 if !ctrl_on {
245 event_info.text = PartialText::System(event_info.utf16parts.clone());
246 } else {
247 let mod_no_ctrl = mod_state.remove_only_ctrl();
248 let num_lock_on = kbd_state[VK_NUMLOCK as usize] & 1 != 0;
249 let vkey = event_info.vkey;
250 let physical_key = &event_info.physical_key;
251 let key = layout.get_key(mod_no_ctrl, num_lock_on, vkey, physical_key);
252 event_info.text = PartialText::Text(key.to_text().map(SmolStr::new));
253 }
254 let ev = event_info.finalize();
255 MatchResult::MessagesToDispatch(self.pending.complete_pending(
256 pending_token,
257 MessageAsKeyEvent { event: ev, is_synthetic: false },
258 ))
259 }
260 },
261 WM_KEYUP | WM_SYSKEYUP => {
262 let pending_token = self.pending.add_pending();
263 *result = ProcResult::Value(0);
264
265 let mut layouts = LAYOUT_CACHE.lock().unwrap();
266 let event_info = PartialKeyEventInfo::from_message(
267 wparam,
268 lparam,
269 ElementState::Released,
270 &mut layouts,
271 );
272 drop(layouts);
275 let next_msg = next_kbd_msg(hwnd);
278 let mut valid_event_info = Some(event_info);
279 if let Some(next_msg) = next_msg {
280 let mut layouts = LAYOUT_CACHE.lock().unwrap();
281 let (_, layout) = layouts.get_current_layout();
282 let is_fake = {
283 let event_info = valid_event_info.as_ref().unwrap();
284 is_current_fake(event_info, next_msg, layout)
285 };
286 if is_fake {
287 valid_event_info = None;
288 }
289 }
290 if let Some(event_info) = valid_event_info {
291 let event = event_info.finalize();
292 return MatchResult::MessagesToDispatch(self.pending.complete_pending(
293 pending_token,
294 MessageAsKeyEvent { event, is_synthetic: false },
295 ));
296 }
297 MatchResult::TokenToRemove(pending_token)
298 },
299 _ => MatchResult::Nothing,
300 }
301 };
302 let matcher_result = matcher();
303 match matcher_result {
304 MatchResult::TokenToRemove(t) => self.pending.remove_pending(t),
305 MatchResult::MessagesToDispatch(m) => m,
306 MatchResult::Nothing => Vec::new(),
307 }
308 }
309
310 #[allow(clippy::nonminimal_bool)]
313 fn synthesize_kbd_state(
314 key_state: ElementState,
315 kbd_state: &[u8; 256],
316 ) -> Vec<MessageAsKeyEvent> {
317 let mut key_events = Vec::new();
318
319 let mut layouts = LAYOUT_CACHE.lock().unwrap();
320 let (locale_id, _) = layouts.get_current_layout();
321
322 macro_rules! is_key_pressed {
323 ($vk:expr) => {
324 kbd_state[$vk as usize] & 0x80 != 0
325 };
326 }
327
328 let caps_lock_on = kbd_state[VK_CAPITAL as usize] & 1 != 0;
331 let num_lock_on = kbd_state[VK_NUMLOCK as usize] & 1 != 0;
332
333 if is_key_pressed!(VK_CAPITAL) {
344 let event = Self::create_synthetic(
345 VK_CAPITAL,
346 key_state,
347 caps_lock_on,
348 num_lock_on,
349 locale_id as HKL,
350 &mut layouts,
351 );
352 if let Some(event) = event {
353 key_events.push(event);
354 }
355 }
356 let do_non_modifier = |key_events: &mut Vec<_>, layouts: &mut _| {
357 for vk in 0..256 {
358 match vk {
359 VK_CONTROL | VK_LCONTROL | VK_RCONTROL | VK_SHIFT | VK_LSHIFT | VK_RSHIFT
360 | VK_MENU | VK_LMENU | VK_RMENU | VK_CAPITAL => continue,
361 _ => (),
362 }
363 if !is_key_pressed!(vk) {
364 continue;
365 }
366 let event = Self::create_synthetic(
367 vk,
368 key_state,
369 caps_lock_on,
370 num_lock_on,
371 locale_id as HKL,
372 layouts,
373 );
374 if let Some(event) = event {
375 key_events.push(event);
376 }
377 }
378 };
379 let do_modifier = |key_events: &mut Vec<_>, layouts: &mut _| {
380 const CLEAR_MODIFIER_VKS: [VIRTUAL_KEY; 6] =
381 [VK_LCONTROL, VK_LSHIFT, VK_LMENU, VK_RCONTROL, VK_RSHIFT, VK_RMENU];
382 for vk in CLEAR_MODIFIER_VKS.iter() {
383 if is_key_pressed!(*vk) {
384 let event = Self::create_synthetic(
385 *vk,
386 key_state,
387 caps_lock_on,
388 num_lock_on,
389 locale_id as HKL,
390 layouts,
391 );
392 if let Some(event) = event {
393 key_events.push(event);
394 }
395 }
396 }
397 };
398
399 match key_state {
403 ElementState::Pressed => {
404 do_non_modifier(&mut key_events, &mut layouts);
405 do_modifier(&mut key_events, &mut layouts);
406 },
407 ElementState::Released => {
408 do_modifier(&mut key_events, &mut layouts);
409 do_non_modifier(&mut key_events, &mut layouts);
410 },
411 }
412
413 key_events
414 }
415
416 fn create_synthetic(
417 vk: VIRTUAL_KEY,
418 key_state: ElementState,
419 caps_lock_on: bool,
420 num_lock_on: bool,
421 locale_id: HKL,
422 layouts: &mut MutexGuard<'_, LayoutCache>,
423 ) -> Option<MessageAsKeyEvent> {
424 let scancode = unsafe { MapVirtualKeyExW(vk as u32, MAPVK_VK_TO_VSC_EX, locale_id) };
425 if scancode == 0 {
426 return None;
427 }
428 let scancode = scancode as ExScancode;
429 let physical_key = scancode_to_physicalkey(scancode as u32);
430 let mods =
431 if caps_lock_on { WindowsModifiers::CAPS_LOCK } else { WindowsModifiers::empty() };
432 let layout = layouts.layouts.get(&(locale_id as u64)).unwrap();
433 let logical_key = layout.get_key(mods, num_lock_on, vk, &physical_key);
434 let key_without_modifiers =
435 layout.get_key(WindowsModifiers::empty(), false, vk, &physical_key);
436 let text = if key_state == ElementState::Pressed {
437 logical_key.to_text().map(SmolStr::new)
438 } else {
439 None
440 };
441 let event_info = PartialKeyEventInfo {
442 vkey: vk,
443 logical_key: PartialLogicalKey::This(logical_key.clone()),
444 key_without_modifiers,
445 key_state,
446 is_repeat: false,
447 physical_key,
448 location: get_location(scancode, locale_id),
449 utf16parts: Vec::with_capacity(8),
450 text: PartialText::Text(text.clone()),
451 };
452
453 let mut event = event_info.finalize();
454 event.logical_key = logical_key;
455 event.platform_specific.text_with_all_modifiers = text;
456 Some(MessageAsKeyEvent { event, is_synthetic: true })
457 }
458}
459
460enum PartialText {
461 System(Vec<u16>),
463 Text(Option<SmolStr>),
464}
465
466enum PartialLogicalKey {
467 TextOr(Key),
472
473 This(Key),
475}
476
477struct PartialKeyEventInfo {
478 vkey: VIRTUAL_KEY,
479 key_state: ElementState,
480 is_repeat: bool,
481 physical_key: PhysicalKey,
482 location: KeyLocation,
483 logical_key: PartialLogicalKey,
484
485 key_without_modifiers: Key,
486
487 utf16parts: Vec<u16>,
490
491 text: PartialText,
492}
493
494impl PartialKeyEventInfo {
495 fn from_message(
496 wparam: WPARAM,
497 lparam: LPARAM,
498 state: ElementState,
499 layouts: &mut MutexGuard<'_, LayoutCache>,
500 ) -> Self {
501 const NO_MODS: WindowsModifiers = WindowsModifiers::empty();
502
503 let (_, layout) = layouts.get_current_layout();
504 let lparam_struct = destructure_key_lparam(lparam);
505 let vkey = wparam as VIRTUAL_KEY;
506 let scancode = if lparam_struct.scancode == 0 {
507 unsafe { MapVirtualKeyExW(vkey as u32, MAPVK_VK_TO_VSC_EX, layout.hkl as HKL) as u16 }
510 } else {
511 new_ex_scancode(lparam_struct.scancode, lparam_struct.extended)
512 };
513 let physical_key = scancode_to_physicalkey(scancode as u32);
514 let location = get_location(scancode, layout.hkl as HKL);
515
516 let kbd_state = get_kbd_state();
517 let mods = WindowsModifiers::active_modifiers(&kbd_state);
518 let mods_without_ctrl = mods.remove_only_ctrl();
519 let num_lock_on = kbd_state[VK_NUMLOCK as usize] & 1 != 0;
520
521 let code_as_key = if mods.contains(WindowsModifiers::CONTROL) {
528 match physical_key {
529 PhysicalKey::Code(KeyCode::NumLock) => Some(Key::Named(NamedKey::NumLock)),
530 PhysicalKey::Code(KeyCode::Pause) => Some(Key::Named(NamedKey::Pause)),
531 _ => None,
532 }
533 } else {
534 None
535 };
536
537 let preliminary_logical_key =
538 layout.get_key(mods_without_ctrl, num_lock_on, vkey, &physical_key);
539 let key_is_char = matches!(preliminary_logical_key, Key::Character(_));
540 let is_pressed = state == ElementState::Pressed;
541
542 let logical_key = if let Some(key) = code_as_key.clone() {
543 PartialLogicalKey::This(key)
544 } else if is_pressed && key_is_char && !mods.contains(WindowsModifiers::CONTROL) {
545 PartialLogicalKey::TextOr(preliminary_logical_key)
548 } else {
549 PartialLogicalKey::This(preliminary_logical_key)
550 };
551 let key_without_modifiers = if let Some(key) = code_as_key {
552 key
553 } else {
554 match layout.get_key(NO_MODS, false, vkey, &physical_key) {
555 Key::Dead(k) => {
561 if let Some(ch) = k {
562 let mut utf8 = [0; 4];
564 let s = ch.encode_utf8(&mut utf8);
565 Key::Character(SmolStr::new(s))
566 } else {
567 Key::Unidentified(NativeKey::Unidentified)
568 }
569 },
570 key => key,
571 }
572 };
573
574 PartialKeyEventInfo {
575 vkey,
576 key_state: state,
577 logical_key,
578 key_without_modifiers,
579 is_repeat: lparam_struct.is_repeat,
580 physical_key,
581 location,
582 utf16parts: Vec::with_capacity(8),
583 text: PartialText::System(Vec::new()),
584 }
585 }
586
587 fn finalize(self) -> KeyEvent {
588 let mut char_with_all_modifiers = None;
589 if !self.utf16parts.is_empty() {
590 let os_string = OsString::from_wide(&self.utf16parts);
591 if let Ok(string) = os_string.into_string() {
592 char_with_all_modifiers = Some(SmolStr::new(string));
593 }
594 }
595
596 let mut text = None;
598 match self.text {
599 PartialText::System(wide) => {
600 if !wide.is_empty() {
601 let os_string = OsString::from_wide(&wide);
602 if let Ok(string) = os_string.into_string() {
603 text = Some(SmolStr::new(string));
604 }
605 }
606 },
607 PartialText::Text(s) => {
608 text = s.map(SmolStr::new);
609 },
610 }
611
612 let logical_key = match self.logical_key {
613 PartialLogicalKey::TextOr(fallback) => match text.as_ref() {
614 Some(s) => {
615 if s.grapheme_indices(true).count() > 1 {
616 fallback
617 } else {
618 Key::Character(s.clone())
619 }
620 },
621 None => Key::Unidentified(NativeKey::Windows(self.vkey)),
622 },
623 PartialLogicalKey::This(v) => v,
624 };
625
626 KeyEvent {
627 physical_key: self.physical_key,
628 logical_key,
629 text,
630 location: self.location,
631 state: self.key_state,
632 repeat: self.is_repeat,
633 platform_specific: KeyEventExtra {
634 text_with_all_modifiers: char_with_all_modifiers,
635 key_without_modifiers: self.key_without_modifiers,
636 },
637 }
638 }
639}
640
641#[derive(Debug, Copy, Clone)]
642struct KeyLParam {
643 pub scancode: u8,
644 pub extended: bool,
645
646 pub is_repeat: bool,
649}
650
651fn destructure_key_lparam(lparam: LPARAM) -> KeyLParam {
652 let previous_state = (lparam >> 30) & 0x01;
653 let transition_state = (lparam >> 31) & 0x01;
654 KeyLParam {
655 scancode: ((lparam >> 16) & 0xff) as u8,
656 extended: ((lparam >> 24) & 0x01) != 0,
657 is_repeat: (previous_state ^ transition_state) != 0,
658 }
659}
660
661#[inline]
662fn new_ex_scancode(scancode: u8, extended: bool) -> ExScancode {
663 (scancode as u16) | (if extended { 0xe000 } else { 0 })
664}
665
666#[inline]
667fn ex_scancode_from_lparam(lparam: LPARAM) -> ExScancode {
668 let lparam = destructure_key_lparam(lparam);
669 new_ex_scancode(lparam.scancode, lparam.extended)
670}
671
672fn get_kbd_state() -> [u8; 256] {
675 unsafe {
676 let mut kbd_state: MaybeUninit<[u8; 256]> = MaybeUninit::uninit();
677 GetKeyboardState(kbd_state.as_mut_ptr() as *mut u8);
678 kbd_state.assume_init()
679 }
680}
681
682#[allow(clippy::uninit_assumed_init)]
685fn get_async_kbd_state() -> [u8; 256] {
686 unsafe {
687 let mut kbd_state: [u8; 256] = [0; 256];
688 for (vk, state) in kbd_state.iter_mut().enumerate() {
689 let vk = vk as VIRTUAL_KEY;
690 let async_state = GetAsyncKeyState(vk as i32);
691 let is_down = (async_state & (1 << 15)) != 0;
692 *state = if is_down { 0x80 } else { 0 };
693
694 if matches!(vk, VK_CAPITAL | VK_NUMLOCK | VK_SCROLL) {
695 let toggle_state = GetKeyState(vk as i32);
697 let is_active = (toggle_state & 1) != 0;
698 *state |= u8::from(is_active);
699 }
700 }
701 kbd_state
702 }
703}
704
705fn is_current_fake(curr_info: &PartialKeyEventInfo, next_msg: MSG, layout: &Layout) -> bool {
712 let curr_is_ctrl =
713 matches!(curr_info.logical_key, PartialLogicalKey::This(Key::Named(NamedKey::Control)));
714 if layout.has_alt_graph {
715 let next_code = ex_scancode_from_lparam(next_msg.lParam);
716 let next_is_altgr = next_code == 0xe038; if curr_is_ctrl && next_is_altgr {
718 return true;
719 }
720 }
721 false
722}
723
724enum PendingMessage<T> {
725 Incomplete,
726 Complete(T),
727}
728struct IdentifiedPendingMessage<T> {
729 token: PendingMessageToken,
730 msg: PendingMessage<T>,
731}
732#[derive(Debug, Clone, Copy, PartialEq, Eq)]
733pub struct PendingMessageToken(u32);
734
735pub struct PendingEventQueue<T> {
752 pending: Mutex<Vec<IdentifiedPendingMessage<T>>>,
753 next_id: AtomicU32,
754}
755impl<T> PendingEventQueue<T> {
756 pub fn add_pending(&self) -> PendingMessageToken {
758 let token = self.next_token();
759 let mut pending = self.pending.lock().unwrap();
760 pending.push(IdentifiedPendingMessage { token, msg: PendingMessage::Incomplete });
761 token
762 }
763
764 pub fn complete_pending(&self, token: PendingMessageToken, msg: T) -> Vec<T> {
770 let mut pending = self.pending.lock().unwrap();
771 let mut target_is_first = false;
772 for (i, pending_msg) in pending.iter_mut().enumerate() {
773 if pending_msg.token == token {
774 pending_msg.msg = PendingMessage::Complete(msg);
775 if i == 0 {
776 target_is_first = true;
777 }
778 break;
779 }
780 }
781 if target_is_first {
782 Self::drain_pending(&mut *pending)
785 } else {
786 Vec::new()
787 }
788 }
789
790 pub fn complete_multi(&self, msgs: Vec<T>) -> Vec<T> {
791 let mut pending = self.pending.lock().unwrap();
792 if pending.is_empty() {
793 return msgs;
794 }
795 pending.reserve(msgs.len());
796 for msg in msgs {
797 pending.push(IdentifiedPendingMessage {
798 token: self.next_token(),
799 msg: PendingMessage::Complete(msg),
800 });
801 }
802 Vec::new()
803 }
804
805 pub fn remove_pending(&self, token: PendingMessageToken) -> Vec<T> {
811 let mut pending = self.pending.lock().unwrap();
812 let mut was_first = false;
813 if let Some(m) = pending.first() {
814 if m.token == token {
815 was_first = true;
816 }
817 }
818 pending.retain(|m| m.token != token);
819 if was_first {
820 Self::drain_pending(&mut *pending)
821 } else {
822 Vec::new()
823 }
824 }
825
826 fn drain_pending(pending: &mut Vec<IdentifiedPendingMessage<T>>) -> Vec<T> {
827 pending
828 .drain(..)
829 .map(|m| match m.msg {
830 PendingMessage::Complete(msg) => msg,
831 PendingMessage::Incomplete => {
832 panic!(
833 "Found an incomplete pending message when collecting messages. This \
834 indicates a bug in winit."
835 )
836 },
837 })
838 .collect()
839 }
840
841 fn next_token(&self) -> PendingMessageToken {
842 let id = self.next_id.fetch_add(1, Relaxed);
849 PendingMessageToken(id)
850 }
851}
852impl<T> Default for PendingEventQueue<T> {
853 fn default() -> Self {
854 PendingEventQueue { pending: Mutex::new(Vec::new()), next_id: AtomicU32::new(0) }
855 }
856}
857
858pub fn next_kbd_msg(hwnd: HWND) -> Option<MSG> {
867 unsafe {
868 let mut next_msg = MaybeUninit::uninit();
869 let peek_retval =
870 PeekMessageW(next_msg.as_mut_ptr(), hwnd, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE);
871 (peek_retval != 0).then(|| next_msg.assume_init())
872 }
873}
874
875fn get_location(scancode: ExScancode, hkl: HKL) -> KeyLocation {
876 const ABNT_C2: VIRTUAL_KEY = VK_ABNT_C2 as VIRTUAL_KEY;
877
878 let extension = 0xe000;
879 let extended = (scancode & extension) == extension;
880 let vkey = unsafe { MapVirtualKeyExW(scancode as u32, MAPVK_VSC_TO_VK_EX, hkl) as VIRTUAL_KEY };
881
882 match vkey {
886 VK_LSHIFT | VK_LCONTROL | VK_LMENU | VK_LWIN => KeyLocation::Left,
887 VK_RSHIFT | VK_RCONTROL | VK_RMENU | VK_RWIN => KeyLocation::Right,
888 VK_RETURN if extended => KeyLocation::Numpad,
889 VK_INSERT | VK_DELETE | VK_END | VK_DOWN | VK_NEXT | VK_LEFT | VK_CLEAR | VK_RIGHT
890 | VK_HOME | VK_UP | VK_PRIOR => {
891 if extended {
892 KeyLocation::Standard
893 } else {
894 KeyLocation::Numpad
895 }
896 },
897 VK_NUMPAD0 | VK_NUMPAD1 | VK_NUMPAD2 | VK_NUMPAD3 | VK_NUMPAD4 | VK_NUMPAD5
898 | VK_NUMPAD6 | VK_NUMPAD7 | VK_NUMPAD8 | VK_NUMPAD9 | VK_DECIMAL | VK_DIVIDE
899 | VK_MULTIPLY | VK_SUBTRACT | VK_ADD | ABNT_C2 => KeyLocation::Numpad,
900 _ => KeyLocation::Standard,
901 }
902}
903
904pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32> {
905 let hkl = unsafe { GetKeyboardLayout(0) };
908
909 let primary_lang_id = primarylangid(loword(hkl as u32));
910 let is_korean = primary_lang_id as u32 == LANG_KOREAN;
911
912 let code = match physical_key {
913 PhysicalKey::Code(code) => code,
914 PhysicalKey::Unidentified(code) => {
915 return match code {
916 NativeKeyCode::Windows(scancode) => Some(scancode as u32),
917 _ => None,
918 };
919 },
920 };
921
922 match code {
923 KeyCode::Backquote => Some(0x0029),
924 KeyCode::Backslash => Some(0x002b),
925 KeyCode::Backspace => Some(0x000e),
926 KeyCode::BracketLeft => Some(0x001a),
927 KeyCode::BracketRight => Some(0x001b),
928 KeyCode::Comma => Some(0x0033),
929 KeyCode::Digit0 => Some(0x000b),
930 KeyCode::Digit1 => Some(0x0002),
931 KeyCode::Digit2 => Some(0x0003),
932 KeyCode::Digit3 => Some(0x0004),
933 KeyCode::Digit4 => Some(0x0005),
934 KeyCode::Digit5 => Some(0x0006),
935 KeyCode::Digit6 => Some(0x0007),
936 KeyCode::Digit7 => Some(0x0008),
937 KeyCode::Digit8 => Some(0x0009),
938 KeyCode::Digit9 => Some(0x000a),
939 KeyCode::Equal => Some(0x000d),
940 KeyCode::IntlBackslash => Some(0x0056),
941 KeyCode::IntlRo => Some(0x0073),
942 KeyCode::IntlYen => Some(0x007d),
943 KeyCode::KeyA => Some(0x001e),
944 KeyCode::KeyB => Some(0x0030),
945 KeyCode::KeyC => Some(0x002e),
946 KeyCode::KeyD => Some(0x0020),
947 KeyCode::KeyE => Some(0x0012),
948 KeyCode::KeyF => Some(0x0021),
949 KeyCode::KeyG => Some(0x0022),
950 KeyCode::KeyH => Some(0x0023),
951 KeyCode::KeyI => Some(0x0017),
952 KeyCode::KeyJ => Some(0x0024),
953 KeyCode::KeyK => Some(0x0025),
954 KeyCode::KeyL => Some(0x0026),
955 KeyCode::KeyM => Some(0x0032),
956 KeyCode::KeyN => Some(0x0031),
957 KeyCode::KeyO => Some(0x0018),
958 KeyCode::KeyP => Some(0x0019),
959 KeyCode::KeyQ => Some(0x0010),
960 KeyCode::KeyR => Some(0x0013),
961 KeyCode::KeyS => Some(0x001f),
962 KeyCode::KeyT => Some(0x0014),
963 KeyCode::KeyU => Some(0x0016),
964 KeyCode::KeyV => Some(0x002f),
965 KeyCode::KeyW => Some(0x0011),
966 KeyCode::KeyX => Some(0x002d),
967 KeyCode::KeyY => Some(0x0015),
968 KeyCode::KeyZ => Some(0x002c),
969 KeyCode::Minus => Some(0x000c),
970 KeyCode::Period => Some(0x0034),
971 KeyCode::Quote => Some(0x0028),
972 KeyCode::Semicolon => Some(0x0027),
973 KeyCode::Slash => Some(0x0035),
974 KeyCode::AltLeft => Some(0x0038),
975 KeyCode::AltRight => Some(0xe038),
976 KeyCode::CapsLock => Some(0x003a),
977 KeyCode::ContextMenu => Some(0xe05d),
978 KeyCode::ControlLeft => Some(0x001d),
979 KeyCode::ControlRight => Some(0xe01d),
980 KeyCode::Enter => Some(0x001c),
981 KeyCode::SuperLeft => Some(0xe05b),
982 KeyCode::SuperRight => Some(0xe05c),
983 KeyCode::ShiftLeft => Some(0x002a),
984 KeyCode::ShiftRight => Some(0x0036),
985 KeyCode::Space => Some(0x0039),
986 KeyCode::Tab => Some(0x000f),
987 KeyCode::Convert => Some(0x0079),
988 KeyCode::Lang1 => {
989 if is_korean {
990 Some(0xe0f2)
991 } else {
992 Some(0x0072)
993 }
994 },
995 KeyCode::Lang2 => {
996 if is_korean {
997 Some(0xe0f1)
998 } else {
999 Some(0x0071)
1000 }
1001 },
1002 KeyCode::KanaMode => Some(0x0070),
1003 KeyCode::NonConvert => Some(0x007b),
1004 KeyCode::Delete => Some(0xe053),
1005 KeyCode::End => Some(0xe04f),
1006 KeyCode::Home => Some(0xe047),
1007 KeyCode::Insert => Some(0xe052),
1008 KeyCode::PageDown => Some(0xe051),
1009 KeyCode::PageUp => Some(0xe049),
1010 KeyCode::ArrowDown => Some(0xe050),
1011 KeyCode::ArrowLeft => Some(0xe04b),
1012 KeyCode::ArrowRight => Some(0xe04d),
1013 KeyCode::ArrowUp => Some(0xe048),
1014 KeyCode::NumLock => Some(0xe045),
1015 KeyCode::Numpad0 => Some(0x0052),
1016 KeyCode::Numpad1 => Some(0x004f),
1017 KeyCode::Numpad2 => Some(0x0050),
1018 KeyCode::Numpad3 => Some(0x0051),
1019 KeyCode::Numpad4 => Some(0x004b),
1020 KeyCode::Numpad5 => Some(0x004c),
1021 KeyCode::Numpad6 => Some(0x004d),
1022 KeyCode::Numpad7 => Some(0x0047),
1023 KeyCode::Numpad8 => Some(0x0048),
1024 KeyCode::Numpad9 => Some(0x0049),
1025 KeyCode::NumpadAdd => Some(0x004e),
1026 KeyCode::NumpadComma => Some(0x007e),
1027 KeyCode::NumpadDecimal => Some(0x0053),
1028 KeyCode::NumpadDivide => Some(0xe035),
1029 KeyCode::NumpadEnter => Some(0xe01c),
1030 KeyCode::NumpadEqual => Some(0x0059),
1031 KeyCode::NumpadMultiply => Some(0x0037),
1032 KeyCode::NumpadSubtract => Some(0x004a),
1033 KeyCode::Escape => Some(0x0001),
1034 KeyCode::F1 => Some(0x003b),
1035 KeyCode::F2 => Some(0x003c),
1036 KeyCode::F3 => Some(0x003d),
1037 KeyCode::F4 => Some(0x003e),
1038 KeyCode::F5 => Some(0x003f),
1039 KeyCode::F6 => Some(0x0040),
1040 KeyCode::F7 => Some(0x0041),
1041 KeyCode::F8 => Some(0x0042),
1042 KeyCode::F9 => Some(0x0043),
1043 KeyCode::F10 => Some(0x0044),
1044 KeyCode::F11 => Some(0x0057),
1045 KeyCode::F12 => Some(0x0058),
1046 KeyCode::F13 => Some(0x0064),
1047 KeyCode::F14 => Some(0x0065),
1048 KeyCode::F15 => Some(0x0066),
1049 KeyCode::F16 => Some(0x0067),
1050 KeyCode::F17 => Some(0x0068),
1051 KeyCode::F18 => Some(0x0069),
1052 KeyCode::F19 => Some(0x006a),
1053 KeyCode::F20 => Some(0x006b),
1054 KeyCode::F21 => Some(0x006c),
1055 KeyCode::F22 => Some(0x006d),
1056 KeyCode::F23 => Some(0x006e),
1057 KeyCode::F24 => Some(0x0076),
1058 KeyCode::PrintScreen => Some(0xe037),
1059 KeyCode::ScrollLock => Some(0x0046),
1061 KeyCode::Pause => Some(0x0045),
1062 KeyCode::BrowserBack => Some(0xe06a),
1064 KeyCode::BrowserFavorites => Some(0xe066),
1065 KeyCode::BrowserForward => Some(0xe069),
1066 KeyCode::BrowserHome => Some(0xe032),
1067 KeyCode::BrowserRefresh => Some(0xe067),
1068 KeyCode::BrowserSearch => Some(0xe065),
1069 KeyCode::BrowserStop => Some(0xe068),
1070 KeyCode::LaunchApp1 => Some(0xe06b),
1071 KeyCode::LaunchApp2 => Some(0xe021),
1072 KeyCode::LaunchMail => Some(0xe06c),
1073 KeyCode::MediaPlayPause => Some(0xe022),
1074 KeyCode::MediaSelect => Some(0xe06d),
1075 KeyCode::MediaStop => Some(0xe024),
1076 KeyCode::MediaTrackNext => Some(0xe019),
1077 KeyCode::MediaTrackPrevious => Some(0xe010),
1078 KeyCode::Power => Some(0xe05e),
1079 KeyCode::AudioVolumeDown => Some(0xe02e),
1080 KeyCode::AudioVolumeMute => Some(0xe020),
1081 KeyCode::AudioVolumeUp => Some(0xe030),
1082 _ => None,
1083 }
1084}
1085
1086pub(crate) fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey {
1087 PhysicalKey::Code(match scancode {
1092 0x0029 => KeyCode::Backquote,
1093 0x002b => KeyCode::Backslash,
1094 0x000e => KeyCode::Backspace,
1095 0x001a => KeyCode::BracketLeft,
1096 0x001b => KeyCode::BracketRight,
1097 0x0033 => KeyCode::Comma,
1098 0x000b => KeyCode::Digit0,
1099 0x0002 => KeyCode::Digit1,
1100 0x0003 => KeyCode::Digit2,
1101 0x0004 => KeyCode::Digit3,
1102 0x0005 => KeyCode::Digit4,
1103 0x0006 => KeyCode::Digit5,
1104 0x0007 => KeyCode::Digit6,
1105 0x0008 => KeyCode::Digit7,
1106 0x0009 => KeyCode::Digit8,
1107 0x000a => KeyCode::Digit9,
1108 0x000d => KeyCode::Equal,
1109 0x0056 => KeyCode::IntlBackslash,
1110 0x0073 => KeyCode::IntlRo,
1111 0x007d => KeyCode::IntlYen,
1112 0x001e => KeyCode::KeyA,
1113 0x0030 => KeyCode::KeyB,
1114 0x002e => KeyCode::KeyC,
1115 0x0020 => KeyCode::KeyD,
1116 0x0012 => KeyCode::KeyE,
1117 0x0021 => KeyCode::KeyF,
1118 0x0022 => KeyCode::KeyG,
1119 0x0023 => KeyCode::KeyH,
1120 0x0017 => KeyCode::KeyI,
1121 0x0024 => KeyCode::KeyJ,
1122 0x0025 => KeyCode::KeyK,
1123 0x0026 => KeyCode::KeyL,
1124 0x0032 => KeyCode::KeyM,
1125 0x0031 => KeyCode::KeyN,
1126 0x0018 => KeyCode::KeyO,
1127 0x0019 => KeyCode::KeyP,
1128 0x0010 => KeyCode::KeyQ,
1129 0x0013 => KeyCode::KeyR,
1130 0x001f => KeyCode::KeyS,
1131 0x0014 => KeyCode::KeyT,
1132 0x0016 => KeyCode::KeyU,
1133 0x002f => KeyCode::KeyV,
1134 0x0011 => KeyCode::KeyW,
1135 0x002d => KeyCode::KeyX,
1136 0x0015 => KeyCode::KeyY,
1137 0x002c => KeyCode::KeyZ,
1138 0x000c => KeyCode::Minus,
1139 0x0034 => KeyCode::Period,
1140 0x0028 => KeyCode::Quote,
1141 0x0027 => KeyCode::Semicolon,
1142 0x0035 => KeyCode::Slash,
1143 0x0038 => KeyCode::AltLeft,
1144 0xe038 => KeyCode::AltRight,
1145 0x003a => KeyCode::CapsLock,
1146 0xe05d => KeyCode::ContextMenu,
1147 0x001d => KeyCode::ControlLeft,
1148 0xe01d => KeyCode::ControlRight,
1149 0x001c => KeyCode::Enter,
1150 0xe05b => KeyCode::SuperLeft,
1151 0xe05c => KeyCode::SuperRight,
1152 0x002a => KeyCode::ShiftLeft,
1153 0x0036 => KeyCode::ShiftRight,
1154 0x0039 => KeyCode::Space,
1155 0x000f => KeyCode::Tab,
1156 0x0079 => KeyCode::Convert,
1157 0x0072 => KeyCode::Lang1, 0xe0f2 => KeyCode::Lang1, 0x0071 => KeyCode::Lang2, 0xe0f1 => KeyCode::Lang2, 0x0070 => KeyCode::KanaMode,
1162 0x007b => KeyCode::NonConvert,
1163 0xe053 => KeyCode::Delete,
1164 0xe04f => KeyCode::End,
1165 0xe047 => KeyCode::Home,
1166 0xe052 => KeyCode::Insert,
1167 0xe051 => KeyCode::PageDown,
1168 0xe049 => KeyCode::PageUp,
1169 0xe050 => KeyCode::ArrowDown,
1170 0xe04b => KeyCode::ArrowLeft,
1171 0xe04d => KeyCode::ArrowRight,
1172 0xe048 => KeyCode::ArrowUp,
1173 0xe045 => KeyCode::NumLock,
1174 0x0052 => KeyCode::Numpad0,
1175 0x004f => KeyCode::Numpad1,
1176 0x0050 => KeyCode::Numpad2,
1177 0x0051 => KeyCode::Numpad3,
1178 0x004b => KeyCode::Numpad4,
1179 0x004c => KeyCode::Numpad5,
1180 0x004d => KeyCode::Numpad6,
1181 0x0047 => KeyCode::Numpad7,
1182 0x0048 => KeyCode::Numpad8,
1183 0x0049 => KeyCode::Numpad9,
1184 0x004e => KeyCode::NumpadAdd,
1185 0x007e => KeyCode::NumpadComma,
1186 0x0053 => KeyCode::NumpadDecimal,
1187 0xe035 => KeyCode::NumpadDivide,
1188 0xe01c => KeyCode::NumpadEnter,
1189 0x0059 => KeyCode::NumpadEqual,
1190 0x0037 => KeyCode::NumpadMultiply,
1191 0x004a => KeyCode::NumpadSubtract,
1192 0x0001 => KeyCode::Escape,
1193 0x003b => KeyCode::F1,
1194 0x003c => KeyCode::F2,
1195 0x003d => KeyCode::F3,
1196 0x003e => KeyCode::F4,
1197 0x003f => KeyCode::F5,
1198 0x0040 => KeyCode::F6,
1199 0x0041 => KeyCode::F7,
1200 0x0042 => KeyCode::F8,
1201 0x0043 => KeyCode::F9,
1202 0x0044 => KeyCode::F10,
1203 0x0057 => KeyCode::F11,
1204 0x0058 => KeyCode::F12,
1205 0x0064 => KeyCode::F13,
1206 0x0065 => KeyCode::F14,
1207 0x0066 => KeyCode::F15,
1208 0x0067 => KeyCode::F16,
1209 0x0068 => KeyCode::F17,
1210 0x0069 => KeyCode::F18,
1211 0x006a => KeyCode::F19,
1212 0x006b => KeyCode::F20,
1213 0x006c => KeyCode::F21,
1214 0x006d => KeyCode::F22,
1215 0x006e => KeyCode::F23,
1216 0x0076 => KeyCode::F24,
1217 0xe037 => KeyCode::PrintScreen,
1218 0x0054 => KeyCode::PrintScreen, 0x0046 => KeyCode::ScrollLock,
1220 0x0045 => KeyCode::Pause,
1221 0xe046 => KeyCode::Pause, 0xe06a => KeyCode::BrowserBack,
1223 0xe066 => KeyCode::BrowserFavorites,
1224 0xe069 => KeyCode::BrowserForward,
1225 0xe032 => KeyCode::BrowserHome,
1226 0xe067 => KeyCode::BrowserRefresh,
1227 0xe065 => KeyCode::BrowserSearch,
1228 0xe068 => KeyCode::BrowserStop,
1229 0xe06b => KeyCode::LaunchApp1,
1230 0xe021 => KeyCode::LaunchApp2,
1231 0xe06c => KeyCode::LaunchMail,
1232 0xe022 => KeyCode::MediaPlayPause,
1233 0xe06d => KeyCode::MediaSelect,
1234 0xe024 => KeyCode::MediaStop,
1235 0xe019 => KeyCode::MediaTrackNext,
1236 0xe010 => KeyCode::MediaTrackPrevious,
1237 0xe05e => KeyCode::Power,
1238 0xe02e => KeyCode::AudioVolumeDown,
1239 0xe020 => KeyCode::AudioVolumeMute,
1240 0xe030 => KeyCode::AudioVolumeUp,
1241 _ => return PhysicalKey::Unidentified(NativeKeyCode::Windows(scancode as u16)),
1242 })
1243}