@@ -48,10 +48,16 @@ use crate::util::{loword, primarylangid};
4848pub ( crate ) static LAYOUT_CACHE : LazyLock < Mutex < LayoutCache > > =
4949 LazyLock :: new ( || Mutex :: new ( LayoutCache :: default ( ) ) ) ;
5050
51+ // high order bit is pressed
5152fn key_pressed ( vkey : VIRTUAL_KEY ) -> bool {
5253 unsafe { ( GetKeyState ( vkey as i32 ) & ( 1 << 15 ) ) == ( 1 << 15 ) }
5354}
5455
56+ // low order bit is toggled
57+ fn key_toggled ( vkey : VIRTUAL_KEY ) -> bool {
58+ unsafe { ( GetKeyState ( vkey as i32 ) & 0x01 ) == 0x01 }
59+ }
60+
5561const NUMPAD_VKEYS : [ VIRTUAL_KEY ; 16 ] = [
5662 VK_NUMPAD0 ,
5763 VK_NUMPAD1 ,
@@ -986,3 +992,47 @@ fn vkey_to_non_char_key(
986992 _ => Key :: Unidentified ( native_code) ,
987993 }
988994}
995+
996+ /// Query the logical key that would be produced by a physical key under the
997+ /// current keyboard layout with the given modifier state.
998+ ///
999+ /// # Example
1000+ ///
1001+ /// ```ignore
1002+ /// use winit::keyboard::{KeyCode, ModifiersState};
1003+ /// use winit_win32::keycode_to_key;
1004+ ///
1005+ /// // Get what the 'Q' key produces without modifiers
1006+ /// let key = keycode_to_key(KeyCode::KeyQ, ModifiersState::empty(), false, false);
1007+ ///
1008+ /// // Get what Shift+Q produces
1009+ /// let shifted = keycode_to_key(KeyCode::KeyQ, ModifiersState::SHIFT, false, false);
1010+ /// ```
1011+ pub fn keycode_to_key (
1012+ keycode : KeyCode ,
1013+ modifiers : ModifiersState ,
1014+ caps_lock : bool ,
1015+ num_lock : bool ,
1016+ ) -> Key {
1017+ let mut cache = LAYOUT_CACHE . lock ( ) . unwrap ( ) ;
1018+ let ( locale_id, layout) = cache. get_current_layout ( ) ;
1019+
1020+ let mut win_mods = WindowsModifiers :: empty ( ) ;
1021+ if modifiers. shift_key ( ) {
1022+ win_mods. insert ( WindowsModifiers :: SHIFT ) ;
1023+ }
1024+ if modifiers. control_key ( ) {
1025+ win_mods. insert ( WindowsModifiers :: CONTROL ) ;
1026+ }
1027+ if modifiers. alt_key ( ) {
1028+ win_mods. insert ( WindowsModifiers :: ALT ) ;
1029+ }
1030+ if caps_lock {
1031+ win_mods. insert ( WindowsModifiers :: CAPS_LOCK ) ;
1032+ }
1033+
1034+ let vkey = keycode_to_vkey ( keycode, locale_id) ;
1035+ let physical_key = PhysicalKey :: Code ( keycode) ;
1036+
1037+ layout. get_key ( win_mods, num_lock, vkey, & physical_key)
1038+ }
0 commit comments