├── .gitignore ├── src ├── scancodes │ ├── mod.rs │ ├── usbhid.rs │ ├── set2.rs │ └── set1.rs └── layouts │ ├── mod.rs │ ├── colemak.rs │ ├── jis109.rs │ ├── de105.rs │ ├── no105.rs │ ├── fi_se105.rs │ ├── dvorak104.rs │ ├── dvorak_programmer104.rs │ ├── azerty.rs │ ├── uk105.rs │ └── us104.rs ├── .github └── workflows │ ├── release.yml │ └── build.yml ├── Cargo.toml ├── LICENSE-MIT ├── examples ├── decoder.rs ├── layout.rs └── scancodes.rs ├── README.md ├── CHANGELOG.md └── LICENSE-APACHE /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | /target 3 | **/*.rs.bk 4 | Cargo.lock 5 | -------------------------------------------------------------------------------- /src/scancodes/mod.rs: -------------------------------------------------------------------------------- 1 | //! A collection of Scancode implementations 2 | 3 | mod set1; 4 | mod set2; 5 | mod usbhid; 6 | 7 | pub use self::set1::ScancodeSet1; 8 | pub use self::set2::ScancodeSet2; 9 | pub use self::usbhid::{convert as usb_convert, Modifiers as UsbModifiers}; 10 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | release-create: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: ncipollo/release-action@v1 16 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pc-keyboard" 3 | version = "0.8.0" 4 | authors = ["Jonathan 'theJPster' Pallant ", "Rust Embedded Community Contributors"] 5 | description = "PS/2 keyboard interface library." 6 | keywords = ["keyboard", "ps2", "scancode", "layout"] 7 | categories = ["embedded", "no-std"] 8 | license = "MIT OR Apache-2.0" 9 | repository = "https://github.com/rust-embedded-community/pc-keyboard.git" 10 | edition = "2021" 11 | rust-version = "1.61" 12 | 13 | [dependencies] 14 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Cargo 2 | 3 | on: [push, pull_request] 4 | 5 | env: 6 | CARGO_TERM_COLOR: always 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - run: cargo build --verbose 14 | 15 | test: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - run: cargo test --verbose 20 | 21 | format-check: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - run: cargo fmt --check 26 | 27 | clippy-check: 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v4 31 | - run: cargo clippy 32 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Rust Embedded Community Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /examples/decoder.rs: -------------------------------------------------------------------------------- 1 | use pc_keyboard::Ps2Decoder; 2 | 3 | fn main() { 4 | let mut decoder = Ps2Decoder::new(); 5 | 6 | // If you get all 11 bits as one `u16` 7 | match decoder.add_word(0x0402) { 8 | Ok(byte) => println!("Word 0x0402 is byte 0x{:02x}", byte), 9 | Err(e) => println!("Word 0x0402 failed to decode: {:?}", e), 10 | } 11 | 12 | // If you get a bit at a time 13 | for bit in [ 14 | false, true, false, false, false, false, false, false, false, false, true, 15 | ] { 16 | match decoder.add_bit(bit) { 17 | Ok(None) => println!("Added {}, not enough bits yet!", bit as u8), 18 | Ok(Some(byte)) => println!("Added {}, got byte 0x{byte:02x}", bit as u8), 19 | Err(e) => println!("Failed to decode: {e:?}"), 20 | } 21 | } 22 | 23 | // Flipped a random bit, so we get a parity error 24 | for bit in [ 25 | false, true, false, false, false, false, true, false, false, false, true, 26 | ] { 27 | match decoder.add_bit(bit) { 28 | Ok(None) => println!("Added {}, not enough bits yet!", bit as u8), 29 | Ok(Some(byte)) => println!("Added {}, got byte 0x{byte:02x}", bit as u8), 30 | Err(e) => println!("Failed to decode: {e:?}"), 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pc-keyboard 2 | 3 | A simple driver for handling PC keyboards, with both Scancode Set 1 (when 4 | running on a PC) and Scancode Set 2 support (when reading a PS/2 keyboard 5 | output directly). 6 | 7 | See for documentation, or read [`src/lib.rs`](./src/lib.rs). 8 | 9 | ## Minimum Supported Rust Version (MSRV) 10 | 11 | This crate is guaranteed to compile on stable Rust 1.61 and up. It might compile with older versions but that may change in any new patch release. 12 | 13 | ## Changelog 14 | 15 | There is a changelog in [CHANGELOG.md](./CHANGELOG.md). 16 | 17 | ## License 18 | 19 | Licensed under either of 20 | 21 | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or 22 | http://www.apache.org/licenses/LICENSE-2.0) 23 | - MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 24 | 25 | at your option. 26 | 27 | ## Contribution 28 | 29 | Unless you explicitly state otherwise, any contribution intentionally 30 | submitted for inclusion in the work by you shall be licensed as above, without 31 | any additional terms or conditions. 32 | 33 | ## Code of Conduct 34 | 35 | Contribution to this crate is organized under the terms of the [Rust Code of 36 | Conduct][coc], the maintainer of this crate, the [Rust Embedded Community][team], promises 37 | to intervene to uphold that code of conduct. 38 | 39 | [coc]: https://www.rust-lang.org/policies/code-of-conduct 40 | [team]: https://github.com/orgs/rust-embedded-community/people 41 | -------------------------------------------------------------------------------- /examples/layout.rs: -------------------------------------------------------------------------------- 1 | use pc_keyboard::{ 2 | layouts::{AnyLayout, Uk105Key}, 3 | DecodedKey, EventDecoder, KeyCode, KeyEvent, KeyState, 4 | }; 5 | 6 | fn main() { 7 | let mut decoder = EventDecoder::new( 8 | AnyLayout::Uk105Key(Uk105Key), 9 | pc_keyboard::HandleControl::Ignore, 10 | ); 11 | 12 | // User presses 'A' on their UK keyboard, gets a lower-case 'a'. 13 | let decoded_key = decoder.process_keyevent(KeyEvent { 14 | code: KeyCode::A, 15 | state: KeyState::Down, 16 | }); 17 | assert_eq!(Some(DecodedKey::Unicode('a')), decoded_key); 18 | println!("Got {:?}", decoded_key); 19 | 20 | // User releases 'A' on their UK keyboard 21 | let decoded_key = decoder.process_keyevent(KeyEvent { 22 | code: KeyCode::A, 23 | state: KeyState::Up, 24 | }); 25 | assert_eq!(None, decoded_key); 26 | 27 | // User presses 'Shift' on their UK keyboard 28 | let decoded_key = decoder.process_keyevent(KeyEvent { 29 | code: KeyCode::LShift, 30 | state: KeyState::Down, 31 | }); 32 | assert_eq!(Some(DecodedKey::RawKey(KeyCode::LShift)), decoded_key); 33 | 34 | // User presses 'A' on their UK keyboard, now gets a Capital A 35 | let decoded_key = decoder.process_keyevent(KeyEvent { 36 | code: KeyCode::A, 37 | state: KeyState::Down, 38 | }); 39 | assert_eq!(Some(DecodedKey::Unicode('A')), decoded_key); 40 | println!("Got {:?}", decoded_key); 41 | 42 | // User releases 'A' on their UK keyboard 43 | let decoded_key = decoder.process_keyevent(KeyEvent { 44 | code: KeyCode::A, 45 | state: KeyState::Up, 46 | }); 47 | assert_eq!(None, decoded_key); 48 | 49 | // User releases 'Shift' on their UK keyboard 50 | let decoded_key = decoder.process_keyevent(KeyEvent { 51 | code: KeyCode::LShift, 52 | state: KeyState::Up, 53 | }); 54 | assert_eq!(None, decoded_key); 55 | } 56 | -------------------------------------------------------------------------------- /examples/scancodes.rs: -------------------------------------------------------------------------------- 1 | use pc_keyboard::{KeyEvent, ScancodeSet, ScancodeSet1, ScancodeSet2}; 2 | 3 | fn main() { 4 | let mut s = ScancodeSet1::new(); 5 | // [ 0x01 ] means "Pressed Escape" in Set 1 6 | match s.advance_state(0x01) { 7 | Ok(Some(KeyEvent { code, state })) => { 8 | println!("Scancode Set 1 0x01 is KeyCode '{code:?}' KeyState '{state:?}'"); 9 | } 10 | Ok(None) => { 11 | println!("This is wrong, we didn't think that was a complete sequence"); 12 | } 13 | Err(e) => { 14 | println!("There was an error: {e:?}"); 15 | } 16 | } 17 | // [ 0x81 ] means "Released Escape" in Set 1 18 | match s.advance_state(0x81) { 19 | Ok(Some(KeyEvent { code, state })) => { 20 | println!("Scancode Set 1 0x81 is KeyCode '{code:?}' KeyState '{state:?}'"); 21 | } 22 | Ok(None) => { 23 | println!("This is wrong, we didn't think that was a complete sequence"); 24 | } 25 | Err(e) => { 26 | println!("There was an error: {e:?}"); 27 | } 28 | } 29 | 30 | let mut s = ScancodeSet2::new(); 31 | // [ 0x01 ] means "Pressed F9" in Set 2 32 | match s.advance_state(0x01) { 33 | Ok(Some(KeyEvent { code, state })) => { 34 | println!("Scancode Set 2 0x01 is KeyCode '{code:?}' KeyState '{state:?}'"); 35 | } 36 | Ok(None) => { 37 | println!("This is wrong, we didn't think that was a complete sequence"); 38 | } 39 | Err(e) => { 40 | println!("There was an error: {e:?}"); 41 | } 42 | } 43 | // [ 0xF0, 0x01 ] means "Released F9" in Set 2 44 | assert_eq!(Ok(None), s.advance_state(0xF0)); 45 | match s.advance_state(0x01) { 46 | Ok(Some(KeyEvent { code, state })) => { 47 | println!("Scancode Set 2 0xF0 0x01 is KeyCode '{code:?}' KeyState '{state:?}'"); 48 | } 49 | Ok(None) => { 50 | println!("This is wrong, we didn't think that was a complete sequence"); 51 | } 52 | Err(e) => { 53 | println!("There was an error: {e:?}"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Unreleased 4 | 5 | * Fix Ctrl combination handling for Colemak and De105Key layouts 6 | * Fix 102/105-key German layout: Add missing Alt-Gr combinations 7 | * Added tool to print keyboard layouts as ASCII-art 8 | * Cleaned up how layouts are implemented 9 | * Added support for decoding USB HID Boot Keyboard reports 10 | 11 | ## v0.8.0 (13 Sep 2024) 12 | 13 | * Add 102/105-key Finnish/Swedish layout 14 | * Add 102/105-key Norwegian layout 15 | * Fix broken Backslash for Us104 layout 16 | * Fix `<` and `>` for Azerty layout 17 | * Renamed `Modifiers::alt_gr` to `Modifiers::ralt` and add `Modifiers::lalt` 18 | 19 | ## v0.7.0 (12 Feb 2022) 20 | 21 | * Changed ordering of `enum KeyCode` and names of several of the keys 22 | * Made 'enum KeyCode' FFI safe 23 | * Support the mysterious 'Right Control 2' and 'Right Alt 2' so that Pause/Break 24 | and Print Screen do the right thing. 25 | * Fix the Backslash/Tilde swap on the UK Layout. 26 | * Added split PS/2 Decoder, Scancode interpreter and Event Decoder objects 27 | * Added example code 28 | * Improved docs - ASCII-art diagrams of ISO 102/105, ANSI 101/104 and JIS 106/109 keyboards. 29 | 30 | ## v0.6.1 (20 Oct 2022) 31 | 32 | * Fix Control-Letter codes on AZERTY 33 | 34 | ## v0.6.0 (29 Aug 2022) 35 | 36 | * `Keyboard::new` is now const 37 | * Layout and Scan Code Set are now const-generics, not arguments 38 | * Pause/Break and Print Screen now work correctly 39 | * KeyCode is now non-exhaustive 40 | * KeyState includes 'SingleShot' for keys with no break code 41 | * Add Colemak, Dvorak Programmer and DE layouts 42 | * MSRV increased to Rust 1.61 43 | 44 | ## v0.5.1 (19 Jul 2020) 45 | 46 | * Add Dvorak, JIS and Azerty layouts 47 | 48 | ## v0.5.0 (6 Feb 2019) 49 | 50 | * Support Ctrl+C generating Unicode U+0003, etc. 51 | * Added tests 52 | 53 | ## v0.4.1 (5 Feb 2019) 54 | 55 | * Support PowerOnTestOk 56 | 57 | ## v0.4.0 (4 Feb 2019) 58 | 59 | * Fixed decoding issues (including Backslash/HashTilde mix-up) 60 | 61 | ## v0.3.1 (16 Nov 2018) 62 | 63 | * Fixed decoding issues 64 | * Added more tests 65 | 66 | ## v0.3.0 (9 Nov 2018) 67 | 68 | * Fixed Scancode Set 1 69 | 70 | ## v0.2.0 (28 Octo 2018) 71 | 72 | * Added Scancode Set 1 73 | 74 | ## v0.1.1 (22 Aug 2018) 75 | 76 | * Metadata fixes 77 | 78 | ## v0.1.0 (26 Apr 2018) 79 | 80 | * First version 81 | -------------------------------------------------------------------------------- /src/layouts/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements the various keyboard layouts. 2 | //! 3 | //! We have one layout per file, but where two layouts are similar, you can 4 | //! handle all the 'different' keys first, and then jump to another handler - 5 | //! see [`Uk105Key`] and [`Us104Key`] as an example of that. 6 | 7 | mod dvorak_programmer104; 8 | use crate::PhysicalKeyboard; 9 | 10 | pub use self::dvorak_programmer104::DVP104Key; 11 | 12 | mod dvorak104; 13 | pub use self::dvorak104::Dvorak104Key; 14 | 15 | mod us104; 16 | pub use self::us104::Us104Key; 17 | 18 | mod uk105; 19 | pub use self::uk105::Uk105Key; 20 | 21 | mod jis109; 22 | pub use self::jis109::Jis109Key; 23 | 24 | mod azerty; 25 | pub use self::azerty::Azerty; 26 | 27 | mod colemak; 28 | pub use self::colemak::Colemak; 29 | 30 | mod de105; 31 | pub use self::de105::De105Key; 32 | 33 | mod no105; 34 | pub use self::no105::No105Key; 35 | 36 | mod fi_se105; 37 | pub use self::fi_se105::FiSe105Key; 38 | 39 | /// A enum of all the supported keyboard layouts. 40 | pub enum AnyLayout { 41 | DVP104Key(DVP104Key), 42 | Dvorak104Key(Dvorak104Key), 43 | Us104Key(Us104Key), 44 | Uk105Key(Uk105Key), 45 | Jis109Key(Jis109Key), 46 | Azerty(Azerty), 47 | Colemak(Colemak), 48 | De105Key(De105Key), 49 | No105Key(No105Key), 50 | FiSe105Key(FiSe105Key), 51 | } 52 | 53 | impl super::KeyboardLayout for AnyLayout { 54 | fn map_keycode( 55 | &self, 56 | keycode: super::KeyCode, 57 | modifiers: &super::Modifiers, 58 | handle_ctrl: super::HandleControl, 59 | ) -> super::DecodedKey { 60 | match self { 61 | AnyLayout::DVP104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 62 | AnyLayout::Dvorak104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 63 | AnyLayout::Us104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 64 | AnyLayout::Uk105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 65 | AnyLayout::Jis109Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 66 | AnyLayout::Azerty(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 67 | AnyLayout::Colemak(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 68 | AnyLayout::De105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 69 | AnyLayout::No105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 70 | AnyLayout::FiSe105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 71 | } 72 | } 73 | 74 | fn get_physical(&self) -> PhysicalKeyboard { 75 | match self { 76 | AnyLayout::DVP104Key(inner) => inner.get_physical(), 77 | AnyLayout::Dvorak104Key(inner) => inner.get_physical(), 78 | AnyLayout::Us104Key(inner) => inner.get_physical(), 79 | AnyLayout::Uk105Key(inner) => inner.get_physical(), 80 | AnyLayout::Jis109Key(inner) => inner.get_physical(), 81 | AnyLayout::Azerty(inner) => inner.get_physical(), 82 | AnyLayout::Colemak(inner) => inner.get_physical(), 83 | AnyLayout::De105Key(inner) => inner.get_physical(), 84 | AnyLayout::No105Key(inner) => inner.get_physical(), 85 | AnyLayout::FiSe105Key(inner) => inner.get_physical(), 86 | } 87 | } 88 | } 89 | 90 | impl super::KeyboardLayout for &AnyLayout { 91 | fn map_keycode( 92 | &self, 93 | keycode: super::KeyCode, 94 | modifiers: &super::Modifiers, 95 | handle_ctrl: super::HandleControl, 96 | ) -> super::DecodedKey { 97 | match self { 98 | AnyLayout::DVP104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 99 | AnyLayout::Dvorak104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 100 | AnyLayout::Us104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 101 | AnyLayout::Uk105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 102 | AnyLayout::Jis109Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 103 | AnyLayout::Azerty(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 104 | AnyLayout::Colemak(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 105 | AnyLayout::De105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 106 | AnyLayout::No105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 107 | AnyLayout::FiSe105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), 108 | } 109 | } 110 | 111 | fn get_physical(&self) -> PhysicalKeyboard { 112 | match self { 113 | AnyLayout::DVP104Key(inner) => inner.get_physical(), 114 | AnyLayout::Dvorak104Key(inner) => inner.get_physical(), 115 | AnyLayout::Us104Key(inner) => inner.get_physical(), 116 | AnyLayout::Uk105Key(inner) => inner.get_physical(), 117 | AnyLayout::Jis109Key(inner) => inner.get_physical(), 118 | AnyLayout::Azerty(inner) => inner.get_physical(), 119 | AnyLayout::Colemak(inner) => inner.get_physical(), 120 | AnyLayout::De105Key(inner) => inner.get_physical(), 121 | AnyLayout::No105Key(inner) => inner.get_physical(), 122 | AnyLayout::FiSe105Key(inner) => inner.get_physical(), 123 | } 124 | } 125 | } 126 | 127 | #[cfg(test)] 128 | mod test { 129 | use super::*; 130 | use crate::*; 131 | 132 | #[test] 133 | fn test_any() { 134 | let mut decoder = EventDecoder::new(AnyLayout::Uk105Key(Uk105Key), HandleControl::Ignore); 135 | // Q gets you a 'q' 136 | let decoded = decoder.process_keyevent(KeyEvent { 137 | code: KeyCode::Q, 138 | state: KeyState::Down, 139 | }); 140 | assert_eq!(decoded, Some(DecodedKey::Unicode('q'))); 141 | // Swap the layout 142 | decoder.change_layout(AnyLayout::Azerty(Azerty)); 143 | // Q gets you a 'a' 144 | let decoded = decoder.process_keyevent(KeyEvent { 145 | code: KeyCode::Q, 146 | state: KeyState::Down, 147 | }); 148 | assert_eq!(decoded, Some(DecodedKey::Unicode('a'))); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/scancodes/usbhid.rs: -------------------------------------------------------------------------------- 1 | //! USB Scancode conversions 2 | 3 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] 4 | #[repr(u8)] 5 | pub enum Modifiers { 6 | LCtrl = 0x01, 7 | LShift = 0x02, 8 | LAlt = 0x04, 9 | LGui = 0x08, 10 | RCtrl = 0x10, 11 | RShift = 0x20, 12 | RAlt = 0x40, 13 | RGui = 0x80, 14 | } 15 | 16 | const HID_A: u8 = 0x04; 17 | const HID_B: u8 = 0x05; 18 | const HID_C: u8 = 0x06; 19 | const HID_D: u8 = 0x07; 20 | const HID_E: u8 = 0x08; 21 | const HID_F: u8 = 0x09; 22 | const HID_G: u8 = 0x0A; 23 | const HID_H: u8 = 0x0B; 24 | const HID_I: u8 = 0x0C; 25 | const HID_J: u8 = 0x0D; 26 | const HID_K: u8 = 0x0E; 27 | const HID_L: u8 = 0x0F; 28 | const HID_M: u8 = 0x10; 29 | const HID_N: u8 = 0x11; 30 | const HID_O: u8 = 0x12; 31 | const HID_P: u8 = 0x13; 32 | const HID_Q: u8 = 0x14; 33 | const HID_R: u8 = 0x15; 34 | const HID_S: u8 = 0x16; 35 | const HID_T: u8 = 0x17; 36 | const HID_U: u8 = 0x18; 37 | const HID_V: u8 = 0x19; 38 | const HID_W: u8 = 0x1A; 39 | const HID_X: u8 = 0x1B; 40 | const HID_Y: u8 = 0x1C; 41 | const HID_Z: u8 = 0x1D; 42 | const HID_1: u8 = 0x1E; 43 | const HID_2: u8 = 0x1F; 44 | const HID_3: u8 = 0x20; 45 | const HID_4: u8 = 0x21; 46 | const HID_5: u8 = 0x22; 47 | const HID_6: u8 = 0x23; 48 | const HID_7: u8 = 0x24; 49 | const HID_8: u8 = 0x25; 50 | const HID_9: u8 = 0x26; 51 | const HID_0: u8 = 0x27; 52 | const HID_RETURN: u8 = 0x28; 53 | const HID_ESCAPE: u8 = 0x29; 54 | const HID_BACKSPACE: u8 = 0x2A; 55 | const HID_TAB: u8 = 0x2B; 56 | const HID_SPACEBAR: u8 = 0x2C; 57 | const HID_UNDERSCORE: u8 = 0x2D; 58 | const HID_EQUAL: u8 = 0x2E; 59 | const HID_OPEN_BRACE: u8 = 0x2F; 60 | const HID_CLOSE_BRACE: u8 = 0x30; 61 | const HID_BACKSLASH: u8 = 0x31; 62 | const HID_HASH_TILDE: u8 = 0x32; 63 | const HID_SEMICOLON: u8 = 0x33; 64 | const HID_APOSTROPHE: u8 = 0x34; 65 | const HID_GRAVE_TILDE: u8 = 0x35; 66 | const HID_COMMA: u8 = 0x36; 67 | const HID_DOT: u8 = 0x37; 68 | const HID_SLASH: u8 = 0x38; 69 | const HID_CAPS_LOCK: u8 = 0x39; 70 | const HID_F1: u8 = 0x3A; 71 | const HID_F2: u8 = 0x3B; 72 | const HID_F3: u8 = 0x3C; 73 | const HID_F4: u8 = 0x3D; 74 | const HID_F5: u8 = 0x3E; 75 | const HID_F6: u8 = 0x3F; 76 | const HID_F7: u8 = 0x40; 77 | const HID_F8: u8 = 0x41; 78 | const HID_F9: u8 = 0x42; 79 | const HID_F10: u8 = 0x43; 80 | const HID_F11: u8 = 0x44; 81 | const HID_F12: u8 = 0x45; 82 | const HID_PRINTSCREEN: u8 = 0x46; 83 | const HID_SCROLL_LOCK: u8 = 0x47; 84 | const HID_PAUSE: u8 = 0x48; 85 | const HID_INSERT: u8 = 0x49; 86 | const HID_HOME: u8 = 0x4A; 87 | const HID_PAGEUP: u8 = 0x4B; 88 | const HID_DELETE: u8 = 0x4C; 89 | const HID_END: u8 = 0x4D; 90 | const HID_PAGEDOWN: u8 = 0x4E; 91 | const HID_RIGHT: u8 = 0x4F; 92 | const HID_LEFT: u8 = 0x50; 93 | const HID_DOWN: u8 = 0x51; 94 | const HID_UP: u8 = 0x52; 95 | const HID_KEYPAD_NUM_LOCK: u8 = 0x53; 96 | const HID_KEYPAD_SLASH: u8 = 0x54; 97 | const HID_KEYPAD_ASTERISK: u8 = 0x55; 98 | const HID_KEYPAD_MINUS: u8 = 0x56; 99 | const HID_KEYPAD_PLUS: u8 = 0x57; 100 | const HID_KEYPAD_ENTER: u8 = 0x58; 101 | const HID_KEYPAD_1: u8 = 0x59; 102 | const HID_KEYPAD_2: u8 = 0x5A; 103 | const HID_KEYPAD_3: u8 = 0x5B; 104 | const HID_KEYPAD_4: u8 = 0x5C; 105 | const HID_KEYPAD_5: u8 = 0x5D; 106 | const HID_KEYPAD_6: u8 = 0x5E; 107 | const HID_KEYPAD_7: u8 = 0x5F; 108 | const HID_KEYPAD_8: u8 = 0x60; 109 | const HID_KEYPAD_9: u8 = 0x61; 110 | const HID_KEYPAD_0: u8 = 0x62; 111 | const HID_KEYPAD_DOT: u8 = 0x63; 112 | const HID_LEFT_CTRL: u8 = 0xE0; 113 | const HID_LEFT_SHIFT: u8 = 0xE1; 114 | const HID_LEFT_ALT: u8 = 0xE2; 115 | const HID_LEFT_GUI: u8 = 0xE3; 116 | const HID_RIGHT_CTRL: u8 = 0xE4; 117 | const HID_RIGHT_SHIFT: u8 = 0xE5; 118 | const HID_RIGHT_ALT: u8 = 0xE6; 119 | const HID_RIGHT_GUI: u8 = 0xE7; 120 | const HID_AT102: u8 = 0x64; 121 | const HID_APPLICATION: u8 = 0x65; 122 | 123 | pub fn convert(usb_keycode: u8) -> crate::KeyCode { 124 | match usb_keycode { 125 | HID_A => crate::KeyCode::A, 126 | HID_B => crate::KeyCode::B, 127 | HID_C => crate::KeyCode::C, 128 | HID_D => crate::KeyCode::D, 129 | HID_E => crate::KeyCode::E, 130 | HID_F => crate::KeyCode::F, 131 | HID_G => crate::KeyCode::G, 132 | HID_H => crate::KeyCode::H, 133 | HID_I => crate::KeyCode::I, 134 | HID_J => crate::KeyCode::J, 135 | HID_K => crate::KeyCode::K, 136 | HID_L => crate::KeyCode::L, 137 | HID_M => crate::KeyCode::M, 138 | HID_N => crate::KeyCode::N, 139 | HID_O => crate::KeyCode::O, 140 | HID_P => crate::KeyCode::P, 141 | HID_Q => crate::KeyCode::Q, 142 | HID_R => crate::KeyCode::R, 143 | HID_S => crate::KeyCode::S, 144 | HID_T => crate::KeyCode::T, 145 | HID_U => crate::KeyCode::U, 146 | HID_V => crate::KeyCode::V, 147 | HID_W => crate::KeyCode::W, 148 | HID_X => crate::KeyCode::X, 149 | HID_Y => crate::KeyCode::Y, 150 | HID_Z => crate::KeyCode::Z, 151 | HID_1 => crate::KeyCode::Key1, 152 | HID_2 => crate::KeyCode::Key2, 153 | HID_3 => crate::KeyCode::Key3, 154 | HID_4 => crate::KeyCode::Key4, 155 | HID_5 => crate::KeyCode::Key5, 156 | HID_6 => crate::KeyCode::Key6, 157 | HID_7 => crate::KeyCode::Key7, 158 | HID_8 => crate::KeyCode::Key8, 159 | HID_9 => crate::KeyCode::Key9, 160 | HID_0 => crate::KeyCode::Key0, 161 | HID_RETURN => crate::KeyCode::Return, 162 | HID_ESCAPE => crate::KeyCode::Escape, 163 | HID_BACKSPACE => crate::KeyCode::Backspace, 164 | HID_TAB => crate::KeyCode::Tab, 165 | HID_SPACEBAR => crate::KeyCode::Spacebar, 166 | HID_UNDERSCORE => crate::KeyCode::OemMinus, 167 | HID_EQUAL => crate::KeyCode::OemPlus, 168 | HID_OPEN_BRACE => crate::KeyCode::Oem4, 169 | HID_CLOSE_BRACE => crate::KeyCode::Oem6, 170 | HID_BACKSLASH => crate::KeyCode::Oem7, 171 | HID_HASH_TILDE => crate::KeyCode::Oem7, 172 | HID_SEMICOLON => crate::KeyCode::Oem1, 173 | HID_APOSTROPHE => crate::KeyCode::Oem3, 174 | HID_GRAVE_TILDE => crate::KeyCode::Oem8, 175 | HID_AT102 => crate::KeyCode::Oem5, 176 | HID_COMMA => crate::KeyCode::OemComma, 177 | HID_DOT => crate::KeyCode::OemPeriod, 178 | HID_SLASH => crate::KeyCode::Oem2, 179 | HID_CAPS_LOCK => crate::KeyCode::CapsLock, 180 | HID_F1 => crate::KeyCode::F1, 181 | HID_F2 => crate::KeyCode::F2, 182 | HID_F3 => crate::KeyCode::F3, 183 | HID_F4 => crate::KeyCode::F4, 184 | HID_F5 => crate::KeyCode::F5, 185 | HID_F6 => crate::KeyCode::F6, 186 | HID_F7 => crate::KeyCode::F7, 187 | HID_F8 => crate::KeyCode::F8, 188 | HID_F9 => crate::KeyCode::F9, 189 | HID_F10 => crate::KeyCode::F10, 190 | HID_F11 => crate::KeyCode::F11, 191 | HID_F12 => crate::KeyCode::F12, 192 | HID_PRINTSCREEN => crate::KeyCode::PrintScreen, 193 | HID_SCROLL_LOCK => crate::KeyCode::ScrollLock, 194 | HID_PAUSE => crate::KeyCode::PauseBreak, 195 | HID_INSERT => crate::KeyCode::Insert, 196 | HID_HOME => crate::KeyCode::Home, 197 | HID_PAGEUP => crate::KeyCode::PageUp, 198 | HID_DELETE => crate::KeyCode::Delete, 199 | HID_END => crate::KeyCode::End, 200 | HID_PAGEDOWN => crate::KeyCode::PageDown, 201 | HID_RIGHT => crate::KeyCode::ArrowRight, 202 | HID_LEFT => crate::KeyCode::ArrowLeft, 203 | HID_DOWN => crate::KeyCode::ArrowDown, 204 | HID_UP => crate::KeyCode::ArrowUp, 205 | HID_KEYPAD_NUM_LOCK => crate::KeyCode::NumpadLock, 206 | HID_KEYPAD_SLASH => crate::KeyCode::NumpadDivide, 207 | HID_KEYPAD_ASTERISK => crate::KeyCode::NumpadMultiply, 208 | HID_KEYPAD_MINUS => crate::KeyCode::NumpadSubtract, 209 | HID_KEYPAD_PLUS => crate::KeyCode::NumpadAdd, 210 | HID_KEYPAD_ENTER => crate::KeyCode::NumpadEnter, 211 | HID_KEYPAD_1 => crate::KeyCode::Numpad1, 212 | HID_KEYPAD_2 => crate::KeyCode::Numpad2, 213 | HID_KEYPAD_3 => crate::KeyCode::Numpad3, 214 | HID_KEYPAD_4 => crate::KeyCode::Numpad4, 215 | HID_KEYPAD_5 => crate::KeyCode::Numpad5, 216 | HID_KEYPAD_6 => crate::KeyCode::Numpad6, 217 | HID_KEYPAD_7 => crate::KeyCode::Numpad7, 218 | HID_KEYPAD_8 => crate::KeyCode::Numpad8, 219 | HID_KEYPAD_9 => crate::KeyCode::Numpad9, 220 | HID_KEYPAD_0 => crate::KeyCode::Numpad0, 221 | HID_KEYPAD_DOT => crate::KeyCode::NumpadPeriod, 222 | HID_LEFT_CTRL => crate::KeyCode::LControl, 223 | HID_LEFT_SHIFT => crate::KeyCode::LShift, 224 | HID_LEFT_ALT => crate::KeyCode::LAlt, 225 | HID_LEFT_GUI => crate::KeyCode::LWin, 226 | HID_APPLICATION => crate::KeyCode::Apps, 227 | HID_RIGHT_CTRL => crate::KeyCode::RControl, 228 | HID_RIGHT_SHIFT => crate::KeyCode::RShift, 229 | HID_RIGHT_ALT => crate::KeyCode::RAltGr, 230 | HID_RIGHT_GUI => crate::KeyCode::RWin, 231 | _ => crate::KeyCode::Unknown, 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /src/scancodes/set2.rs: -------------------------------------------------------------------------------- 1 | //! Scan Code Set 2 support 2 | 3 | use crate::{ 4 | DecodeState, Error, KeyCode, KeyEvent, KeyState, ScancodeSet, EXTENDED2_KEY_CODE, 5 | EXTENDED_KEY_CODE, KEY_RELEASE_CODE, 6 | }; 7 | 8 | /// Contains the implementation of Scancode Set 2. 9 | /// 10 | /// See the OS dev wiki: 11 | /// Additional reference: 12 | pub struct ScancodeSet2 { 13 | state: DecodeState, 14 | } 15 | 16 | impl ScancodeSet2 { 17 | /// Construct a new [`ScancodeSet2`] decoder. 18 | pub const fn new() -> ScancodeSet2 { 19 | ScancodeSet2 { 20 | state: DecodeState::Start, 21 | } 22 | } 23 | 24 | /// Implements the single byte codes for Set 2. 25 | fn map_scancode(code: u8) -> Result { 26 | match code { 27 | 0x00 => Ok(KeyCode::TooManyKeys), 28 | 0x01 => Ok(KeyCode::F9), 29 | // 0x02 30 | 0x03 => Ok(KeyCode::F5), 31 | 0x04 => Ok(KeyCode::F3), 32 | 0x05 => Ok(KeyCode::F1), 33 | 0x06 => Ok(KeyCode::F2), 34 | 0x07 => Ok(KeyCode::F12), 35 | 0x09 => Ok(KeyCode::F10), 36 | 0x0A => Ok(KeyCode::F8), 37 | 0x0B => Ok(KeyCode::F6), 38 | 0x0C => Ok(KeyCode::F4), 39 | 0x0D => Ok(KeyCode::Tab), 40 | 0x0E => Ok(KeyCode::Oem8), 41 | 0x11 => Ok(KeyCode::LAlt), 42 | 0x12 => Ok(KeyCode::LShift), 43 | 0x13 => Ok(KeyCode::Oem11), 44 | 0x14 => Ok(KeyCode::LControl), 45 | 0x15 => Ok(KeyCode::Q), 46 | 0x16 => Ok(KeyCode::Key1), 47 | 0x1A => Ok(KeyCode::Z), 48 | 0x1B => Ok(KeyCode::S), 49 | 0x1C => Ok(KeyCode::A), 50 | 0x1D => Ok(KeyCode::W), 51 | 0x1E => Ok(KeyCode::Key2), 52 | 0x21 => Ok(KeyCode::C), 53 | 0x22 => Ok(KeyCode::X), 54 | 0x23 => Ok(KeyCode::D), 55 | 0x24 => Ok(KeyCode::E), 56 | 0x25 => Ok(KeyCode::Key4), 57 | 0x26 => Ok(KeyCode::Key3), 58 | 0x29 => Ok(KeyCode::Spacebar), 59 | 0x2A => Ok(KeyCode::V), 60 | 0x2B => Ok(KeyCode::F), 61 | 0x2C => Ok(KeyCode::T), 62 | 0x2D => Ok(KeyCode::R), 63 | 0x2E => Ok(KeyCode::Key5), 64 | 0x31 => Ok(KeyCode::N), 65 | 0x32 => Ok(KeyCode::B), 66 | 0x33 => Ok(KeyCode::H), 67 | 0x34 => Ok(KeyCode::G), 68 | 0x35 => Ok(KeyCode::Y), 69 | 0x36 => Ok(KeyCode::Key6), 70 | 0x3A => Ok(KeyCode::M), 71 | 0x3B => Ok(KeyCode::J), 72 | 0x3C => Ok(KeyCode::U), 73 | 0x3D => Ok(KeyCode::Key7), 74 | 0x3E => Ok(KeyCode::Key8), 75 | 0x41 => Ok(KeyCode::OemComma), 76 | 0x42 => Ok(KeyCode::K), 77 | 0x43 => Ok(KeyCode::I), 78 | 0x44 => Ok(KeyCode::O), 79 | 0x45 => Ok(KeyCode::Key0), 80 | 0x46 => Ok(KeyCode::Key9), 81 | 0x49 => Ok(KeyCode::OemPeriod), 82 | 0x4A => Ok(KeyCode::Oem2), 83 | 0x4B => Ok(KeyCode::L), 84 | 0x4C => Ok(KeyCode::Oem1), 85 | 0x4D => Ok(KeyCode::P), 86 | 0x4E => Ok(KeyCode::OemMinus), 87 | 0x51 => Ok(KeyCode::Oem12), 88 | 0x52 => Ok(KeyCode::Oem3), 89 | 0x54 => Ok(KeyCode::Oem4), 90 | 0x55 => Ok(KeyCode::OemPlus), 91 | 0x58 => Ok(KeyCode::CapsLock), 92 | 0x59 => Ok(KeyCode::RShift), 93 | 0x5A => Ok(KeyCode::Return), 94 | 0x5B => Ok(KeyCode::Oem6), 95 | 0x5D => Ok(KeyCode::Oem7), 96 | 0x61 => Ok(KeyCode::Oem5), 97 | 0x64 => Ok(KeyCode::Oem10), 98 | 0x66 => Ok(KeyCode::Backspace), 99 | 0x67 => Ok(KeyCode::Oem9), 100 | 0x69 => Ok(KeyCode::Numpad1), 101 | 0x6A => Ok(KeyCode::Oem13), 102 | 0x6B => Ok(KeyCode::Numpad4), 103 | 0x6C => Ok(KeyCode::Numpad7), 104 | 0x70 => Ok(KeyCode::Numpad0), 105 | 0x71 => Ok(KeyCode::NumpadPeriod), 106 | 0x72 => Ok(KeyCode::Numpad2), 107 | 0x73 => Ok(KeyCode::Numpad5), 108 | 0x74 => Ok(KeyCode::Numpad6), 109 | 0x75 => Ok(KeyCode::Numpad8), 110 | 0x76 => Ok(KeyCode::Escape), 111 | 0x77 => Ok(KeyCode::NumpadLock), 112 | 0x78 => Ok(KeyCode::F11), 113 | 0x79 => Ok(KeyCode::NumpadAdd), 114 | 0x7A => Ok(KeyCode::Numpad3), 115 | 0x7B => Ok(KeyCode::NumpadSubtract), 116 | 0x7C => Ok(KeyCode::NumpadMultiply), 117 | 0x7D => Ok(KeyCode::Numpad9), 118 | 0x7E => Ok(KeyCode::ScrollLock), 119 | 0x7F => Ok(KeyCode::SysRq), 120 | 0x83 => Ok(KeyCode::F7), 121 | 0xAA => Ok(KeyCode::PowerOnTestOk), 122 | _ => Err(Error::UnknownKeyCode), 123 | } 124 | } 125 | 126 | /// Implements the extended byte codes for set 2 (prefixed with E0) 127 | fn map_extended_scancode(code: u8) -> Result { 128 | match code { 129 | 0x11 => Ok(KeyCode::RAltGr), 130 | 0x12 => Ok(KeyCode::RAlt2), 131 | 0x14 => Ok(KeyCode::RControl), 132 | 0x15 => Ok(KeyCode::PrevTrack), 133 | 0x1F => Ok(KeyCode::LWin), 134 | 0x21 => Ok(KeyCode::VolumeDown), 135 | 0x23 => Ok(KeyCode::Mute), 136 | 0x27 => Ok(KeyCode::RWin), 137 | 0x2B => Ok(KeyCode::Calculator), 138 | 0x2F => Ok(KeyCode::Apps), 139 | 0x32 => Ok(KeyCode::VolumeUp), 140 | 0x34 => Ok(KeyCode::Play), 141 | 0x3A => Ok(KeyCode::WWWHome), 142 | 0x3B => Ok(KeyCode::Stop), 143 | 0x4A => Ok(KeyCode::NumpadDivide), 144 | 0x4D => Ok(KeyCode::NextTrack), 145 | 0x5A => Ok(KeyCode::NumpadEnter), 146 | 0x69 => Ok(KeyCode::End), 147 | 0x6B => Ok(KeyCode::ArrowLeft), 148 | 0x6C => Ok(KeyCode::Home), 149 | 0x70 => Ok(KeyCode::Insert), 150 | 0x71 => Ok(KeyCode::Delete), 151 | 0x72 => Ok(KeyCode::ArrowDown), 152 | 0x74 => Ok(KeyCode::ArrowRight), 153 | 0x75 => Ok(KeyCode::ArrowUp), 154 | 0x7A => Ok(KeyCode::PageDown), 155 | 0x7C => Ok(KeyCode::PrintScreen), 156 | 0x7D => Ok(KeyCode::PageUp), 157 | _ => Err(Error::UnknownKeyCode), 158 | } 159 | } 160 | 161 | /// Implements the alternate extended byte codes for set 2 (prefixed with E1) 162 | fn map_extended2_scancode(code: u8) -> Result { 163 | match code { 164 | 0x14 => Ok(KeyCode::RControl2), 165 | _ => Err(Error::UnknownKeyCode), 166 | } 167 | } 168 | } 169 | 170 | impl ScancodeSet for ScancodeSet2 { 171 | /// Implements state logic for scancode set 2 172 | /// 173 | /// ## Start: 174 | /// * F0 => Goto Release 175 | /// * E0 => Goto Extended 176 | /// * E1 => Goto Extended2 177 | /// * xx => Key Down Event 178 | /// 179 | /// ## Release: 180 | /// * xxx => Key Up Event 181 | /// 182 | /// ## Extended: 183 | /// * F0 => Goto Release-Extended 184 | /// * xx => Extended Key Down Event 185 | /// 186 | /// ## Release-Extended: 187 | /// * xxx => Extended Key Up Event 188 | /// 189 | /// ## Extended2: 190 | /// * F0 => Goto Release-Extended2 191 | /// * xx => Extended2 Key Down Event 192 | /// 193 | /// ## Release-Extended2: 194 | /// * xxx => Extended2 Key Up Event 195 | fn advance_state(&mut self, code: u8) -> Result, Error> { 196 | match self.state { 197 | DecodeState::Start => match code { 198 | EXTENDED_KEY_CODE => { 199 | self.state = DecodeState::Extended; 200 | Ok(None) 201 | } 202 | EXTENDED2_KEY_CODE => { 203 | self.state = DecodeState::Extended2; 204 | Ok(None) 205 | } 206 | KEY_RELEASE_CODE => { 207 | self.state = DecodeState::Release; 208 | Ok(None) 209 | } 210 | _ => { 211 | let keycode = Self::map_scancode(code)?; 212 | if keycode == KeyCode::TooManyKeys || keycode == KeyCode::PowerOnTestOk { 213 | Ok(Some(KeyEvent::new(keycode, KeyState::SingleShot))) 214 | } else { 215 | Ok(Some(KeyEvent::new( 216 | Self::map_scancode(code)?, 217 | KeyState::Down, 218 | ))) 219 | } 220 | } 221 | }, 222 | DecodeState::Release => { 223 | self.state = DecodeState::Start; 224 | Ok(Some(KeyEvent::new(Self::map_scancode(code)?, KeyState::Up))) 225 | } 226 | DecodeState::Extended => match code { 227 | KEY_RELEASE_CODE => { 228 | self.state = DecodeState::ExtendedRelease; 229 | Ok(None) 230 | } 231 | _ => { 232 | self.state = DecodeState::Start; 233 | 234 | let keycode = Self::map_extended_scancode(code)?; 235 | Ok(Some(KeyEvent::new(keycode, KeyState::Down))) 236 | } 237 | }, 238 | DecodeState::ExtendedRelease => { 239 | self.state = DecodeState::Start; 240 | Ok(Some(KeyEvent::new( 241 | Self::map_extended_scancode(code)?, 242 | KeyState::Up, 243 | ))) 244 | } 245 | DecodeState::Extended2 => match code { 246 | KEY_RELEASE_CODE => { 247 | self.state = DecodeState::Extended2Release; 248 | Ok(None) 249 | } 250 | _ => { 251 | self.state = DecodeState::Start; 252 | Ok(Some(KeyEvent::new( 253 | Self::map_extended2_scancode(code)?, 254 | KeyState::Down, 255 | ))) 256 | } 257 | }, 258 | DecodeState::Extended2Release => { 259 | self.state = DecodeState::Start; 260 | Ok(Some(KeyEvent::new( 261 | Self::map_extended2_scancode(code)?, 262 | KeyState::Up, 263 | ))) 264 | } 265 | } 266 | } 267 | } 268 | 269 | impl Default for ScancodeSet2 { 270 | fn default() -> Self { 271 | ScancodeSet2::new() 272 | } 273 | } 274 | 275 | #[cfg(test)] 276 | mod test { 277 | use super::*; 278 | 279 | #[test] 280 | fn validate_scancodes() { 281 | let mut codes = Vec::new(); 282 | let mut errs = Vec::new(); 283 | for code in 0x00..=0xFF { 284 | let r = ScancodeSet2::map_scancode(code); 285 | match r { 286 | Ok(c) => codes.push(c), 287 | Err(_) => errs.push(code), 288 | } 289 | } 290 | codes.sort(); 291 | println!("{:?}", codes); 292 | assert_eq!(codes.len(), 94); 293 | assert_eq!(errs.len(), 162); 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/scancodes/set1.rs: -------------------------------------------------------------------------------- 1 | //! Scan Code Set 1 support 2 | 3 | use crate::{ 4 | DecodeState, Error, KeyCode, KeyEvent, KeyState, ScancodeSet, EXTENDED2_KEY_CODE, 5 | EXTENDED_KEY_CODE, 6 | }; 7 | 8 | /// Contains the implementation of Scancode Set 1. 9 | /// 10 | /// See the OS dev wiki: 11 | pub struct ScancodeSet1 { 12 | state: DecodeState, 13 | } 14 | 15 | impl ScancodeSet1 { 16 | /// Construct a new [`ScancodeSet1`] decoder. 17 | pub const fn new() -> ScancodeSet1 { 18 | ScancodeSet1 { 19 | state: DecodeState::Start, 20 | } 21 | } 22 | 23 | /// Implements the single byte codes for Set 1. 24 | fn map_scancode(code: u8) -> Result { 25 | match code { 26 | 0x01 => Ok(KeyCode::Escape), 27 | 0x02 => Ok(KeyCode::Key1), 28 | 0x03 => Ok(KeyCode::Key2), 29 | 0x04 => Ok(KeyCode::Key3), 30 | 0x05 => Ok(KeyCode::Key4), 31 | 0x06 => Ok(KeyCode::Key5), 32 | 0x07 => Ok(KeyCode::Key6), 33 | 0x08 => Ok(KeyCode::Key7), 34 | 0x09 => Ok(KeyCode::Key8), 35 | 0x0A => Ok(KeyCode::Key9), 36 | 0x0B => Ok(KeyCode::Key0), 37 | 0x0C => Ok(KeyCode::OemMinus), 38 | 0x0D => Ok(KeyCode::OemPlus), 39 | 0x0E => Ok(KeyCode::Backspace), 40 | 0x0F => Ok(KeyCode::Tab), 41 | 0x10 => Ok(KeyCode::Q), 42 | 0x11 => Ok(KeyCode::W), 43 | 0x12 => Ok(KeyCode::E), 44 | 0x13 => Ok(KeyCode::R), 45 | 0x14 => Ok(KeyCode::T), 46 | 0x15 => Ok(KeyCode::Y), 47 | 0x16 => Ok(KeyCode::U), 48 | 0x17 => Ok(KeyCode::I), 49 | 0x18 => Ok(KeyCode::O), 50 | 0x19 => Ok(KeyCode::P), 51 | 0x1A => Ok(KeyCode::Oem4), 52 | 0x1B => Ok(KeyCode::Oem6), 53 | 0x1C => Ok(KeyCode::Return), 54 | 0x1D => Ok(KeyCode::LControl), 55 | 0x1E => Ok(KeyCode::A), 56 | 0x1F => Ok(KeyCode::S), 57 | 0x20 => Ok(KeyCode::D), 58 | 0x21 => Ok(KeyCode::F), 59 | 0x22 => Ok(KeyCode::G), 60 | 0x23 => Ok(KeyCode::H), 61 | 0x24 => Ok(KeyCode::J), 62 | 0x25 => Ok(KeyCode::K), 63 | 0x26 => Ok(KeyCode::L), 64 | 0x27 => Ok(KeyCode::Oem1), 65 | 0x28 => Ok(KeyCode::Oem3), 66 | 0x29 => Ok(KeyCode::Oem8), 67 | 0x2A => Ok(KeyCode::LShift), 68 | 0x2B => Ok(KeyCode::Oem7), 69 | 0x2C => Ok(KeyCode::Z), 70 | 0x2D => Ok(KeyCode::X), 71 | 0x2E => Ok(KeyCode::C), 72 | 0x2F => Ok(KeyCode::V), 73 | 0x30 => Ok(KeyCode::B), 74 | 0x31 => Ok(KeyCode::N), 75 | 0x32 => Ok(KeyCode::M), 76 | 0x33 => Ok(KeyCode::OemComma), 77 | 0x34 => Ok(KeyCode::OemPeriod), 78 | 0x35 => Ok(KeyCode::Oem2), 79 | 0x36 => Ok(KeyCode::RShift), 80 | 0x37 => Ok(KeyCode::NumpadMultiply), 81 | 0x38 => Ok(KeyCode::LAlt), 82 | 0x39 => Ok(KeyCode::Spacebar), 83 | 0x3A => Ok(KeyCode::CapsLock), 84 | 0x3B => Ok(KeyCode::F1), 85 | 0x3C => Ok(KeyCode::F2), 86 | 0x3D => Ok(KeyCode::F3), 87 | 0x3E => Ok(KeyCode::F4), 88 | 0x3F => Ok(KeyCode::F5), 89 | 0x40 => Ok(KeyCode::F6), 90 | 0x41 => Ok(KeyCode::F7), 91 | 0x42 => Ok(KeyCode::F8), 92 | 0x43 => Ok(KeyCode::F9), 93 | 0x44 => Ok(KeyCode::F10), 94 | 0x45 => Ok(KeyCode::NumpadLock), 95 | 0x46 => Ok(KeyCode::ScrollLock), 96 | 0x47 => Ok(KeyCode::Numpad7), 97 | 0x48 => Ok(KeyCode::Numpad8), 98 | 0x49 => Ok(KeyCode::Numpad9), 99 | 0x4A => Ok(KeyCode::NumpadSubtract), 100 | 0x4B => Ok(KeyCode::Numpad4), 101 | 0x4C => Ok(KeyCode::Numpad5), 102 | 0x4D => Ok(KeyCode::Numpad6), 103 | 0x4E => Ok(KeyCode::NumpadAdd), 104 | 0x4F => Ok(KeyCode::Numpad1), 105 | 0x50 => Ok(KeyCode::Numpad2), 106 | 0x51 => Ok(KeyCode::Numpad3), 107 | 0x52 => Ok(KeyCode::Numpad0), 108 | 0x53 => Ok(KeyCode::NumpadPeriod), 109 | 0x54 => Ok(KeyCode::SysRq), 110 | // 0x55 is unused? 111 | 0x56 => Ok(KeyCode::Oem5), 112 | 0x57 => Ok(KeyCode::F11), 113 | 0x58 => Ok(KeyCode::F12), 114 | _ => Err(Error::UnknownKeyCode), 115 | } 116 | } 117 | 118 | /// Implements the extended byte codes for set 1 (prefixed with E0) 119 | fn map_extended_scancode(code: u8) -> Result { 120 | match code { 121 | 0x10 => Ok(KeyCode::PrevTrack), 122 | //0x11 123 | //0x12 124 | //0x13 125 | //0x14 126 | //0x15 127 | //0x16 128 | //0x17 129 | //0x18 130 | 0x19 => Ok(KeyCode::NextTrack), 131 | //0x1A 132 | //0x1B 133 | 0x1C => Ok(KeyCode::NumpadEnter), 134 | 0x1D => Ok(KeyCode::RControl), 135 | //0x1E 136 | //0x1F 137 | 0x20 => Ok(KeyCode::Mute), 138 | 0x21 => Ok(KeyCode::Calculator), 139 | 0x22 => Ok(KeyCode::Play), 140 | //0x23 141 | 0x24 => Ok(KeyCode::Stop), 142 | //0x25 143 | //0x26 144 | //0x27 145 | //0x28 146 | //0x29 147 | 0x2A => Ok(KeyCode::RAlt2), 148 | //0x2B 149 | //0x2C 150 | //0x2D 151 | 0x2E => Ok(KeyCode::VolumeDown), 152 | //0x2F 153 | 0x30 => Ok(KeyCode::VolumeUp), 154 | //0x31 155 | 0x32 => Ok(KeyCode::WWWHome), 156 | //0x33 157 | //0x34 158 | 0x35 => Ok(KeyCode::NumpadDivide), 159 | //0x36 160 | 0x37 => Ok(KeyCode::PrintScreen), 161 | 0x38 => Ok(KeyCode::RAltGr), 162 | //0x39 163 | //0x3A 164 | //0x3B 165 | //0x3C 166 | //0x3D 167 | //0x3E 168 | //0x3F 169 | //0x40 170 | //0x41 171 | //0x42 172 | //0x43 173 | //0x44 174 | //0x45 175 | //0x46 176 | 0x47 => Ok(KeyCode::Home), 177 | 0x48 => Ok(KeyCode::ArrowUp), 178 | 0x49 => Ok(KeyCode::PageUp), 179 | //0x4A 180 | 0x4B => Ok(KeyCode::ArrowLeft), 181 | //0x4C 182 | 0x4D => Ok(KeyCode::ArrowRight), 183 | //0x4E 184 | 0x4F => Ok(KeyCode::End), 185 | 0x50 => Ok(KeyCode::ArrowDown), 186 | 0x51 => Ok(KeyCode::PageDown), 187 | 0x52 => Ok(KeyCode::Insert), 188 | 0x53 => Ok(KeyCode::Delete), 189 | 0x5B => Ok(KeyCode::LWin), 190 | 0x5C => Ok(KeyCode::RWin), 191 | 0x5D => Ok(KeyCode::Apps), 192 | // 0x5E ACPI Power 193 | // 0x5F ACPI Sleep 194 | // 0x60 195 | // 0x61 196 | // 0x62 197 | // 0x63 ACPI Wake 198 | // 0x64 199 | // 0x65 WWW Search 200 | // 0x66 WWW Favourites 201 | // 0x67 WWW Refresh 202 | // 0x68 WWW Stop 203 | // 0x69 WWW Forward 204 | // 0x6A WWW Back 205 | // 0x6B My Computer 206 | // 0x6C Email 207 | // 0x6D Media Select 208 | 0x70 => Ok(KeyCode::Oem11), 209 | 0x73 => Ok(KeyCode::Oem12), 210 | 0x79 => Ok(KeyCode::Oem10), 211 | 0x7B => Ok(KeyCode::Oem9), 212 | 0x7D => Ok(KeyCode::Oem13), 213 | _ => Err(Error::UnknownKeyCode), 214 | } 215 | } 216 | 217 | /// Implements the extended byte codes for set 1 (prefixed with E1) 218 | fn map_extended2_scancode(code: u8) -> Result { 219 | match code { 220 | 0x1D => Ok(KeyCode::RControl2), 221 | _ => Err(Error::UnknownKeyCode), 222 | } 223 | } 224 | } 225 | 226 | impl ScancodeSet for ScancodeSet1 { 227 | /// Implements state logic for scancode set 1 228 | /// 229 | /// ## Start: 230 | /// * `E0` => Goto Extended 231 | /// * `E1` => Goto Extended 2 232 | /// * `< 0x80` => Key Down 233 | /// * `>= 0x80` => Key Up 234 | /// 235 | /// ## Extended: 236 | /// * `< 0x80` => Extended Key Down 237 | /// * `>= 0x80` => Extended Key Up 238 | /// 239 | /// ## Extended 2: 240 | /// * `< 0x80` => Extended 2 Key Down 241 | /// * `>= 0x80` => Extended 2 Key Up 242 | fn advance_state(&mut self, code: u8) -> Result, Error> { 243 | match self.state { 244 | DecodeState::Start => { 245 | match code { 246 | EXTENDED_KEY_CODE => { 247 | self.state = DecodeState::Extended; 248 | Ok(None) 249 | } 250 | EXTENDED2_KEY_CODE => { 251 | self.state = DecodeState::Extended2; 252 | Ok(None) 253 | } 254 | 0x80..=0xFF => { 255 | // Break codes 256 | Ok(Some(KeyEvent::new( 257 | Self::map_scancode(code - 0x80)?, 258 | KeyState::Up, 259 | ))) 260 | } 261 | _ => { 262 | // Make codes 263 | Ok(Some(KeyEvent::new( 264 | Self::map_scancode(code)?, 265 | KeyState::Down, 266 | ))) 267 | } 268 | } 269 | } 270 | DecodeState::Extended => { 271 | self.state = DecodeState::Start; 272 | match code { 273 | 0x80..=0xFF => { 274 | // Extended break codes 275 | Ok(Some(KeyEvent::new( 276 | Self::map_extended_scancode(code - 0x80)?, 277 | KeyState::Up, 278 | ))) 279 | } 280 | _ => { 281 | // Extended make codes 282 | Ok(Some(KeyEvent::new( 283 | Self::map_extended_scancode(code)?, 284 | KeyState::Down, 285 | ))) 286 | } 287 | } 288 | } 289 | DecodeState::Extended2 => { 290 | self.state = DecodeState::Start; 291 | match code { 292 | 0x80..=0xFF => { 293 | // Extended 2 break codes 294 | Ok(Some(KeyEvent::new( 295 | Self::map_extended2_scancode(code - 0x80)?, 296 | KeyState::Up, 297 | ))) 298 | } 299 | _ => { 300 | // Extended 2 make codes 301 | Ok(Some(KeyEvent::new( 302 | Self::map_extended2_scancode(code)?, 303 | KeyState::Down, 304 | ))) 305 | } 306 | } 307 | } 308 | _ => { 309 | // Can't get in to this state 310 | unimplemented!(); 311 | } 312 | } 313 | } 314 | } 315 | 316 | impl Default for ScancodeSet1 { 317 | fn default() -> Self { 318 | ScancodeSet1::new() 319 | } 320 | } 321 | 322 | #[cfg(test)] 323 | mod test { 324 | use super::*; 325 | 326 | #[test] 327 | fn validate_scancodes() { 328 | let mut codes = Vec::new(); 329 | let mut errs = Vec::new(); 330 | for code in 0x00..=0x7F { 331 | let r = ScancodeSet1::map_scancode(code); 332 | match r { 333 | Ok(c) => codes.push(c), 334 | Err(_) => errs.push(code), 335 | } 336 | } 337 | codes.sort(); 338 | println!("{:?}", codes); 339 | assert_eq!(codes.len(), 87); 340 | assert_eq!(errs.len(), 41); 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /src/layouts/colemak.rs: -------------------------------------------------------------------------------- 1 | //! Colemak keyboard support 2 | 3 | use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; 4 | 5 | /// A Colemak 101-key (or 104-key including Windows keys) keyboard. 6 | /// 7 | /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). 8 | /// 9 | /// Based on US 101/104 key, with the letters re-arranged. 10 | /// 11 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 12 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 13 | /// printable character. Blank spaces are passed through as 14 | /// [`DecodedKey::RawKey`]. 15 | /// 16 | /// Run the `print_keyboard` example to re-generate these images. 17 | /// 18 | /// ## Unmodified 19 | /// 20 | /// ```text 21 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 22 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 23 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 24 | /// 25 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 26 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 27 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 28 | /// │0009 │ q │ w │ f │ p │ g │ j │ l │ u │ y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 29 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 30 | /// │ │ a │ r │ s │ t │ d │ h │ n │ e │ i │ o │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 31 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 32 | /// │ │ z │ x │ c │ v │ b │ k │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 33 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 34 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 35 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 36 | /// ``` 37 | /// 38 | /// ## Caps Lock 39 | /// 40 | /// ```text 41 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 42 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 43 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 44 | /// 45 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 46 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 47 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 48 | /// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 49 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 50 | /// │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 51 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 52 | /// │ │ Z │ X │ C │ V │ B │ K │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 53 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 54 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 55 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 56 | /// ``` 57 | /// 58 | /// ## Shifted 59 | /// 60 | /// ```text 61 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 62 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 63 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 64 | /// 65 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 66 | /// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 67 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 68 | /// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ : │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 69 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 70 | /// │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ " │ 000a │ │ 4 │ 5 │ 6 │ │ 71 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 72 | /// │ │ Z │ X │ C │ V │ B │ K │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ 73 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 74 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 75 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 76 | /// ``` 77 | /// 78 | /// ## Control 79 | /// 80 | /// ```text 81 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 82 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 83 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 84 | /// 85 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 86 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 87 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 88 | /// │0009 │0011│0017│0006│0010│0007│000a│000c│0015│0019│ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 89 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 90 | /// │ │0001│0012│0013│0014│0004│0008│000e│0005│0009│000f│ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 91 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 92 | /// │ │001a│0018│0003│0016│0002│000b│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 93 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 94 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 95 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 96 | /// ``` 97 | /// 98 | /// ## AltGr 99 | /// 100 | /// ```text 101 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 102 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 103 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 104 | /// 105 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 106 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 107 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 108 | /// │0009 │ q │ w │ f │ p │ g │ j │ l │ u │ y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 109 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 110 | /// │ │ a │ r │ s │ t │ d │ h │ n │ e │ i │ o │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 111 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 112 | /// │ │ z │ x │ c │ v │ b │ k │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 113 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 114 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 115 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 116 | /// ``` 117 | /// 118 | /// ## Shift AltGr 119 | /// 120 | /// ```text 121 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 122 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 123 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 124 | /// 125 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 126 | /// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 127 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 128 | /// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ : │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 129 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 130 | /// │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ " │ 000a │ │ 4 │ 5 │ 6 │ │ 131 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 132 | /// │ │ Z │ X │ C │ V │ B │ K │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ 133 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 134 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 135 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 136 | /// ``` 137 | pub struct Colemak; 138 | 139 | impl KeyboardLayout for Colemak { 140 | #[rustfmt::skip] 141 | fn map_keycode( 142 | &self, 143 | keycode: KeyCode, 144 | modifiers: &Modifiers, 145 | handle_ctrl: HandleControl, 146 | ) -> DecodedKey { 147 | match keycode { 148 | // ========= Row 3 (QWERTY) ========= 149 | KeyCode::E => modifiers.handle_ascii_2('F', handle_ctrl), 150 | KeyCode::R => modifiers.handle_ascii_2('P', handle_ctrl), 151 | KeyCode::T => modifiers.handle_ascii_2('G', handle_ctrl), 152 | KeyCode::Y => modifiers.handle_ascii_2('J', handle_ctrl), 153 | KeyCode::U => modifiers.handle_ascii_2('L', handle_ctrl), 154 | KeyCode::I => modifiers.handle_ascii_2('U', handle_ctrl), 155 | KeyCode::O => modifiers.handle_ascii_2('Y', handle_ctrl), 156 | KeyCode::P => modifiers.handle_symbol2(';', ':'), 157 | // ========= Row 4 (ASDFG) ========= 158 | KeyCode::S => modifiers.handle_ascii_2('R', handle_ctrl), 159 | KeyCode::D => modifiers.handle_ascii_2('S', handle_ctrl), 160 | KeyCode::F => modifiers.handle_ascii_2('T', handle_ctrl), 161 | KeyCode::G => modifiers.handle_ascii_2('D', handle_ctrl), 162 | KeyCode::J => modifiers.handle_ascii_2('N', handle_ctrl), 163 | KeyCode::K => modifiers.handle_ascii_2('E', handle_ctrl), 164 | KeyCode::L => modifiers.handle_ascii_2('I', handle_ctrl), 165 | KeyCode::Oem1 => modifiers.handle_ascii_2('O', handle_ctrl), 166 | // ========= Row 5 (ZXCVB) ========= 167 | KeyCode::N => modifiers.handle_ascii_2('K', handle_ctrl), 168 | // ========= Fallback ========= 169 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 170 | } 171 | } 172 | 173 | fn get_physical(&self) -> PhysicalKeyboard { 174 | PhysicalKeyboard::Ansi 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/layouts/jis109.rs: -------------------------------------------------------------------------------- 1 | //! JIS keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard Japan 106-key (or 109-key including Windows keys) keyboard. 8 | /// 9 | /// Has a small space bar, to fit in extra keys. 10 | /// 11 | /// We used as a 12 | /// reference. 13 | /// 14 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 15 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 16 | /// printable character. Blank spaces are passed through as 17 | /// [`DecodedKey::RawKey`]. 18 | /// 19 | /// Run the `print_keyboard` example to re-generate these images. 20 | /// 21 | /// ## Unmodified 22 | /// 23 | /// ```text 24 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 25 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 26 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 27 | /// 28 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 29 | /// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ 30 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 31 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 32 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 33 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ 34 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ 35 | /// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ 36 | /// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 37 | /// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 38 | /// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 39 | /// ``` 40 | /// 41 | /// ## Caps Lock 42 | /// 43 | /// ```text 44 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 45 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 46 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 47 | /// 48 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 49 | /// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ 50 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 51 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 52 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 53 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ 54 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ 55 | /// │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ 56 | /// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 57 | /// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 58 | /// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 59 | /// ``` 60 | /// 61 | /// ## Shifted 62 | /// 63 | /// ```text 64 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 65 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 66 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 67 | /// 68 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 69 | /// │ │ ! │ " │ # │ $ │ % │ & │ ' │ ( │ ) │ ~ │ = │ ¯ │ | │0008│ │ │ │ │ │ │ / │ * │ - │ 70 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 71 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ` │ { │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 72 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 73 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ + │ * │ } │ │ │ 4 │ 5 │ 6 │ │ 74 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ 75 | /// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 76 | /// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 77 | /// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 78 | /// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 79 | /// ``` 80 | /// 81 | /// ## Control 82 | /// 83 | /// ```text 84 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 85 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 86 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 87 | /// 88 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 89 | /// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ 90 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 91 | /// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 92 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 93 | /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ 94 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ 95 | /// │ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ 96 | /// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 97 | /// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 98 | /// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 99 | /// ``` 100 | /// 101 | /// ## AltGr 102 | /// 103 | /// ```text 104 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 105 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 106 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 107 | /// 108 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 109 | /// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ 110 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 111 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 112 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 113 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ 114 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ 115 | /// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ 116 | /// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 117 | /// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 118 | /// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 119 | /// ``` 120 | /// 121 | /// ## Shift AltGr 122 | /// 123 | /// ```text 124 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 125 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 126 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 127 | /// 128 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 129 | /// │ │ ! │ " │ # │ $ │ % │ & │ ' │ ( │ ) │ ~ │ = │ ¯ │ | │0008│ │ │ │ │ │ │ / │ * │ - │ 130 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 131 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ` │ { │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 132 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 133 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ + │ * │ } │ │ │ 4 │ 5 │ 6 │ │ 134 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ 135 | /// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 136 | /// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 137 | /// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 138 | /// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 139 | /// ``` 140 | pub struct Jis109Key; 141 | 142 | impl KeyboardLayout for Jis109Key { 143 | #[rustfmt::skip] 144 | fn map_keycode( 145 | &self, 146 | keycode: KeyCode, 147 | modifiers: &Modifiers, 148 | handle_ctrl: HandleControl, 149 | ) -> DecodedKey { 150 | match keycode { 151 | // ========= Row 2 (the numbers) ========= 152 | // hankaku/zenkaku/kanji 153 | KeyCode::Oem8 => DecodedKey::RawKey(keycode), 154 | KeyCode::Key2 => modifiers.handle_symbol2('2', '"'), 155 | KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), 156 | KeyCode::Key7 => modifiers.handle_symbol2('7', QUO), 157 | KeyCode::Key8 => modifiers.handle_symbol2('8', '('), 158 | KeyCode::Key9 => modifiers.handle_symbol2('9', ')'), 159 | KeyCode::Key0 => modifiers.handle_symbol2('0', '~'), 160 | KeyCode::OemMinus => modifiers.handle_symbol2('-', '='), 161 | KeyCode::OemPlus => modifiers.handle_symbol2('^', '¯'), 162 | KeyCode::Oem13 => modifiers.handle_symbol2('¥', '|'), 163 | // ========= Row 3 (QWERTY) ========= 164 | KeyCode::Oem4 => modifiers.handle_symbol2('@', '`'), 165 | KeyCode::Oem6 => modifiers.handle_symbol2('[', '{'), 166 | // ========= Row 4 (ASDFG) ========= 167 | KeyCode::Oem1 => modifiers.handle_symbol2(';', '+'), 168 | KeyCode::Oem3 => modifiers.handle_symbol2(':', '*'), 169 | KeyCode::Oem7 => modifiers.handle_symbol2(']', '}'), 170 | // ========= Row 5 (ZXCVB) ========= 171 | KeyCode::Oem12 => modifiers.handle_symbol2(SLS, '_'), 172 | // ========= Modifiers ========= 173 | // Muhenkan 174 | KeyCode::Oem9 => DecodedKey::RawKey(keycode), 175 | // Henkan/Zenkouho 176 | KeyCode::Oem10 => DecodedKey::RawKey(keycode), 177 | // Hiragana/Katakana 178 | KeyCode::Oem11 => DecodedKey::RawKey(keycode), 179 | // ========= Fallback ========= 180 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl) 181 | } 182 | } 183 | 184 | fn get_physical(&self) -> PhysicalKeyboard { 185 | PhysicalKeyboard::Jis 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/layouts/de105.rs: -------------------------------------------------------------------------------- 1 | //! German keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard German 102-key (or 105-key including Windows keys) keyboard. 8 | /// 9 | /// The top row spells `QWERTZ`. 10 | /// 11 | /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). 12 | /// 13 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 14 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 15 | /// printable character. Blank spaces are passed through as 16 | /// [`DecodedKey::RawKey`]. 17 | /// 18 | /// Run the `print_keyboard` example to re-generate these images. 19 | /// 20 | /// ## Unmodified 21 | /// 22 | /// ```text 23 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 24 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 25 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 26 | /// 27 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 28 | /// │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 29 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 30 | /// │0009 │ q │ w │ e │ r │ t │ z │ u │ i │ o │ p │ ü │ + │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 31 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 32 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ # │ │ │ 4 │ 5 │ 6 │ │ 33 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 34 | /// │ │ < │ y │ x │ c │ v │ b │ n │ m │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 35 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 36 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 37 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 38 | /// ``` 39 | /// 40 | /// ## Caps Lock 41 | /// 42 | /// ```text 43 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 44 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 45 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 46 | /// 47 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 48 | /// │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 49 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 50 | /// │0009 │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ Ü │ + │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 51 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 52 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ # │ │ │ 4 │ 5 │ 6 │ │ 53 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 54 | /// │ │ < │ Y │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 55 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 56 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 57 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 58 | /// ``` 59 | /// 60 | /// ## Shifted 61 | /// 62 | /// ```text 63 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 64 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 65 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 66 | /// 67 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 68 | /// │ ° │ ! │ " │ § │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 69 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 70 | /// │0009 │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ Ü │ * │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 71 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 72 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ ' │ │ │ 4 │ 5 │ 6 │ │ 73 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 74 | /// │ │ > │ Y │ X │ C │ V │ B │ N │ M │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 75 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 76 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 77 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 78 | /// ``` 79 | /// 80 | /// ## Control 81 | /// 82 | /// ```text 83 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 84 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 85 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 86 | /// 87 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 88 | /// │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 89 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 90 | /// │0009 │0011│0017│0005│0012│0014│001a│0015│0009│000f│0010│ ü │ + │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 91 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 92 | /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ö │ ä │ # │ │ │ 4 │ 5 │ 6 │ │ 93 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 94 | /// │ │ < │0019│0018│0003│0016│0002│000e│000d│ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 95 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 96 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 97 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 98 | /// ``` 99 | /// 100 | /// ## AltGr 101 | /// 102 | /// ```text 103 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 104 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 105 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 106 | /// 107 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 108 | /// │ ^ │ 1 │ ² │ ³ │ 4 │ 5 │ 6 │ { │ [ │ ] │ } │ \ │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 109 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 110 | /// │0009 │ @ │ w │ € │ r │ t │ z │ u │ i │ o │ p │ ü │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 111 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 112 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ # │ │ │ 4 │ 5 │ 6 │ │ 113 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 114 | /// │ │ | │ y │ x │ c │ v │ b │ n │ µ │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 115 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 116 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 117 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 118 | /// ``` 119 | /// 120 | /// ## Shift AltGr 121 | /// 122 | /// ```text 123 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 124 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 125 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 126 | /// 127 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 128 | /// │ ° │ ! │ ² │ ³ │ $ │ % │ & │ { │ [ │ ] │ } │ \ │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 129 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 130 | /// │0009 │ @ │ W │ € │ R │ T │ Z │ U │ I │ O │ P │ Ü │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 131 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 132 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ ' │ │ │ 4 │ 5 │ 6 │ │ 133 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 134 | /// │ │ | │ Y │ X │ C │ V │ B │ N │ µ │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 135 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 136 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 137 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 138 | /// ``` 139 | pub struct De105Key; 140 | 141 | impl KeyboardLayout for De105Key { 142 | #[rustfmt::skip] 143 | fn map_keycode( 144 | &self, 145 | keycode: KeyCode, 146 | modifiers: &Modifiers, 147 | handle_ctrl: HandleControl, 148 | ) -> DecodedKey { 149 | match keycode { 150 | // ========= Row 2 (the numbers) ========= 151 | KeyCode::Oem8 => modifiers.handle_symbol2('^', '°'), 152 | KeyCode::Key2 => modifiers.handle_symbol3('2', '"', '²'), 153 | KeyCode::Key3 => modifiers.handle_symbol3('3', '§', '³'), 154 | KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), 155 | KeyCode::Key7 => modifiers.handle_symbol3('7', '/', '{'), 156 | KeyCode::Key8 => modifiers.handle_symbol3('8', '(', '['), 157 | KeyCode::Key9 => modifiers.handle_symbol3('9', ')', ']'), 158 | KeyCode::Key0 => modifiers.handle_symbol3('0', '=', '}'), 159 | KeyCode::OemMinus => modifiers.handle_symbol3('ß', '?', SLS), 160 | KeyCode::OemPlus => modifiers.handle_symbol2('´', '`'), 161 | // ========= Row 3 (QWERTY) ========= 162 | KeyCode::Q => modifiers.handle_ascii_3('Q', '@', handle_ctrl), 163 | KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), 164 | KeyCode::Y => modifiers.handle_ascii_2('Z', handle_ctrl), 165 | KeyCode::Oem4 => modifiers.handle_letter2('ü', 'Ü'), 166 | KeyCode::Oem6 => modifiers.handle_symbol3('+', '*', '~'), 167 | // ========= Row 4 (ASDFG) ========= 168 | KeyCode::Oem1 => modifiers.handle_letter2('ö', 'Ö'), 169 | KeyCode::Oem3 => modifiers.handle_letter2('ä', 'Ä'), 170 | KeyCode::Oem7 => modifiers.handle_symbol2('#', QUO), 171 | // ========= Row 5 (ZXCVB) ========= 172 | KeyCode::Oem5 => modifiers.handle_symbol3('<', '>', '|'), 173 | KeyCode::Z => modifiers.handle_ascii_2('Y', handle_ctrl), 174 | KeyCode::M => modifiers.handle_ascii_3('M', 'µ', handle_ctrl), 175 | KeyCode::OemComma => modifiers.handle_symbol2(',', ';'), 176 | KeyCode::OemPeriod => modifiers.handle_symbol2('.', ':'), 177 | KeyCode::Oem2 => modifiers.handle_symbol2('-', '_'), 178 | // ========= Fallback ========= 179 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 180 | } 181 | } 182 | 183 | fn get_physical(&self) -> PhysicalKeyboard { 184 | PhysicalKeyboard::Iso 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/layouts/no105.rs: -------------------------------------------------------------------------------- 1 | //! Norwegian keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard Norwegian 102-key (or 105-key including Windows keys) keyboard. 8 | /// 9 | /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). 10 | /// 11 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 12 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 13 | /// printable character. Blank spaces are passed through as 14 | /// [`DecodedKey::RawKey`]. 15 | /// 16 | /// Run the `print_keyboard` example to re-generate these images. 17 | /// 18 | /// ## Unmodified 19 | /// 20 | /// ```text 21 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 22 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 23 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 24 | /// 25 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 26 | /// │ | │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ \ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 27 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 28 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 29 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 30 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ø │ æ │ ' │ │ │ 4 │ 5 │ 6 │ │ 31 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 32 | /// │ │ < │ z │ x │ c │ v │ b │ n │ m │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 33 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 34 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 35 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 36 | /// ``` 37 | /// 38 | /// ## Caps Lock 39 | /// 40 | /// ```text 41 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 42 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 43 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 44 | /// 45 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 46 | /// │ | │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ \ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 47 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 48 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 49 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 50 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ø │ Æ │ ' │ │ │ 4 │ 5 │ 6 │ │ 51 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 52 | /// │ │ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 53 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 54 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 55 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 56 | /// ``` 57 | /// 58 | /// ## Shifted 59 | /// 60 | /// ```text 61 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 62 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 63 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 64 | /// 65 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 66 | /// │ § │ ! │ " │ # │ ¤ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 67 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 68 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ^ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 69 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 70 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ø │ Æ │ * │ │ │ 4 │ 5 │ 6 │ │ 71 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 72 | /// │ │ > │ Z │ X │ C │ V │ B │ N │ M │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 73 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 74 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 75 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 76 | /// ``` 77 | /// 78 | /// ## Control 79 | /// 80 | /// ```text 81 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 82 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 83 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 84 | /// 85 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 86 | /// │ | │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ \ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 87 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 88 | /// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 89 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 90 | /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ø │ æ │ ' │ │ │ 4 │ 5 │ 6 │ │ 91 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 92 | /// │ │ < │001a│0018│0003│0016│0002│000e│000d│ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 93 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 94 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 95 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 96 | /// ``` 97 | /// 98 | /// ## AltGr 99 | /// 100 | /// ```text 101 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 102 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 103 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 104 | /// 105 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 106 | /// │ | │ 1 │ @ │ £ │ $ │ 5 │ 6 │ { │ [ │ ] │ } │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 107 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 108 | /// │0009 │ q │ w │ € │ r │ t │ y │ u │ i │ o │ p │ å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 109 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 110 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ø │ æ │ ' │ │ │ 4 │ 5 │ 6 │ │ 111 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 112 | /// │ │ < │ z │ x │ c │ v │ b │ n │ µ │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 113 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 114 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 115 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 116 | /// ``` 117 | /// 118 | /// ## Shift AltGr 119 | /// 120 | /// ```text 121 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 122 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 123 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 124 | /// 125 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 126 | /// │ § │ ! │ @ │ £ │ $ │ % │ & │ { │ [ │ ] │ } │ ? │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 127 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 128 | /// │0009 │ Q │ W │ € │ R │ T │ Y │ U │ I │ O │ P │ Å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 129 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 130 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ø │ Æ │ * │ │ │ 4 │ 5 │ 6 │ │ 131 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 132 | /// │ │ > │ Z │ X │ C │ V │ B │ N │ µ │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 133 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 134 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 135 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 136 | /// ``` 137 | pub struct No105Key; 138 | 139 | impl KeyboardLayout for No105Key { 140 | #[rustfmt::skip] 141 | fn map_keycode( 142 | &self, 143 | keycode: KeyCode, 144 | modifiers: &Modifiers, 145 | handle_ctrl: HandleControl, 146 | ) -> DecodedKey { 147 | match keycode { 148 | // ========= Row 2 (the numbers) ========= 149 | KeyCode::Oem8 => modifiers.handle_symbol2('|', '§'), 150 | KeyCode::Key2 => modifiers.handle_symbol3('2', '"', '@'), 151 | KeyCode::Key3 => modifiers.handle_symbol3('3', '#', '£'), 152 | KeyCode::Key4 => modifiers.handle_symbol3('4', '¤', '$'), 153 | KeyCode::Key5 => modifiers.handle_symbol2('5', '%'), 154 | KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), 155 | KeyCode::Key7 => modifiers.handle_symbol3('7', '/', '{'), 156 | KeyCode::Key8 => modifiers.handle_symbol3('8', '(', '['), 157 | KeyCode::Key9 => modifiers.handle_symbol3('9', ')', ']'), 158 | KeyCode::Key0 => modifiers.handle_symbol3('0', '=', '}'), 159 | KeyCode::OemMinus => modifiers.handle_symbol2('+', '?'), 160 | KeyCode::OemPlus => modifiers.handle_symbol3(SLS, '`', '´'), 161 | // ========= Row 3 (QWERTY) ========= 162 | KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), 163 | KeyCode::Oem4 => modifiers.handle_letter2('å', 'Å'), 164 | KeyCode::Oem6 => modifiers.handle_symbol3('¨', '^', '~'), 165 | // ========= Row 4 (ASDF) ========= 166 | KeyCode::Oem7 => modifiers.handle_symbol2(QUO, '*'), 167 | KeyCode::Oem1 => modifiers.handle_letter2('ø', 'Ø'), 168 | KeyCode::Oem3 => modifiers.handle_letter2('æ', 'Æ'), 169 | // ========= Row 5 (ZXCV) ========= 170 | KeyCode::Oem5 => modifiers.handle_symbol2('<', '>'), 171 | KeyCode::M => modifiers.handle_ascii_3('M', 'µ', handle_ctrl), 172 | KeyCode::OemComma => modifiers.handle_symbol2(',', ';'), 173 | KeyCode::OemPeriod => modifiers.handle_symbol2('.', ':'), 174 | KeyCode::Oem2 => modifiers.handle_symbol2('-', '_'), 175 | // ========= Row 6 (modifers and space bar) ========= 176 | KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), 177 | // ========= Fallback ========= 178 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 179 | } 180 | } 181 | 182 | fn get_physical(&self) -> PhysicalKeyboard { 183 | PhysicalKeyboard::Iso 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/layouts/fi_se105.rs: -------------------------------------------------------------------------------- 1 | //! Finnish/Swedish keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard Finnish/Swedish 102-key (or 105-key including Windows keys) keyboard. 8 | /// 9 | /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). 10 | /// 11 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 12 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 13 | /// printable character. Blank spaces are passed through as 14 | /// [`DecodedKey::RawKey`]. 15 | /// 16 | /// Run the `print_keyboard` example to re-generate these images. 17 | /// 18 | /// ## Unmodified 19 | /// 20 | /// ```text 21 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 22 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 23 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 24 | /// 25 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 26 | /// │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 27 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 28 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 29 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 30 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ ' │ │ │ 4 │ 5 │ 6 │ │ 31 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 32 | /// │ │ < │ z │ x │ c │ v │ b │ n │ m │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 33 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 34 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 35 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 36 | /// ``` 37 | /// 38 | /// ## Caps Lock 39 | /// 40 | /// ```text 41 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 42 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 43 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 44 | /// 45 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 46 | /// │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 47 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 48 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 49 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 50 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ ' │ │ │ 4 │ 5 │ 6 │ │ 51 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 52 | /// │ │ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 53 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 54 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 55 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 56 | /// ``` 57 | /// 58 | /// ## Shifted 59 | /// 60 | /// ```text 61 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 62 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 63 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 64 | /// 65 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 66 | /// │ ½ │ ! │ " │ # │ ¤ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 67 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 68 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ^ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 69 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 70 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ * │ │ │ 4 │ 5 │ 6 │ │ 71 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 72 | /// │ │ > │ Z │ X │ C │ V │ B │ N │ M │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 73 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 74 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 75 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 76 | /// ``` 77 | /// 78 | /// ## Control 79 | /// 80 | /// ```text 81 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 82 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 83 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 84 | /// 85 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 86 | /// │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 87 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 88 | /// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 89 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 90 | /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ö │ ä │ ' │ │ │ 4 │ 5 │ 6 │ │ 91 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 92 | /// │ │ < │001a│0018│0003│0016│0002│000e│000d│ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 93 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 94 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 95 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 96 | /// ``` 97 | /// 98 | /// ## AltGr 99 | /// 100 | /// ```text 101 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 102 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 103 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 104 | /// 105 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 106 | /// │ § │ 1 │ @ │ £ │ $ │ € │ 6 │ { │ [ │ ] │ } │ \ │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 107 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 108 | /// │0009 │ q │ w │ € │ r │ t │ y │ u │ i │ o │ p │ å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 109 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 110 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ ' │ │ │ 4 │ 5 │ 6 │ │ 111 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 112 | /// │ │ | │ z │ x │ c │ v │ b │ n │ µ │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ 113 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 114 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 115 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 116 | /// ``` 117 | /// 118 | /// ## Shift AltGr 119 | /// 120 | /// ```text 121 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 122 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 123 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 124 | /// 125 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 126 | /// │ ½ │ ! │ @ │ £ │ $ │ € │ & │ { │ [ │ ] │ } │ \ │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 127 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 128 | /// │0009 │ Q │ W │ € │ R │ T │ Y │ U │ I │ O │ P │ Å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 129 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 130 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ * │ │ │ 4 │ 5 │ 6 │ │ 131 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 132 | /// │ │ | │ Z │ X │ C │ V │ B │ N │ µ │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ 133 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 134 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ 135 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 136 | /// ``` 137 | pub struct FiSe105Key; 138 | 139 | impl KeyboardLayout for FiSe105Key { 140 | #[rustfmt::skip] 141 | fn map_keycode( 142 | &self, 143 | keycode: KeyCode, 144 | modifiers: &Modifiers, 145 | handle_ctrl: HandleControl, 146 | ) -> DecodedKey { 147 | match keycode { 148 | // ========= Row 2 (the numbers) ========= 149 | KeyCode::Oem8 => modifiers.handle_symbol2('§', '½'), 150 | KeyCode::Key2 => modifiers.handle_symbol3('2', '"', '@'), 151 | KeyCode::Key3 => modifiers.handle_symbol3('3', '#', '£'), 152 | KeyCode::Key4 => modifiers.handle_symbol3('4', '¤', '$'), 153 | KeyCode::Key5 => modifiers.handle_symbol3('5', '%', '€'), 154 | KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), 155 | KeyCode::Key7 => modifiers.handle_symbol3('7', '/', '{'), 156 | KeyCode::Key8 => modifiers.handle_symbol3('8', '(', '['), 157 | KeyCode::Key9 => modifiers.handle_symbol3('9', ')', ']'), 158 | KeyCode::Key0 => modifiers.handle_symbol3('0', '=', '}'), 159 | KeyCode::OemMinus => modifiers.handle_symbol3('+', '?', SLS), 160 | KeyCode::OemPlus => modifiers.handle_symbol2('´', '`'), 161 | // ========= Row 3 (QWERTY) ========= 162 | KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), 163 | KeyCode::Oem4 => modifiers.handle_letter2('å', 'Å'), 164 | KeyCode::Oem6 => modifiers.handle_symbol3('¨', '^', '~'), 165 | // ========= Row 4 (ASDF) ========= 166 | KeyCode::Oem1 => modifiers.handle_letter2('ö', 'Ö'), 167 | KeyCode::Oem3 => modifiers.handle_letter2('ä', 'Ä'), 168 | KeyCode::Oem7 => modifiers.handle_symbol2(QUO, '*'), 169 | // ========= Row 5 (ZXCV) ========= 170 | KeyCode::Oem5 => modifiers.handle_symbol3('<', '>', '|'), 171 | KeyCode::M => modifiers.handle_ascii_3('M', 'µ', handle_ctrl), 172 | KeyCode::OemComma => modifiers.handle_symbol2(',', ';'), 173 | KeyCode::OemPeriod => modifiers.handle_symbol2('.', ':'), 174 | KeyCode::Oem2 => modifiers.handle_symbol2('-', '_'), 175 | // ========= Row 6 (modifers and space bar) ========= 176 | KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), 177 | // ========= Fallback ========= 178 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 179 | } 180 | } 181 | 182 | fn get_physical(&self) -> PhysicalKeyboard { 183 | PhysicalKeyboard::Iso 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/layouts/dvorak104.rs: -------------------------------------------------------------------------------- 1 | //! Dvorak keyboard support 2 | 3 | use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO}; 4 | 5 | /// A Dvorak 101-key (or 104-key including Windows keys) keyboard. 6 | /// 7 | /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). 8 | /// 9 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 10 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 11 | /// printable character. Blank spaces are passed through as 12 | /// [`DecodedKey::RawKey`]. 13 | /// 14 | /// Run the `print_keyboard` example to re-generate these images. 15 | /// 16 | /// ## Unmodified 17 | /// 18 | /// ```text 19 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 20 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 21 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 22 | /// 23 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 24 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 25 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 26 | /// │0009 │ ' │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 27 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 28 | /// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ 29 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 30 | /// │ │ ; │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ 31 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 32 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 33 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 34 | /// ``` 35 | /// 36 | /// ## Caps Lock 37 | /// 38 | /// ```text 39 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 40 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 41 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 42 | /// 43 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 44 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 45 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 46 | /// │0009 │ ' │ , │ . │ P │ Y │ F │ G │ C │ R │ L │ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 47 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 48 | /// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ - │ 000a │ │ 4 │ 5 │ 6 │ │ 49 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 50 | /// │ │ ; │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ 51 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 52 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 53 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 54 | /// ``` 55 | /// 56 | /// ## Shifted 57 | /// 58 | /// ```text 59 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 60 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 61 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 62 | /// 63 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 64 | /// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ { │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 65 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 66 | /// │0009 │ " │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ + │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 67 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 68 | /// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ 69 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 70 | /// │ │ : │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ 71 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 72 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 73 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 74 | /// ``` 75 | /// 76 | /// ## Control 77 | /// 78 | /// ```text 79 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 80 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 81 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 82 | /// 83 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 84 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 85 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 86 | /// │0009 │ ' │ , │ . │0010│0019│0006│0007│0003│0012│000c│ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 87 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 88 | /// │ │0001│000f│0005│0015│0009│0004│0008│0014│000e│0013│ - │ 000a │ │ 4 │ 5 │ 6 │ │ 89 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 90 | /// │ │ ; │0011│000a│000b│0018│0002│000d│0017│0016│001a│ │ │ │ │ 1 │ 2 │ 3 │ │ 91 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 92 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 93 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 94 | /// ``` 95 | /// 96 | /// ## AltGr 97 | /// 98 | /// ```text 99 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 100 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 101 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 102 | /// 103 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 104 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 105 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 106 | /// │0009 │ ' │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 107 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 108 | /// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ 109 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 110 | /// │ │ ; │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ 111 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 112 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 113 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 114 | /// ``` 115 | /// 116 | /// ## Shift AltGr 117 | /// 118 | /// ```text 119 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 120 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 121 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 122 | /// 123 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 124 | /// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ { │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 125 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 126 | /// │0009 │ " │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ + │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 127 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 128 | /// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ 129 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 130 | /// │ │ : │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ 131 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 132 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 133 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 134 | /// ``` 135 | pub struct Dvorak104Key; 136 | 137 | impl KeyboardLayout for Dvorak104Key { 138 | #[rustfmt::skip] 139 | fn map_keycode( 140 | &self, 141 | keycode: KeyCode, 142 | modifiers: &Modifiers, 143 | handle_ctrl: HandleControl, 144 | ) -> DecodedKey { 145 | match keycode { 146 | // ========= Row 2 (the numbers) ========= 147 | KeyCode::OemMinus => modifiers.handle_symbol2('[', '{'), 148 | KeyCode::OemPlus => modifiers.handle_symbol2(']', '}'), 149 | // ========= Row 3 (QWERTY) ========= 150 | KeyCode::Q => modifiers.handle_symbol2(QUO, '"'), 151 | KeyCode::W => modifiers.handle_symbol2(',', '<'), 152 | KeyCode::E => modifiers.handle_symbol2('.', '>'), 153 | KeyCode::R => modifiers.handle_ascii_2('P', handle_ctrl), 154 | KeyCode::T => modifiers.handle_ascii_2('Y', handle_ctrl), 155 | KeyCode::Y => modifiers.handle_ascii_2('F', handle_ctrl), 156 | KeyCode::U => modifiers.handle_ascii_2('G', handle_ctrl), 157 | KeyCode::I => modifiers.handle_ascii_2('C', handle_ctrl), 158 | KeyCode::O => modifiers.handle_ascii_2('R', handle_ctrl), 159 | KeyCode::P => modifiers.handle_ascii_2('L', handle_ctrl), 160 | KeyCode::Oem4 => modifiers.handle_symbol2('/', '?'), 161 | KeyCode::Oem6 => modifiers.handle_symbol2('=', '+'), 162 | // ========= Row 4 (ASDFG) ========= 163 | KeyCode::S => modifiers.handle_ascii_2('O', handle_ctrl), 164 | KeyCode::D => modifiers.handle_ascii_2('E', handle_ctrl), 165 | KeyCode::F => modifiers.handle_ascii_2('U', handle_ctrl), 166 | KeyCode::G => modifiers.handle_ascii_2('I', handle_ctrl), 167 | KeyCode::H => modifiers.handle_ascii_2('D', handle_ctrl), 168 | KeyCode::J => modifiers.handle_ascii_2('H', handle_ctrl), 169 | KeyCode::K => modifiers.handle_ascii_2('T', handle_ctrl), 170 | KeyCode::L => modifiers.handle_ascii_2('N', handle_ctrl), 171 | KeyCode::Oem1 => modifiers.handle_ascii_2('S', handle_ctrl), 172 | KeyCode::Oem3 => modifiers.handle_symbol2('-', '_'), 173 | // ========= Row 5 (ZXCVB) ========= 174 | KeyCode::Z => modifiers.handle_symbol2(';', ':'), 175 | KeyCode::X => modifiers.handle_ascii_2('Q', handle_ctrl), 176 | KeyCode::C => modifiers.handle_ascii_2('J', handle_ctrl), 177 | KeyCode::V => modifiers.handle_ascii_2('K', handle_ctrl), 178 | KeyCode::B => modifiers.handle_ascii_2('X', handle_ctrl), 179 | KeyCode::N => modifiers.handle_ascii_2('B', handle_ctrl), 180 | KeyCode::OemComma => modifiers.handle_ascii_2('W', handle_ctrl), 181 | KeyCode::OemPeriod => modifiers.handle_ascii_2('V', handle_ctrl), 182 | KeyCode::Oem2 => modifiers.handle_ascii_2('Z', handle_ctrl), 183 | // ========= Fallback ========= 184 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 185 | } 186 | } 187 | 188 | fn get_physical(&self) -> PhysicalKeyboard { 189 | PhysicalKeyboard::Ansi 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/layouts/dvorak_programmer104.rs: -------------------------------------------------------------------------------- 1 | //! Dvorak Programmer keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard. 8 | /// 9 | /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). 10 | /// 11 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 12 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 13 | /// printable character. Blank spaces are passed through as 14 | /// [`DecodedKey::RawKey`]. 15 | /// 16 | /// Run the `print_keyboard` example to re-generate these images. 17 | /// 18 | /// ## Unmodified 19 | /// 20 | /// ```text 21 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 22 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 23 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 24 | /// 25 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 26 | /// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 27 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 28 | /// │0009 │ ; │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 29 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 30 | /// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ 31 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 32 | /// │ │ ' │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ 33 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 34 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 35 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 36 | /// ``` 37 | /// 38 | /// ## Caps Lock 39 | /// 40 | /// ```text 41 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 42 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 43 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 44 | /// 45 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 46 | /// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 47 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 48 | /// │0009 │ ; │ , │ . │ P │ Y │ F │ G │ C │ R │ L │ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 49 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 50 | /// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ - │ 000a │ │ 4 │ 5 │ 6 │ │ 51 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 52 | /// │ │ ' │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ 53 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 54 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 55 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 56 | /// ``` 57 | /// 58 | /// ## Shifted 59 | /// 60 | /// ```text 61 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 62 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 63 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 64 | /// 65 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 66 | /// │ ~ │ % │ 7 │ 5 │ 3 │ 1 │ 9 │ 0 │ 2 │ 4 │ 6 │ 8 │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 67 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 68 | /// │0009 │ : │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ ^ │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 69 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 70 | /// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ 71 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 72 | /// │ │ " │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ 73 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 74 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 75 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 76 | /// ``` 77 | /// 78 | /// ## Control 79 | /// 80 | /// ```text 81 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 82 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 83 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 84 | /// 85 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 86 | /// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 87 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 88 | /// │0009 │ ; │ , │ . │0010│0019│0006│0007│0003│0012│000c│ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 89 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 90 | /// │ │0001│000f│0005│0015│0009│0004│0008│0014│000e│0013│ - │ 000a │ │ 4 │ 5 │ 6 │ │ 91 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 92 | /// │ │ ' │0011│000a│000b│0018│0002│000d│0017│0016│001a│ │ │ │ │ 1 │ 2 │ 3 │ │ 93 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 94 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 95 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 96 | /// ``` 97 | /// 98 | /// ## AltGr 99 | /// 100 | /// ```text 101 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 102 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 103 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 104 | /// 105 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 106 | /// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 107 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 108 | /// │0009 │ ; │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 109 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 110 | /// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ 111 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 112 | /// │ │ ' │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ 113 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 114 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 115 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 116 | /// ``` 117 | /// 118 | /// ## Shift AltGr 119 | /// 120 | /// ```text 121 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 122 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 123 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 124 | /// 125 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 126 | /// │ ~ │ % │ 7 │ 5 │ 3 │ 1 │ 9 │ 0 │ 2 │ 4 │ 6 │ 8 │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 127 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 128 | /// │0009 │ : │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ ^ │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 129 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 130 | /// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ 131 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 132 | /// │ │ " │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ 133 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 134 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 135 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 136 | /// ``` 137 | pub struct DVP104Key; 138 | 139 | impl KeyboardLayout for DVP104Key { 140 | #[rustfmt::skip] 141 | fn map_keycode( 142 | &self, 143 | keycode: KeyCode, 144 | modifiers: &Modifiers, 145 | handle_ctrl: HandleControl, 146 | ) -> DecodedKey { 147 | match keycode { 148 | // ========= Row 2 (the numbers) ========= 149 | KeyCode::Oem8 => modifiers.handle_symbol2('$', '~'), 150 | KeyCode::Key1 => modifiers.handle_symbol2('&', '%'), 151 | KeyCode::Key2 => modifiers.handle_symbol2('[', '7'), 152 | KeyCode::Key3 => modifiers.handle_symbol2('{', '5'), 153 | KeyCode::Key4 => modifiers.handle_symbol2('}', '3'), 154 | KeyCode::Key5 => modifiers.handle_symbol2('(', '1'), 155 | KeyCode::Key6 => modifiers.handle_symbol2('=', '9'), 156 | KeyCode::Key7 => modifiers.handle_symbol2('*', '0'), 157 | KeyCode::Key8 => modifiers.handle_symbol2(')', '2'), 158 | KeyCode::Key9 => modifiers.handle_symbol2('+', '4'), 159 | KeyCode::Key0 => modifiers.handle_symbol2(']', '6'), 160 | KeyCode::OemMinus => modifiers.handle_symbol2('!', '8'), 161 | KeyCode::OemPlus => modifiers.handle_symbol2('=', '`'), 162 | // ========= Row 3 (QWERTY) ========= 163 | KeyCode::Q => modifiers.handle_symbol2(';', ':'), 164 | KeyCode::W => modifiers.handle_symbol2(',', '<'), 165 | KeyCode::E => modifiers.handle_symbol2('.', '>'), 166 | KeyCode::R => modifiers.handle_ascii_2('P', handle_ctrl), 167 | KeyCode::T => modifiers.handle_ascii_2('Y', handle_ctrl), 168 | KeyCode::Y => modifiers.handle_ascii_2('F', handle_ctrl), 169 | KeyCode::U => modifiers.handle_ascii_2('G', handle_ctrl), 170 | KeyCode::I => modifiers.handle_ascii_2('C', handle_ctrl), 171 | KeyCode::O => modifiers.handle_ascii_2('R', handle_ctrl), 172 | KeyCode::P => modifiers.handle_ascii_2('L', handle_ctrl), 173 | KeyCode::Oem4 => modifiers.handle_symbol2('/', '?'), 174 | KeyCode::Oem6 => modifiers.handle_symbol2('@', '^'), 175 | KeyCode::Oem7 => modifiers.handle_symbol2(SLS, '|'), 176 | // ========= Row 4 (ASDFG) ========= 177 | KeyCode::A => modifiers.handle_ascii_2('A', handle_ctrl), 178 | KeyCode::S => modifiers.handle_ascii_2('O', handle_ctrl), 179 | KeyCode::D => modifiers.handle_ascii_2('E', handle_ctrl), 180 | KeyCode::F => modifiers.handle_ascii_2('U', handle_ctrl), 181 | KeyCode::G => modifiers.handle_ascii_2('I', handle_ctrl), 182 | KeyCode::H => modifiers.handle_ascii_2('D', handle_ctrl), 183 | KeyCode::J => modifiers.handle_ascii_2('H', handle_ctrl), 184 | KeyCode::K => modifiers.handle_ascii_2('T', handle_ctrl), 185 | KeyCode::L => modifiers.handle_ascii_2('N', handle_ctrl), 186 | KeyCode::Oem1 => modifiers.handle_ascii_2('S', handle_ctrl), 187 | KeyCode::Oem3 => modifiers.handle_symbol2('-', '_'), 188 | // ========= Row 5 (ZXCVB) ========= 189 | KeyCode::Z => modifiers.handle_symbol2(QUO, '"'), 190 | KeyCode::X => modifiers.handle_ascii_2('Q', handle_ctrl), 191 | KeyCode::C => modifiers.handle_ascii_2('J', handle_ctrl), 192 | KeyCode::V => modifiers.handle_ascii_2('K', handle_ctrl), 193 | KeyCode::B => modifiers.handle_ascii_2('X', handle_ctrl), 194 | KeyCode::N => modifiers.handle_ascii_2('B', handle_ctrl), 195 | KeyCode::M => modifiers.handle_ascii_2('M', handle_ctrl), 196 | KeyCode::OemComma => modifiers.handle_ascii_2('W', handle_ctrl), 197 | KeyCode::OemPeriod => modifiers.handle_ascii_2('V', handle_ctrl), 198 | KeyCode::Oem2 => modifiers.handle_ascii_2('Z', handle_ctrl), 199 | // ========= Fallback ========= 200 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 201 | } 202 | } 203 | 204 | fn get_physical(&self) -> PhysicalKeyboard { 205 | PhysicalKeyboard::Ansi 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/layouts/azerty.rs: -------------------------------------------------------------------------------- 1 | //! French keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard French 102-key (or 105-key including Windows keys) keyboard. 8 | /// 9 | /// The top row spells `AZERTY`. Has a 2-row high Enter key, with Oem5 next to 10 | /// the left shift (ISO format). 11 | /// 12 | /// NB: no "dead key" support for now 13 | /// 14 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 15 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 16 | /// printable character. Blank spaces are passed through as 17 | /// [`DecodedKey::RawKey`]. 18 | /// 19 | /// Run the `print_keyboard` example to re-generate these images. 20 | /// 21 | /// ## Unmodified 22 | /// 23 | /// ```text 24 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 25 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 26 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 27 | /// 28 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 29 | /// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 30 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 31 | /// │0009 │ a │ z │ e │ r │ t │ y │ u │ i │ o │ p │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 32 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 33 | /// │ │ q │ s │ d │ f │ g │ h │ j │ k │ l │ m │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ 34 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 35 | /// │ │ < │ w │ x │ c │ v │ b │ n │ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ 36 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 37 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 38 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 39 | /// ``` 40 | /// 41 | /// ## Caps Lock 42 | /// 43 | /// ```text 44 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 45 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 46 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 47 | /// 48 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 49 | /// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 50 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 51 | /// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 52 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 53 | /// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ 54 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 55 | /// │ │ < │ W │ X │ C │ V │ B │ N │ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ 56 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 57 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 58 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 59 | /// ``` 60 | /// 61 | /// ## Shifted 62 | /// 63 | /// ```text 64 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 65 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 66 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 67 | /// 68 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 69 | /// │ ² │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 70 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 71 | /// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ £ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 72 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 73 | /// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ % │ µ │ │ │ 4 │ 5 │ 6 │ │ 74 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 75 | /// │ │ > │ W │ X │ C │ V │ B │ N │ ? │ . │ / │ § │ │ │ │ │ 1 │ 2 │ 3 │ │ 76 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 77 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 78 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 79 | /// ``` 80 | /// 81 | /// ## Control 82 | /// 83 | /// ```text 84 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 85 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 86 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 87 | /// 88 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 89 | /// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 90 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 91 | /// │0009 │0001│001a│0005│0012│0014│0019│0015│0009│000f│0010│ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 92 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 93 | /// │ │0011│0013│0004│0006│0007│0008│000a│000b│000c│000d│ ù │ * │ │ │ 4 │ 5 │ 6 │ │ 94 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 95 | /// │ │ < │0017│0018│0003│0016│0002│000e│ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ 96 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 97 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 98 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 99 | /// ``` 100 | /// 101 | /// ## AltGr 102 | /// 103 | /// ```text 104 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 105 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 106 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 107 | /// 108 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 109 | /// │ ² │ & │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 110 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 111 | /// │0009 │ a │ z │ € │ r │ t │ y │ u │ i │ o │ p │ ^ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 112 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 113 | /// │ │ q │ s │ d │ f │ g │ h │ j │ k │ l │ m │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ 114 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 115 | /// │ │ < │ w │ x │ c │ v │ b │ n │ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ 116 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 117 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 118 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 119 | /// ``` 120 | /// 121 | /// ## Shift AltGr 122 | /// 123 | /// ```text 124 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 125 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 126 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 127 | /// 128 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 129 | /// │ ² │ 1 │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 130 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 131 | /// │0009 │ A │ Z │ € │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 132 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 133 | /// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ % │ µ │ │ │ 4 │ 5 │ 6 │ │ 134 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 135 | /// │ │ > │ W │ X │ C │ V │ B │ N │ ? │ . │ / │ § │ │ │ │ │ 1 │ 2 │ 3 │ │ 136 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 137 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 138 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 139 | /// ``` 140 | pub struct Azerty; 141 | 142 | impl KeyboardLayout for Azerty { 143 | #[rustfmt::skip] 144 | fn map_keycode( 145 | &self, 146 | keycode: KeyCode, 147 | modifiers: &Modifiers, 148 | handle_ctrl: HandleControl, 149 | ) -> DecodedKey { 150 | match keycode { 151 | // ========= Row 2 (the numbers) ========= 152 | KeyCode::Oem8 => DecodedKey::Unicode('²'), 153 | KeyCode::Key1 => modifiers.handle_symbol2('&', '1'), 154 | KeyCode::Key2 => modifiers.handle_symbol3('é', '2', '~'), 155 | KeyCode::Key3 => modifiers.handle_symbol3('"', '3', '#'), 156 | KeyCode::Key4 => modifiers.handle_symbol3(QUO, '4', '{'), 157 | KeyCode::Key5 => modifiers.handle_symbol3('(', '5', '['), 158 | KeyCode::Key6 => modifiers.handle_symbol3('-', '6', '|'), 159 | KeyCode::Key7 => modifiers.handle_symbol3('è', '7', '`'), 160 | KeyCode::Key8 => modifiers.handle_symbol3('_', '8', SLS), 161 | KeyCode::Key9 => modifiers.handle_symbol3('ç', '9', '^'), 162 | KeyCode::Key0 => modifiers.handle_symbol3('à', '0', '@'), 163 | KeyCode::OemMinus => modifiers.handle_symbol3(')', '°', ']'), 164 | KeyCode::OemPlus => modifiers.handle_symbol3('=', '+', '}'), 165 | // ========= Row 3 (QWERTY) ========= 166 | KeyCode::Q => modifiers.handle_ascii_2('A', handle_ctrl), 167 | KeyCode::W => modifiers.handle_ascii_2('Z', handle_ctrl), 168 | KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), 169 | KeyCode::Oem4 => modifiers.handle_symbol2('^', '¨'), 170 | KeyCode::Oem6 => modifiers.handle_symbol3('$', '£', '¤'), 171 | // ========= Row 4 (ASDFG) ========= 172 | KeyCode::A => modifiers.handle_ascii_2('Q', handle_ctrl), 173 | KeyCode::Oem1 => modifiers.handle_ascii_2('M', handle_ctrl), 174 | KeyCode::Oem3 => modifiers.handle_symbol2('ù', '%'), 175 | KeyCode::Oem7 => modifiers.handle_symbol2('*', 'µ'), 176 | // ========= Row 5 (ZXCVB) ========= 177 | KeyCode::Oem5 => modifiers.handle_symbol2('<', '>'), 178 | KeyCode::Z => modifiers.handle_ascii_2('W', handle_ctrl), 179 | KeyCode::M => modifiers.handle_symbol2(',', '?'), 180 | KeyCode::OemComma => modifiers.handle_symbol2(';', '.'), 181 | KeyCode::OemPeriod => modifiers.handle_symbol2(':', '/'), 182 | KeyCode::Oem2 => modifiers.handle_symbol2('!', '§'), 183 | // ========= Fallback ========= 184 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 185 | } 186 | } 187 | 188 | fn get_physical(&self) -> PhysicalKeyboard { 189 | PhysicalKeyboard::Iso 190 | } 191 | } 192 | 193 | #[cfg(test)] 194 | mod test { 195 | use super::*; 196 | use crate::{KeyCode, KeyEvent, KeyState, PS2Keyboard, ScancodeSet2}; 197 | 198 | #[test] 199 | fn test_frazert() { 200 | let mut k = PS2Keyboard::new( 201 | ScancodeSet2::new(), 202 | Azerty, 203 | HandleControl::MapLettersToUnicode, 204 | ); 205 | assert_eq!( 206 | k.process_keyevent(KeyEvent::new(KeyCode::NumpadDivide, KeyState::Down)), 207 | Some(DecodedKey::Unicode('/')) 208 | ); 209 | assert_eq!( 210 | k.process_keyevent(KeyEvent::new(KeyCode::NumpadMultiply, KeyState::Down)), 211 | Some(DecodedKey::Unicode('*')) 212 | ); 213 | assert_eq!( 214 | k.process_keyevent(KeyEvent::new(KeyCode::A, KeyState::Down)), 215 | Some(DecodedKey::Unicode('q')) 216 | ); 217 | assert_eq!( 218 | k.process_keyevent(KeyEvent::new(KeyCode::Key4, KeyState::Down)), 219 | Some(DecodedKey::Unicode('\'')) 220 | ); 221 | assert_eq!( 222 | k.process_keyevent(KeyEvent::new(KeyCode::Oem5, KeyState::Down)), 223 | Some(DecodedKey::Unicode('<')) 224 | ); 225 | assert_eq!( 226 | k.process_keyevent(KeyEvent::new(KeyCode::Oem7, KeyState::Down)), 227 | Some(DecodedKey::Unicode('*')) 228 | ); 229 | assert_eq!( 230 | k.process_keyevent(KeyEvent::new(KeyCode::Numpad0, KeyState::Up)), 231 | None 232 | ); 233 | assert_eq!( 234 | k.process_keyevent(KeyEvent::new(KeyCode::NumpadLock, KeyState::Down)), 235 | Some(DecodedKey::RawKey(KeyCode::NumpadLock)) 236 | ); 237 | assert_eq!( 238 | k.process_keyevent(KeyEvent::new(KeyCode::NumpadLock, KeyState::Up)), 239 | None 240 | ); 241 | assert_eq!( 242 | k.process_keyevent(KeyEvent::new(KeyCode::Numpad0, KeyState::Down)), 243 | Some(DecodedKey::RawKey(KeyCode::Insert)) 244 | ); 245 | assert_eq!( 246 | k.process_keyevent(KeyEvent::new(KeyCode::Numpad0, KeyState::Up)), 247 | None 248 | ); 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /src/layouts/uk105.rs: -------------------------------------------------------------------------------- 1 | //! United Kingdom keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard United Kingdom 102-key (or 105-key including Windows keys) keyboard. 8 | /// 9 | /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). 10 | /// 11 | /// Based on US 101/104 key, with minor changes. 12 | /// 13 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 14 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 15 | /// printable character. Blank spaces are passed through as 16 | /// [`DecodedKey::RawKey`]. 17 | /// 18 | /// Run the `print_keyboard` example to re-generate these images. 19 | /// 20 | /// ## Unmodified 21 | /// 22 | /// ```text 23 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 24 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 25 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 26 | /// 27 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 28 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 29 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 30 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 31 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 32 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ 33 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 34 | /// │ │ \ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 35 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 36 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 37 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 38 | /// ``` 39 | /// 40 | /// ## Caps Lock 41 | /// 42 | /// ```text 43 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 44 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 45 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 46 | /// 47 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 48 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 49 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 50 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 51 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 52 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ 53 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 54 | /// │ │ \ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 55 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 56 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 57 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 58 | /// ``` 59 | /// 60 | /// ## Shifted 61 | /// 62 | /// ```text 63 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 64 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 65 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 66 | /// 67 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 68 | /// │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 69 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 70 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 71 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 72 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │ 73 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 74 | /// │ │ | │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ 75 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 76 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 77 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 78 | /// ``` 79 | /// 80 | /// ## Control 81 | /// 82 | /// ```text 83 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 84 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 85 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 86 | /// 87 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 88 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 89 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 90 | /// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 91 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 92 | /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ 93 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 94 | /// │ │ \ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 95 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 96 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 97 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 98 | /// ``` 99 | /// 100 | /// ## AltGr 101 | /// 102 | /// ```text 103 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 104 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 105 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 106 | /// 107 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 108 | /// │ ¦ │ 1 │ 2 │ 3 │ € │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 109 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 110 | /// │0009 │ q │ w │ é │ r │ t │ y │ ú │ í │ ó │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 111 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 112 | /// │ │ á │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ 113 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 114 | /// │ │ \ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 115 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 116 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 117 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 118 | /// ``` 119 | /// 120 | /// ## Shift AltGr 121 | /// 122 | /// ```text 123 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 124 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 125 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 126 | /// 127 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 128 | /// │ ¦ │ ! │ " │ £ │ € │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 129 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 130 | /// │0009 │ Q │ W │ É │ R │ T │ Y │ Ú │ Í │ Ó │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 131 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ 132 | /// │ │ Á │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │ 133 | /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ 134 | /// │ │ | │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ 135 | /// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 136 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 137 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 138 | /// ``` 139 | pub struct Uk105Key; 140 | 141 | impl KeyboardLayout for Uk105Key { 142 | #[rustfmt::skip] 143 | fn map_keycode( 144 | &self, 145 | keycode: KeyCode, 146 | modifiers: &Modifiers, 147 | handle_ctrl: HandleControl, 148 | ) -> DecodedKey { 149 | match keycode { 150 | KeyCode::Key2 => modifiers.handle_symbol2('2', '"'), 151 | KeyCode::Key3 => modifiers.handle_symbol2('3', '£'), 152 | KeyCode::Key4 => modifiers.handle_symbol3('4', '$', '€'), 153 | KeyCode::Oem3 => modifiers.handle_symbol2(QUO, '@'), 154 | KeyCode::Oem5 => modifiers.handle_symbol2(SLS, '|'), 155 | KeyCode::Oem7 => modifiers.handle_symbol2('#', '~'), 156 | KeyCode::Oem8 => modifiers.handle_symbol3('`', '¬', '¦'), 157 | KeyCode::E => modifiers.handle_ascii_4('E', 'é', 'É', handle_ctrl), 158 | KeyCode::U => modifiers.handle_ascii_4('U', 'ú', 'Ú', handle_ctrl), 159 | KeyCode::I => modifiers.handle_ascii_4('I', 'í', 'Í', handle_ctrl), 160 | KeyCode::O => modifiers.handle_ascii_4('O', 'ó', 'Ó', handle_ctrl), 161 | KeyCode::A => modifiers.handle_ascii_4('A', 'á', 'Á', handle_ctrl), 162 | e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), 163 | } 164 | } 165 | 166 | fn get_physical(&self) -> PhysicalKeyboard { 167 | PhysicalKeyboard::Iso 168 | } 169 | } 170 | 171 | #[cfg(test)] 172 | mod test { 173 | use super::*; 174 | use crate::{ 175 | EventDecoder, HandleControl, PS2Keyboard, ScancodeSet, ScancodeSet1, ScancodeSet2, 176 | }; 177 | 178 | #[test] 179 | fn layout() { 180 | // Codes taken from https://kbdlayout.info/kbduk/overview+scancodes?arrangement=ISO105 181 | let mut s = ScancodeSet1::new(); 182 | let mut dec = EventDecoder::new(Uk105Key, HandleControl::Ignore); 183 | let data = [ 184 | (0x29, '`'), 185 | (0x02, '1'), 186 | (0x03, '2'), 187 | (0x04, '3'), 188 | (0x05, '4'), 189 | (0x06, '5'), 190 | (0x07, '6'), 191 | (0x08, '7'), 192 | (0x09, '8'), 193 | (0x0a, '9'), 194 | (0x0b, '0'), 195 | (0x0c, '-'), 196 | (0x0d, '='), 197 | (0x0f, '\t'), 198 | (0x10, 'q'), 199 | (0x11, 'w'), 200 | (0x12, 'e'), 201 | (0x13, 'r'), 202 | (0x14, 't'), 203 | (0x15, 'y'), 204 | (0x16, 'u'), 205 | (0x17, 'i'), 206 | (0x18, 'o'), 207 | (0x19, 'p'), 208 | (0x1a, '['), 209 | (0x1b, ']'), 210 | (0x1e, 'a'), 211 | (0x1f, 's'), 212 | (0x20, 'd'), 213 | (0x21, 'f'), 214 | (0x22, 'g'), 215 | (0x23, 'h'), 216 | (0x24, 'j'), 217 | (0x25, 'k'), 218 | (0x26, 'l'), 219 | (0x27, ';'), 220 | (0x28, '\''), 221 | (0x2B, '#'), 222 | (0x1c, '\n'), 223 | (0x56, '\\'), 224 | (0x2c, 'z'), 225 | (0x2d, 'x'), 226 | (0x2e, 'c'), 227 | (0x2f, 'v'), 228 | (0x30, 'b'), 229 | (0x31, 'n'), 230 | (0x32, 'm'), 231 | (0x33, ','), 232 | (0x34, '.'), 233 | (0x35, '/'), 234 | ]; 235 | for (code, unicode) in data { 236 | let ev = s.advance_state(code).unwrap().unwrap(); 237 | assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev)); 238 | } 239 | } 240 | 241 | #[test] 242 | fn test_hash() { 243 | let mut k = PS2Keyboard::new( 244 | ScancodeSet2::new(), 245 | Uk105Key, 246 | HandleControl::MapLettersToUnicode, 247 | ); 248 | // As seen on a UK 105 key Dell PS/2 keyboard when pressing `~#` 249 | let ev = k.add_byte(0x5D).unwrap().unwrap(); 250 | let decoded_key = k.process_keyevent(ev); 251 | assert_eq!(decoded_key, Some(DecodedKey::Unicode('#'))); 252 | } 253 | 254 | #[test] 255 | fn test_backslash() { 256 | let mut k = PS2Keyboard::new( 257 | ScancodeSet2::new(), 258 | Uk105Key, 259 | HandleControl::MapLettersToUnicode, 260 | ); 261 | // As seen on a UK 105 key Dell PS/2 keyboard when pressing `|\` 262 | let ev = k.add_byte(0x61).unwrap().unwrap(); 263 | let decoded_key = k.process_keyevent(ev); 264 | assert_eq!(decoded_key, Some(DecodedKey::Unicode('\\'))); 265 | } 266 | 267 | #[test] 268 | fn test_tilde() { 269 | let mut k = PS2Keyboard::new( 270 | ScancodeSet2::new(), 271 | Uk105Key, 272 | HandleControl::MapLettersToUnicode, 273 | ); 274 | // As seen on a UK 105 key Dell PS/2 keyboard when pressing Shift and `~#` 275 | let ev = k.add_byte(0x12).unwrap().unwrap(); 276 | let _ = k.process_keyevent(ev); 277 | let ev = k.add_byte(0x5D).unwrap().unwrap(); 278 | let decoded_key = k.process_keyevent(ev); 279 | assert_eq!(decoded_key, Some(DecodedKey::Unicode('~'))); 280 | } 281 | 282 | #[test] 283 | fn test_pipe() { 284 | let mut k = PS2Keyboard::new( 285 | ScancodeSet2::new(), 286 | Uk105Key, 287 | HandleControl::MapLettersToUnicode, 288 | ); 289 | // As seen on a UK 105 key Dell PS/2 keyboard when pressing Shift and `|\` 290 | let ev = k.add_byte(0x12).unwrap().unwrap(); 291 | let _ = k.process_keyevent(ev); 292 | let ev = k.add_byte(0x61).unwrap().unwrap(); 293 | let decoded_key = k.process_keyevent(ev); 294 | assert_eq!(decoded_key, Some(DecodedKey::Unicode('|'))); 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/layouts/us104.rs: -------------------------------------------------------------------------------- 1 | //! # United States keyboard support 2 | 3 | use crate::{ 4 | DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, 5 | }; 6 | 7 | /// A standard United States 101-key (or 104-key including Windows keys) keyboard. 8 | /// 9 | /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). 10 | /// 11 | /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We 12 | /// show either a Unicode glyph, or a hex number if the glyph isn't a 13 | /// printable character. Blank spaces are passed through as 14 | /// [`DecodedKey::RawKey`]. 15 | /// 16 | /// Run the `print_keyboard` example to re-generate these images. 17 | /// 18 | /// ## Unmodified 19 | /// 20 | /// ```text 21 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 22 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 23 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 24 | /// 25 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 26 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 27 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 28 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 29 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 30 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 31 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 32 | /// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 33 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 34 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 35 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 36 | /// ``` 37 | /// 38 | /// ## Caps Lock 39 | /// 40 | /// ```text 41 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 42 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 43 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 44 | /// 45 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 46 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 47 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 48 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 49 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 50 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 51 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 52 | /// │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 53 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 54 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 55 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 56 | /// ``` 57 | /// 58 | /// ## Shifted 59 | /// 60 | /// ```text 61 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 62 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 63 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 64 | /// 65 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 66 | /// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 67 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 68 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 69 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 70 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " │ 000a │ │ 4 │ 5 │ 6 │ │ 71 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 72 | /// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ 73 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 74 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 75 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 76 | /// ``` 77 | /// 78 | /// ## Control 79 | /// 80 | /// ```text 81 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 82 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 83 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 84 | /// 85 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 86 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 87 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 88 | /// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 89 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 90 | /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 91 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 92 | /// │ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 93 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 94 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 95 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 96 | /// ``` 97 | /// 98 | /// ## AltGr 99 | /// 100 | /// ```text 101 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 102 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 103 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 104 | /// 105 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 106 | /// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 107 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 108 | /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 109 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 110 | /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ 111 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 112 | /// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ 113 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 114 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 115 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 116 | /// ``` 117 | /// 118 | /// ## Shift AltGr 119 | /// 120 | /// ```text 121 | /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ 122 | /// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 123 | /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ 124 | /// 125 | /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ 126 | /// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ 127 | /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ 128 | /// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ 129 | /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ 130 | /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " │ 000a │ │ 4 │ 5 │ 6 │ │ 131 | /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ 132 | /// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ 133 | /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ 134 | /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ 135 | /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ 136 | /// ``` 137 | pub struct Us104Key; 138 | 139 | impl KeyboardLayout for Us104Key { 140 | #[rustfmt::skip] 141 | fn map_keycode( 142 | &self, 143 | keycode: KeyCode, 144 | modifiers: &Modifiers, 145 | handle_ctrl: HandleControl, 146 | ) -> DecodedKey { 147 | match keycode { 148 | // ========= Row 2 (the numbers) ========= 149 | KeyCode::Oem8 => modifiers.handle_symbol2('`', '~'), 150 | KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), 151 | KeyCode::Key1 => modifiers.handle_symbol2('1', '!'), 152 | KeyCode::Key2 => modifiers.handle_symbol2('2', '@'), 153 | KeyCode::Key3 => modifiers.handle_symbol2('3', '#'), 154 | KeyCode::Key4 => modifiers.handle_symbol2('4', '$'), 155 | KeyCode::Key5 => modifiers.handle_symbol2('5', '%'), 156 | KeyCode::Key6 => modifiers.handle_symbol2('6', '^'), 157 | KeyCode::Key7 => modifiers.handle_symbol2('7', '&'), 158 | KeyCode::Key8 => modifiers.handle_symbol2('8', '*'), 159 | KeyCode::Key9 => modifiers.handle_symbol2('9', '('), 160 | KeyCode::Key0 => modifiers.handle_symbol2('0', ')'), 161 | KeyCode::OemMinus => modifiers.handle_symbol2('-', '_'), 162 | KeyCode::OemPlus => modifiers.handle_symbol2('=', '+'), 163 | KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), 164 | // ========= Row 3 (QWERTY) ========= 165 | KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), 166 | KeyCode::Q => modifiers.handle_ascii_2('Q', handle_ctrl), 167 | KeyCode::W => modifiers.handle_ascii_2('W', handle_ctrl), 168 | KeyCode::E => modifiers.handle_ascii_2('E', handle_ctrl), 169 | KeyCode::R => modifiers.handle_ascii_2('R', handle_ctrl), 170 | KeyCode::T => modifiers.handle_ascii_2('T', handle_ctrl), 171 | KeyCode::Y => modifiers.handle_ascii_2('Y', handle_ctrl), 172 | KeyCode::U => modifiers.handle_ascii_2('U', handle_ctrl), 173 | KeyCode::I => modifiers.handle_ascii_2('I', handle_ctrl), 174 | KeyCode::O => modifiers.handle_ascii_2('O', handle_ctrl), 175 | KeyCode::P => modifiers.handle_ascii_2('P', handle_ctrl), 176 | KeyCode::Oem4 => modifiers.handle_symbol2('[', '{'), 177 | KeyCode::Oem6 => modifiers.handle_symbol2(']', '}'), 178 | KeyCode::Oem7 => modifiers.handle_symbol2(SLS, '|'), 179 | // ========= Row 4 (ASDFG) ========= 180 | KeyCode::A => modifiers.handle_ascii_2('A', handle_ctrl), 181 | KeyCode::S => modifiers.handle_ascii_2('S', handle_ctrl), 182 | KeyCode::D => modifiers.handle_ascii_2('D', handle_ctrl), 183 | KeyCode::F => modifiers.handle_ascii_2('F', handle_ctrl), 184 | KeyCode::G => modifiers.handle_ascii_2('G', handle_ctrl), 185 | KeyCode::H => modifiers.handle_ascii_2('H', handle_ctrl), 186 | KeyCode::J => modifiers.handle_ascii_2('J', handle_ctrl), 187 | KeyCode::K => modifiers.handle_ascii_2('K', handle_ctrl), 188 | KeyCode::L => modifiers.handle_ascii_2('L', handle_ctrl), 189 | KeyCode::Oem1 => modifiers.handle_symbol2(';', ':'), 190 | KeyCode::Oem3 => modifiers.handle_symbol2(QUO, '"'), 191 | KeyCode::Return => DecodedKey::Unicode('\u{000A}'), 192 | // ========= Row 5 (ZXCVB) ========= 193 | KeyCode::Z => modifiers.handle_ascii_2('Z', handle_ctrl), 194 | KeyCode::X => modifiers.handle_ascii_2('X', handle_ctrl), 195 | KeyCode::C => modifiers.handle_ascii_2('C', handle_ctrl), 196 | KeyCode::V => modifiers.handle_ascii_2('V', handle_ctrl), 197 | KeyCode::B => modifiers.handle_ascii_2('B', handle_ctrl), 198 | KeyCode::N => modifiers.handle_ascii_2('N', handle_ctrl), 199 | KeyCode::M => modifiers.handle_ascii_2('M', handle_ctrl), 200 | KeyCode::OemComma => modifiers.handle_symbol2(',', '<'), 201 | KeyCode::OemPeriod => modifiers.handle_symbol2('.', '>'), 202 | KeyCode::Oem2 => modifiers.handle_symbol2('/', '?'), 203 | // ========= Unicode Specials ========= 204 | KeyCode::Spacebar => DecodedKey::Unicode(' '), 205 | KeyCode::Delete => DecodedKey::Unicode('\u{007f}'), 206 | // ========= Numpad ========= 207 | KeyCode::NumpadDivide => DecodedKey::Unicode('/'), 208 | KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), 209 | KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), 210 | KeyCode::Numpad7 => modifiers.handle_num_pad('7', KeyCode::Home), 211 | KeyCode::Numpad8 => modifiers.handle_num_pad('8', KeyCode::ArrowUp), 212 | KeyCode::Numpad9 => modifiers.handle_num_pad('9', KeyCode::PageUp), 213 | KeyCode::NumpadAdd => DecodedKey::Unicode('+'), 214 | KeyCode::Numpad4 => modifiers.handle_num_pad('4', KeyCode::ArrowLeft), 215 | KeyCode::Numpad5 => DecodedKey::Unicode('5'), 216 | KeyCode::Numpad6 => modifiers.handle_num_pad('6', KeyCode::ArrowRight), 217 | KeyCode::Numpad1 => modifiers.handle_num_pad('1', KeyCode::End), 218 | KeyCode::Numpad2 => modifiers.handle_num_pad('2', KeyCode::ArrowDown), 219 | KeyCode::Numpad3 => modifiers.handle_num_pad('3', KeyCode::PageDown), 220 | KeyCode::Numpad0 => modifiers.handle_num_pad('0', KeyCode::Insert), 221 | KeyCode::NumpadPeriod => modifiers.handle_num_del('.', '\u{007f}'), 222 | KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), 223 | // ========= Fallback ========= 224 | k => DecodedKey::RawKey(k), 225 | } 226 | } 227 | 228 | fn get_physical(&self) -> PhysicalKeyboard { 229 | PhysicalKeyboard::Ansi 230 | } 231 | } 232 | 233 | #[cfg(test)] 234 | mod test { 235 | use super::*; 236 | use crate::{EventDecoder, ScancodeSet, ScancodeSet1}; 237 | 238 | #[test] 239 | fn layout() { 240 | // Codes taken from https://kbdlayout.info/kbdus/overview+scancodes?arrangement=ANSI104 241 | let mut s = ScancodeSet1::new(); 242 | let mut dec = EventDecoder::new(Us104Key, HandleControl::Ignore); 243 | let data = [ 244 | (0x29, '`'), 245 | (0x02, '1'), 246 | (0x03, '2'), 247 | (0x04, '3'), 248 | (0x05, '4'), 249 | (0x06, '5'), 250 | (0x07, '6'), 251 | (0x08, '7'), 252 | (0x09, '8'), 253 | (0x0a, '9'), 254 | (0x0b, '0'), 255 | (0x0c, '-'), 256 | (0x0d, '='), 257 | (0x0f, '\t'), 258 | (0x10, 'q'), 259 | (0x11, 'w'), 260 | (0x12, 'e'), 261 | (0x13, 'r'), 262 | (0x14, 't'), 263 | (0x15, 'y'), 264 | (0x16, 'u'), 265 | (0x17, 'i'), 266 | (0x18, 'o'), 267 | (0x19, 'p'), 268 | (0x1a, '['), 269 | (0x1b, ']'), 270 | (0x2b, '\\'), 271 | (0x1e, 'a'), 272 | (0x1f, 's'), 273 | (0x20, 'd'), 274 | (0x21, 'f'), 275 | (0x22, 'g'), 276 | (0x23, 'h'), 277 | (0x24, 'j'), 278 | (0x25, 'k'), 279 | (0x26, 'l'), 280 | (0x27, ';'), 281 | (0x28, '\''), 282 | (0x1c, '\n'), 283 | (0x2c, 'z'), 284 | (0x2d, 'x'), 285 | (0x2e, 'c'), 286 | (0x2f, 'v'), 287 | (0x30, 'b'), 288 | (0x31, 'n'), 289 | (0x32, 'm'), 290 | (0x33, ','), 291 | (0x34, '.'), 292 | (0x35, '/'), 293 | ]; 294 | for (code, unicode) in data { 295 | let ev = s.advance_state(code).unwrap().unwrap(); 296 | assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev)); 297 | } 298 | } 299 | 300 | #[test] 301 | fn lowercase() { 302 | let modifiers = Modifiers { 303 | capslock: false, 304 | lalt: false, 305 | lctrl: false, 306 | lshift: false, 307 | numlock: false, 308 | ralt: false, 309 | rctrl: false, 310 | rctrl2: false, 311 | rshift: false, 312 | }; 313 | assert_eq!( 314 | modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), 315 | DecodedKey::Unicode('a') 316 | ); 317 | } 318 | 319 | #[test] 320 | fn uppercase() { 321 | let modifiers = Modifiers { 322 | capslock: true, 323 | lalt: false, 324 | lctrl: false, 325 | lshift: false, 326 | numlock: false, 327 | ralt: false, 328 | rctrl: false, 329 | rctrl2: false, 330 | rshift: false, 331 | }; 332 | assert_eq!( 333 | modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), 334 | DecodedKey::Unicode('A') 335 | ); 336 | } 337 | 338 | #[test] 339 | fn shifted() { 340 | let modifiers = Modifiers { 341 | capslock: false, 342 | lalt: false, 343 | lctrl: false, 344 | lshift: true, 345 | numlock: false, 346 | ralt: false, 347 | rctrl: false, 348 | rctrl2: false, 349 | rshift: false, 350 | }; 351 | assert_eq!( 352 | modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), 353 | DecodedKey::Unicode('A') 354 | ); 355 | } 356 | 357 | #[test] 358 | fn shift_caps() { 359 | let modifiers = Modifiers { 360 | capslock: true, 361 | lalt: false, 362 | lctrl: false, 363 | lshift: true, 364 | numlock: false, 365 | ralt: false, 366 | rctrl: false, 367 | rctrl2: false, 368 | rshift: false, 369 | }; 370 | assert_eq!( 371 | modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), 372 | DecodedKey::Unicode('a') 373 | ); 374 | } 375 | 376 | #[test] 377 | fn ctrl() { 378 | let modifiers = Modifiers { 379 | capslock: true, 380 | lalt: false, 381 | lctrl: true, 382 | lshift: true, 383 | numlock: false, 384 | ralt: false, 385 | rctrl: false, 386 | rctrl2: false, 387 | rshift: false, 388 | }; 389 | assert_eq!( 390 | modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), 391 | DecodedKey::Unicode('\u{0001}') 392 | ); 393 | } 394 | } 395 | --------------------------------------------------------------------------------