pc-keyboard 0.9.0

PS/2 keyboard interface library.
Documentation
//! Dvorak Programmer keyboard support

use crate::{
    DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS,
};

/// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard.
///
/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
///
/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We
/// show either a Unicode glyph, or a hex number if the glyph isn't a
/// printable character. Blank spaces are passed through as
/// [`DecodedKey::RawKey`].
///
/// Run the `print_keyboard` example to re-generate these images.
///
/// ## Unmodified
///
/// ```text
/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
///
/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
/// │ $  │ &  │ [  │ {  │ }  │ (  │ =  │ *  │ )  │ +  │ ]  │ !  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
/// │0009 │ ;  │ ,  │ .  │ p  │ y  │ f  │ g  │ c  │ r  │ l  │ /  │ @  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
/// │      │ a  │ o  │ e  │ u  │ i  │ d  │ h  │ t  │ n  │ s  │ -  │   000a     │                    │ 4  │ 5  │ 6  │    │
/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
/// │         │ '  │ q  │ j  │ k  │ x  │ b  │ m  │ w  │ v  │ z  │              │       │    │       │ 1  │ 2  │ 3  │    │
/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
/// ```
///
/// ## Caps Lock
///
/// ```text
/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
///
/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
/// │ $  │ &  │ [  │ {  │ }  │ (  │ =  │ *  │ )  │ +  │ ]  │ !  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
/// │0009 │ ;  │ ,  │ .  │ P  │ Y  │ F  │ G  │ C  │ R  │ L  │ /  │ @  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
/// │      │ A  │ O  │ E  │ U  │ I  │ D  │ H  │ T  │ N  │ S  │ -  │   000a     │                    │ 4  │ 5  │ 6  │    │
/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
/// │         │ '  │ Q  │ J  │ K  │ X  │ B  │ M  │ W  │ V  │ Z  │              │       │    │       │ 1  │ 2  │ 3  │    │
/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
/// ```
///
/// ## Shifted
///
/// ```text
/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
///
/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
/// │ ~  │ %  │ 7  │ 5  │ 3  │ 1  │ 9  │ 0  │ 2  │ 4  │ 6  │ 8  │ `  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
/// │0009 │ :  │ <  │ >  │ P  │ Y  │ F  │ G  │ C  │ R  │ L  │ ?  │ ^  │   |    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
/// │      │ A  │ O  │ E  │ U  │ I  │ D  │ H  │ T  │ N  │ S  │ _  │   000a     │                    │ 4  │ 5  │ 6  │    │
/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
/// │         │ "  │ Q  │ J  │ K  │ X  │ B  │ M  │ W  │ V  │ Z  │              │       │    │       │ 1  │ 2  │ 3  │    │
/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
/// ```
///
/// ## Control
///
/// ```text
/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
///
/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
/// │ $  │ &  │ [  │ {  │ }  │ (  │ =  │ *  │ )  │ +  │ ]  │ !  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
/// │0009 │ ;  │ ,  │ .  │0010│0019│0006│0007│0003│0012│000c│ /  │ @  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
/// │      │0001│000f│0005│0015│0009│0004│0008│0014│000e│0013│ -  │   000a     │                    │ 4  │ 5  │ 6  │    │
/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
/// │         │ '  │0011│000a│000b│0018│0002│000d│0017│0016│001a│              │       │    │       │ 1  │ 2  │ 3  │    │
/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
/// ```
///
/// ## AltGr
///
/// ```text
/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
///
/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
/// │ $  │ &  │ [  │ {  │ }  │ (  │ =  │ *  │ )  │ +  │ ]  │ !  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
/// │0009 │ ;  │ ,  │ .  │ p  │ y  │ f  │ g  │ c  │ r  │ l  │ /  │ @  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
/// │      │ a  │ o  │ e  │ u  │ i  │ d  │ h  │ t  │ n  │ s  │ -  │   000a     │                    │ 4  │ 5  │ 6  │    │
/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
/// │         │ '  │ q  │ j  │ k  │ x  │ b  │ m  │ w  │ v  │ z  │              │       │    │       │ 1  │ 2  │ 3  │    │
/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
/// ```
///
/// ## Shift AltGr
///
/// ```text
/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
///
/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
/// │ ~  │ %  │ 7  │ 5  │ 3  │ 1  │ 9  │ 0  │ 2  │ 4  │ 6  │ 8  │ `  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
/// │0009 │ :  │ <  │ >  │ P  │ Y  │ F  │ G  │ C  │ R  │ L  │ ?  │ ^  │   |    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
/// │      │ A  │ O  │ E  │ U  │ I  │ D  │ H  │ T  │ N  │ S  │ _  │   000a     │                    │ 4  │ 5  │ 6  │    │
/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
/// │         │ "  │ Q  │ J  │ K  │ X  │ B  │ M  │ W  │ V  │ Z  │              │       │    │       │ 1  │ 2  │ 3  │    │
/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
/// ```
pub struct DVP104Key;

impl KeyboardLayout for DVP104Key {
    #[rustfmt::skip]
    fn map_keycode(
        &self,
        keycode: KeyCode,
        modifiers: &Modifiers,
        handle_ctrl: HandleControl,
    ) -> DecodedKey {
        match keycode {
            // ========= Row 2 (the numbers) =========
            KeyCode::Oem8      => modifiers.handle_symbol2('$', '~'),
            KeyCode::Key1      => modifiers.handle_symbol2('&', '%'),
            KeyCode::Key2      => modifiers.handle_symbol2('[', '7'),
            KeyCode::Key3      => modifiers.handle_symbol2('{', '5'),
            KeyCode::Key4      => modifiers.handle_symbol2('}', '3'),
            KeyCode::Key5      => modifiers.handle_symbol2('(', '1'),
            KeyCode::Key6      => modifiers.handle_symbol2('=', '9'),
            KeyCode::Key7      => modifiers.handle_symbol2('*', '0'),
            KeyCode::Key8      => modifiers.handle_symbol2(')', '2'),
            KeyCode::Key9      => modifiers.handle_symbol2('+', '4'),
            KeyCode::Key0      => modifiers.handle_symbol2(']', '6'),
            KeyCode::OemMinus  => modifiers.handle_symbol2('!', '8'),
            KeyCode::OemPlus   => modifiers.handle_symbol2('=', '`'),
            // ========= Row 3 (QWERTY) =========
            KeyCode::Q         => modifiers.handle_symbol2(';', ':'),
            KeyCode::W         => modifiers.handle_symbol2(',', '<'),
            KeyCode::E         => modifiers.handle_symbol2('.', '>'),
            KeyCode::R         => modifiers.handle_ascii_2('P', handle_ctrl),
            KeyCode::T         => modifiers.handle_ascii_2('Y', handle_ctrl),
            KeyCode::Y         => modifiers.handle_ascii_2('F', handle_ctrl),
            KeyCode::U         => modifiers.handle_ascii_2('G', handle_ctrl),
            KeyCode::I         => modifiers.handle_ascii_2('C', handle_ctrl),
            KeyCode::O         => modifiers.handle_ascii_2('R', handle_ctrl),
            KeyCode::P         => modifiers.handle_ascii_2('L', handle_ctrl),
            KeyCode::Oem4      => modifiers.handle_symbol2('/', '?'),
            KeyCode::Oem6      => modifiers.handle_symbol2('@', '^'),
            KeyCode::Oem7      => modifiers.handle_symbol2(SLS, '|'),
            // ========= Row 4 (ASDFG) =========
            KeyCode::A         => modifiers.handle_ascii_2('A', handle_ctrl),
            KeyCode::S         => modifiers.handle_ascii_2('O', handle_ctrl),
            KeyCode::D         => modifiers.handle_ascii_2('E', handle_ctrl),
            KeyCode::F         => modifiers.handle_ascii_2('U', handle_ctrl),
            KeyCode::G         => modifiers.handle_ascii_2('I', handle_ctrl),
            KeyCode::H         => modifiers.handle_ascii_2('D', handle_ctrl),
            KeyCode::J         => modifiers.handle_ascii_2('H', handle_ctrl),
            KeyCode::K         => modifiers.handle_ascii_2('T', handle_ctrl),
            KeyCode::L         => modifiers.handle_ascii_2('N', handle_ctrl),
            KeyCode::Oem1      => modifiers.handle_ascii_2('S', handle_ctrl),
            KeyCode::Oem3      => modifiers.handle_symbol2('-', '_'),
            // ========= Row 5 (ZXCVB) =========
            KeyCode::Z         => modifiers.handle_symbol2(QUO, '"'),
            KeyCode::X         => modifiers.handle_ascii_2('Q', handle_ctrl),
            KeyCode::C         => modifiers.handle_ascii_2('J', handle_ctrl),
            KeyCode::V         => modifiers.handle_ascii_2('K', handle_ctrl),
            KeyCode::B         => modifiers.handle_ascii_2('X', handle_ctrl),
            KeyCode::N         => modifiers.handle_ascii_2('B', handle_ctrl),
            KeyCode::M         => modifiers.handle_ascii_2('M', handle_ctrl),
            KeyCode::OemComma  => modifiers.handle_ascii_2('W', handle_ctrl),
            KeyCode::OemPeriod => modifiers.handle_ascii_2('V', handle_ctrl),
            KeyCode::Oem2      => modifiers.handle_ascii_2('Z', handle_ctrl),
            // ========= Fallback =========
            e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl),
        }
    }

    fn get_physical(&self) -> PhysicalKeyboard {
        PhysicalKeyboard::Ansi
    }
}