From 0b6c451524ec833d521fe5b153905c6e8e7edb90 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 1 Jun 2025 09:14:59 +0100 Subject: [PATCH 01/18] Move docs into lib.rs So it appears on docs.rs. Leave README for repo-level data. --- README.md | 290 +-------------------------------------------------- src/lib.rs | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 291 insertions(+), 297 deletions(-) diff --git a/README.md b/README.md index 86fec61..e79a55e 100644 --- a/README.md +++ b/README.md @@ -4,295 +4,7 @@ A simple driver for handling PC keyboards, with both Scancode Set 1 (when running on a PC) and Scancode Set 2 support (when reading a PS/2 keyboard output directly). -## Supports: - -- Scancode Set 1 (from the i8042 PC keyboard controller) -- Scancode Set 2 (direct from the AT or PS/2 interface keyboard) -- Several keyboard layouts: - -| Name | No. Keys | Description | Link | -| ---------------------------------------------------- | -------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | -| [`Us104Key`](./src/layouts/us104.rs) | 101/104 | North American standard English | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#United_States) | -| [`Uk105Key`](./src/layouts/uk105.rs) | 102/105 | United Kingdom standard English | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#United_Kingdom) | -| [`Azerty`](./src/layouts/azerty.rs) | 102/105 | Typically used in French locales | [Wikipedia](https://en.wikipedia.org/wiki/AZERTY) | -| [`De105Key`](./src/layouts/de105.rs) | 102/105 | German layout | [Wikipedia](https://en.wikipedia.org/wiki/QWERTZ) | -| [`FiSe105Key`](./src/layouts/fi_se105.rs) | 102/105 | Finnish/Swedish layout | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#Finnish%E2%80%93Swedish) | -| [`No105Key`](./src/layouts/no105.rs) | 102/105 | Norwegian layout | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#Norwegian) | -| [`Jis109Key`](./src/layouts/jis109.rs) | 106/109 | JIS 109-key layout (Latin chars only) | [Wikipedia](https://en.wikipedia.org/wiki/Japanese_input_method#Japanese_keyboards) | -| [`Colemak`](./src/layouts/colemak.rs) | 101/104 | A keyboard layout designed to make typing more efficient and comfortable | [Wikipedia](https://en.wikipedia.org/wiki/Colemak) | -| [`Dvorak104Key`](./src/layouts/dvorak104.rs) | 101/104 | The more 'ergonomic' alternative to QWERTY | [Wikipedia](https://en.wikipedia.org/wiki/Dvorak_keyboard_layout) | -| [`DVP104Key`](./src/layouts/dvorak_programmer104.rs) | 101/104 | Dvorak for Programmers | [Wikipedia](https://en.wikipedia.org/wiki/Dvorak_keyboard_layout#Programmer_Dvorak) | - -101/104 keys is ANSI layout (wide Enter key) and 102/105 keys is ISO layout -(tall Enter key). The difference between 101 and 104 (and between 102 and -105) comes from the two Windows keys and the Menu key that were added when -Windows 95 came out. JIS keyboards have extra keys, added by making the -space-bar and backspace keys shorter. - - -## Usage - -There are three basic steps to handling keyboard input. Your application may bypass some of these. - -* `Ps2Decoder` - converts 11-bit PS/2 words into bytes, removing the start/stop - bits and checking the parity bits. Only needed if you talk to the PS/2 - keyboard over GPIO pins and not required if you talk to the i8042 PC keyboard - controller. -* `ScancodeSet` - converts from Scancode Set 1 (i8042 PC keyboard controller) or - Scancode Set 2 (raw PS/2 keyboard output) into a symbolic `KeyCode` and an - up/down `KeyState`. -* `EventDecoder` - converts symbolic `KeyCode` and `KeyState` into a Unicode - characters (where possible) according to the currently selected `KeyboardLayout`. - -There is also `Keyboard` which combines the above three functions into a single object. - -See the [`examples`](./examples) folder for more details. - -## [Documentation](https://docs.rs/crate/pc-keyboard) - -## Keycodes - -This crate uses symbolic keycodes to abstract over Scancode Set 1 and Scancode -Set 2. They represented by the `KeyCode` enum. The scancodes can come from one of three supported keyboards: 102/105 key ISO, 101/104 key ANSI and 106/109-key JIS. - -### 102/105 key ISO - -This is the mapping of `KeyCode` to a 102/105-key ISO keyboard: - -```text -┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ -│Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│ -└────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ - -┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -│Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│ -├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Enter │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │ -├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤Num+│ -│CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│Oem7│ │ │Num4│Num5│Num6│ │ -├────┬─┴───┬┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ -│LShf│Oem5 │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│ RShift │ │ Up │ │Num1│Num2│Num3│ │ -├────┴┬────┴┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┴────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │ -│LCtrl│LWin │ Alt │ Space │AltGr│RWin │ Menu │RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│ -└─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ -``` - -The 102-key is missing `LWin`, `RWin`, and `Menu`. - -(Reference: ) - -### 101/104 key ANSI - -This is the mapping of `KeyCode` to a 101/104-key ANSI keyboard: - -```text -┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ -│Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│ -└────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ - -┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -│Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│ -├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────+────+────┤ ├────┼────┼────┼────┤ -│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Oem7 │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │ -├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤Num+│ -│CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│ Enter │ │Num4│Num5│Num6│ │ -├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ -│ LShift │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│ RShift │ │ Up │ │Num1│Num2│Num3│ │ -├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┴────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │ -│LCtrl│LWin │ Alt │ Space │AltGr│RWin │ Menu │RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│ -└─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ -``` - -Note that the `Oem5` key is missing on the 104-key ANSI keyboard. - -The 101-key is also missing `LWin`, `RWin`, and `Menu`. - -(Reference: ) - -### 106/109 key JIS - -This is the mapping of `KeyCode` to a 106/109-key JIS keyboard: - -```text -┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ -│Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│ -└────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ - -┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -│Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Om13│BkSp│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│ -├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Enter │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │ -├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤Num+│ -│CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│Oem7│ │ │Num4│Num5│Num6│ │ -├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ -│LShift │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│Oem12 │RShift │ │ Up │ │Num1│Num2│Num3│ │ -├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │ -│LCtrl│LWin │LAlt │Oem9 │ Space Bar │Oem10│Oem11│RWin│Menu│RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│ -└─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ -``` - -Note that the `Oem5` is missing on the 109-key JIS layout, but `Oem9` (Muhenkan), `Oem10` (Henkan/Zenkouho), `Oem11` (Hiragana/Katakana), `Oem12` (Backslash) and `Oem13` (¥) are added. - -The 106-key is missing `LWin`, `RWin`, and `Menu`. - -(Reference: ) - -### Conversion Table - -Scancode Set 1 and Scancode Set 2 can be losslessly converted. Indeed, this is -what the i8042 keyboard controller in your PC does - it takes Scancode Set 2 -from the keyboard and provides Scancode Set 1 to the Operating System. This -allowed them to change the keyboard design without breaking compatibility with -any MS-DOS applications that read raw scancodes from the keyboard. - -This table shows the correspondence between our symbolic KeyCode, Scancode Set 1 -and Scancode Set 2. We may extend this in the future to also handle USB HID -Scancodes. Any codes prefixed `0xE0` or `0xE1` are *extended* multi-byte -scancodes. Typically these are keys that were not on the IBM PC and PC/XT -keyboards so they they were added in such a way that if you ignored the 0xE0, -you got a reasonable result anyway. For example `ArrowLeft` is `0xE04B` in -Scancode Set 1 because `Numpad4` is `0x4B` and that was the left-arrow key on an -IBM PC or PC/XT. - -| Symbolic Key | Scancode Set 1 | Scancode Set 2 | -| -------------- | -------------- | -------------- | -| Escape | 0x01 | 0x76 | -| F1 | 0x3B | 0x05 | -| F2 | 0x3C | 0x06 | -| F3 | 0x3D | 0x04 | -| F4 | 0x3E | 0x0C | -| F5 | 0x3F | 0x03 | -| F6 | 0x40 | 0x0B | -| F7 | 0x41 | 0x83 | -| F8 | 0x42 | 0x0A | -| F9 | 0x43 | 0x01 | -| F10 | 0x44 | 0x09 | -| F11 | 0x57 | 0x78 | -| F12 | 0x58 | 0x07 | -| PrintScreen | 0xE037 | 0xE07C | -| SysRq | 0x54 | 0x7F | -| ScrollLock | 0x46 | 0x7E | -| PauseBreak | -- | -- | -| - | -- | -- | -| Oem8 | 0x29 | 0x0E | -| Key1 | 0x02 | 0x16 | -| Key2 | 0x03 | 0x1E | -| Key3 | 0x04 | 0x26 | -| Key4 | 0x05 | 0x25 | -| Key5 | 0x06 | 0x2E | -| Key6 | 0x07 | 0x36 | -| Key7 | 0x08 | 0x3D | -| Key8 | 0x09 | 0x3E | -| Key9 | 0x0A | 0x46 | -| Key0 | 0x0B | 0x45 | -| OemMinus | 0x0C | 0x4E | -| OemPlus | 0x0D | 0x55 | -| Backspace | 0x0E | 0x66 | -| Insert | 0xE052 | 0xE070 | -| Home | 0xE047 | 0xE06C | -| PageUp | 0xE049 | 0xE07D | -| NumpadLock | 0x45 | 0x77 | -| NumpadDivide | 0xE035 | 0xE04A | -| NumpadMultiply | 0x37 | 0x7C | -| NumpadSubtract | 0x4A | 0x7B | -| - | -- | -- | -| Tab | 0x0F | 0x0D | -| Q | 0x10 | 0x15 | -| W | 0x11 | 0x1D | -| E | 0x12 | 0x24 | -| R | 0x13 | 0x2D | -| T | 0x14 | 0x2C | -| Y | 0x15 | 0x35 | -| U | 0x16 | 0x3C | -| I | 0x17 | 0x43 | -| O | 0x18 | 0x44 | -| P | 0x19 | 0x4D | -| Oem4 | 0x1A | 0x54 | -| Oem6 | 0x1B | 0x5B | -| Oem5 | 0x56 | 0x61 | -| Oem7 | 0x2B | 0x5D | -| Delete | 0xE053 | 0xE071 | -| End | 0xE04F | 0xE069 | -| PageDown | 0xE051 | 0xE07A | -| Numpad7 | 0x47 | 0x6C | -| Numpad8 | 0x48 | 0x75 | -| Numpad9 | 0x49 | 0x7D | -| NumpadAdd | 0x4E | 0x79 | -| - | -- | -- | -| CapsLock | 0x3A | 0x58 | -| A | 0x1E | 0x1C | -| S | 0x1F | 0x1B | -| D | 0x20 | 0x23 | -| F | 0x21 | 0x2B | -| G | 0x22 | 0x34 | -| H | 0x23 | 0x33 | -| J | 0x24 | 0x3B | -| K | 0x25 | 0x42 | -| L | 0x26 | 0x4B | -| Oem1 | 0x27 | 0x4C | -| Oem3 | 0x28 | 0x52 | -| Return | 0x1C | 0x5A | -| Numpad4 | 0x4B | 0x6B | -| Numpad5 | 0x4C | 0x73 | -| Numpad6 | 0x4D | 0x74 | -| - | -- | -- | -| LShift | 0x2A | 0x12 | -| Z | 0x2C | 0x1A | -| X | 0x2D | 0x22 | -| C | 0x2E | 0x21 | -| V | 0x2F | 0x2A | -| B | 0x30 | 0x32 | -| N | 0x31 | 0x31 | -| M | 0x32 | 0x3A | -| OemComma | 0x33 | 0x41 | -| OemPeriod | 0x34 | 0x49 | -| Oem2 | 0x35 | 0x4A | -| RShift | 0x36 | 0x59 | -| ArrowUp | 0xE048 | 0xE075 | -| Numpad1 | 0x4F | 0x69 | -| Numpad2 | 0x50 | 0x72 | -| Numpad3 | 0x51 | 0x7A | -| NumpadEnter | 0xE01C | 0xE075 | -| - | -- | -- | -| LControl | 0x1D | 0x14 | -| LWin | 0xE05B | 0xE01F | -| LAlt | 0x38 | 0x11 | -| Spacebar | 0x39 | 0x29 | -| RAltGr | 0xE038 | 0xE011 | -| RWin | 0xE05C | 0xE027 | -| Apps | 0xE05C | 0xE02F | -| RControl | 0xE01D | 0xE014 | -| ArrowLeft | 0xE04B | 0xE06B | -| ArrowDown | 0xE050 | 0xE072 | -| ArrowRight | 0xE04D | 0xE074 | -| Numpad0 | 0x52 | 0x70 | -| NumpadPeriod | 0x53 | 0x71 | -| - | -- | -- | -| Oem9 | 0x7B | 0x67 | -| Oem10 | 0x79 | 0x64 | -| Oem11 | 0x70 | 0x13 | -| Oem12 | 0x73 | 0x51 | -| Oem13 | 0x7D | 0x6A | -| - | -- | -- | -| PrevTrack | 0xE010 | 0xE015 | -| NextTrack | 0xE019 | 0xE04D | -| Mute | 0xE020 | 0xE023 | -| Calculator | 0xE021 | 0xE02B | -| Play | 0xE022 | 0xE034 | -| Stop | 0xE024 | 0xE03B | -| VolumeDown | 0xE02E | 0xE021 | -| VolumeUp | 0xE030 | 0xE032 | -| WWWHome | 0xE032 | 0xE03A | -| TooManyKeys | -- | 0x00 | -| PowerOnTestOk | -- | 0xAA | -| RControl2 | 0xE11D | 0xE114 | -| RAlt2 | 0xE02A | 0xE012 | - -__Note 1:__ `PauseBreak` does not have a scancode because it's something we infer from a -sequence of other keypresses (`NumLock` with `RControl2` held). - -__Note 2:__ `SysReq` doesn't have a key on the diagram, because the scancode is -only generated when you do `Alt` + `PrintScreen`. +See for documentation. ## Minimum Supported Rust Version (MSRV) diff --git a/src/lib.rs b/src/lib.rs index 172102a..f6e55d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,19 +3,301 @@ //! Supports PS/2 Scan Code Set 1 and 2, on a variety of keyboard layouts. See //! [the OSDev Wiki](https://wiki.osdev.org/PS/2_Keyboard). //! -//! There are three basic steps to handling keyboard input. Your application may bypass some of these. +//! There is also [`Keyboard`] which combines the above three functions into a single object. +//! +//! ## Supports: +//! +//! - Scancode Set 1 (from the i8042 PC keyboard controller) +//! - Scancode Set 2 (direct from the AT or PS/2 interface keyboard) +//! - Several keyboard layouts: +//! +//! | Name | No. Keys | Description | Link | +//! | --------------------------------------- | -------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | +//! | [`Us104Key`](layouts::Us104Key) | 101/104 | North American standard English | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#United_States) | +//! | [`Uk105Key`](layouts::Uk105Key) | 102/105 | United Kingdom standard English | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#United_Kingdom) | +//! | [`Azerty`](layouts::Azerty) | 102/105 | Typically used in French locales | [Wikipedia](https://en.wikipedia.org/wiki/AZERTY) | +//! | [`De105Key`](layouts::De105Key) | 102/105 | German layout | [Wikipedia](https://en.wikipedia.org/wiki/QWERTZ) | +//! | [`FiSe105Key`](layouts::FiSe105Key) | 102/105 | Finnish/Swedish layout | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#Finnish%E2%80%93Swedish) | +//! | [`No105Key`](layouts::No105Key) | 102/105 | Norwegian layout | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#Norwegian) | +//! | [`Jis109Key`](layouts::Jis109Key) | 106/109 | JIS 109-key layout (Latin chars only) | [Wikipedia](https://en.wikipedia.org/wiki/Japanese_input_method#Japanese_keyboards) | +//! | [`Colemak`](layouts::Colemak) | 101/104 | A keyboard layout designed to make typing more efficient and comfortable | [Wikipedia](https://en.wikipedia.org/wiki/Colemak) | +//! | [`Dvorak104Key`](layouts::Dvorak104Key) | 101/104 | The more 'ergonomic' alternative to QWERTY | [Wikipedia](https://en.wikipedia.org/wiki/Dvorak_keyboard_layout) | +//! | [`DVP104Key`](layouts::DVP104Key) | 101/104 | Dvorak for Programmers | [Wikipedia](https://en.wikipedia.org/wiki/Dvorak_keyboard_layout#Programmer_Dvorak) | +//! +//! 101/104 keys is ANSI layout (wide Enter key) and 102/105 keys is ISO layout +//! (tall Enter key). The difference between 101 and 104 (and between 102 and +//! 105) comes from the two Windows keys and the Menu key that were added when +//! Windows 95 came out. JIS keyboards have extra keys, added by making the +//! space-bar and backspace keys shorter. //! -//! * [`Ps2Decoder`] - converts 11-bit PS/2 words into bytes, removing the start/stop +//! ## Usage +//! +//! There are three basic steps to handling keyboard input. Your application +//! may bypass some of these. +//! +//! * `Ps2Decoder` - converts 11-bit PS/2 words into bytes, removing the start/stop //! bits and checking the parity bits. Only needed if you talk to the PS/2 //! keyboard over GPIO pins and not required if you talk to the i8042 PC keyboard //! controller. -//! * [`ScancodeSet`] - converts from Scancode Set 1 (i8042 PC keyboard controller) or -//! Scancode Set 2 (raw PS/2 keyboard output) into a symbolic [`KeyCode`] and an -//! up/down [`KeyState`]. -//! * [`EventDecoder`] - converts symbolic [`KeyCode`] and [`KeyState`] into a Unicode -//! characters (where possible) according to the currently selected `KeyboardLayout`. +//! * `ScancodeSet` - converts from Scancode Set 1 (i8042 PC keyboard controller) or +//! Scancode Set 2 (raw PS/2 keyboard output) into a symbolic `KeyCode` and an +//! up/down `KeyState`. +//! * `EventDecoder` - converts symbolic `KeyCode` and `KeyState` into a +//! Unicode characters (where possible) according to the currently selected +//! `KeyboardLayout`. //! -//! There is also [`Keyboard`] which combines the above three functions into a single object. +//! There is also `Keyboard` which combines the above three functions into a +//! single object. +//! +//! See the [`examples`](./examples) folder for more details. +//! +//! ## [Documentation](https://docs.rs/crate/pc-keyboard) +//! +//! ## Keycodes +//! +//! This crate uses symbolic keycodes to abstract over Scancode Set 1 and +//! Scancode Set 2. They represented by the `KeyCode` enum. The scancodes can +//! come from one of three supported keyboards: 102/105 key ISO, 101/104 key +//! ANSI and 106/109-key JIS. +//! +//! ### 102/105 key ISO +//! +//! This is the mapping of `KeyCode` to a 102/105-key ISO keyboard: +//! +//! ```text +//! ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +//! │Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│ +//! └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +//! +//! ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +//! │Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│ +//! ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +//! │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Enter │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │ +//! ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤Num+│ +//! │CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│Oem7│ │ │Num4│Num5│Num6│ │ +//! ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +//! │LShf│Oem5│ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│ RShift │ │ Up │ │Num1│Num2│Num3│ │ +//! ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │ +//! │LCtrl│LWin │ Alt │ Space │AltGr│RWin │ Menu │RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│ +//! └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +//! ``` +//! +//! The 102-key is missing `LWin`, `RWin`, and `Menu`. +//! +//! (Reference: ) +//! +//! ### 101/104 key ANSI +//! +//! This is the mapping of `KeyCode` to a 101/104-key ANSI keyboard: +//! +//! ```text +//! ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +//! │Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│ +//! └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +//! +//! ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +//! │Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│ +//! ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +//! │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Oem7 │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │ +//! ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤Num+│ +//! │CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│ Enter │ │Num4│Num5│Num6│ │ +//! ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +//! │ LShift │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│ RShift │ │ Up │ │Num1│Num2│Num3│ │ +//! ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │ +//! │LCtrl│LWin │ Alt │ Space │AltGr│RWin │ Menu │RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│ +//! └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +//! ``` +//! +//! Note that the `Oem5` key is missing on the 104-key ANSI keyboard. +//! +//! The 101-key is also missing `LWin`, `RWin`, and `Menu`. +//! +//! (Reference: ) +//! +//! ### 106/109 key JIS +//! +//! This is the mapping of `KeyCode` to a 106/109-key JIS keyboard: +//! +//! ```text +//! ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +//! │Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│ +//! └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +//! +//! ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +//! │Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Om13│BkSp│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│ +//! ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +//! │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Enter │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │ +//! ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤Num+│ +//! │CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│Oem7│ │ │Num4│Num5│Num6│ │ +//! ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +//! │LShift │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│Oem12 │RShift │ │ Up │ │Num1│Num2│Num3│ │ +//! ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │ +//! │LCtrl│LWin │LAlt │Oem9 │ Space Bar │Oem10│Oem11│RWin│Menu│RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│ +//! └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +//! ``` +//! +//! Note that the `Oem5` is missing on the 109-key JIS layout, but `Oem9` (Muhenkan), `Oem10` (Henkan/Zenkouho), `Oem11` (Hiragana/Katakana), `Oem12` (Backslash) and `Oem13` (¥) are added. +//! +//! The 106-key is missing `LWin`, `RWin`, and `Menu`. +//! +//! (Reference: ) +//! +//! ### Conversion Table +//! +//! Scancode Set 1 and Scancode Set 2 can be losslessly converted. Indeed, this is +//! what the i8042 keyboard controller in your PC does - it takes Scancode Set 2 +//! from the keyboard and provides Scancode Set 1 to the Operating System. This +//! allowed them to change the keyboard design without breaking compatibility with +//! any MS-DOS applications that read raw scancodes from the keyboard. +//! +//! This table shows the correspondence between our symbolic KeyCode, Scancode Set 1 +//! and Scancode Set 2. We may extend this in the future to also handle USB HID +//! Scancodes. Any codes prefixed `0xE0` or `0xE1` are *extended* multi-byte +//! scancodes. Typically these are keys that were not on the IBM PC and PC/XT +//! keyboards so they they were added in such a way that if you ignored the 0xE0, +//! you got a reasonable result anyway. For example `ArrowLeft` is `0xE04B` in +//! Scancode Set 1 because `Numpad4` is `0x4B` and that was the left-arrow key on an +//! IBM PC or PC/XT. +//! +//! | Symbolic Key | Scancode Set 1 | Scancode Set 2 | +//! | -------------- | -------------- | -------------- | +//! | Escape | 0x01 | 0x76 | +//! | F1 | 0x3B | 0x05 | +//! | F2 | 0x3C | 0x06 | +//! | F3 | 0x3D | 0x04 | +//! | F4 | 0x3E | 0x0C | +//! | F5 | 0x3F | 0x03 | +//! | F6 | 0x40 | 0x0B | +//! | F7 | 0x41 | 0x83 | +//! | F8 | 0x42 | 0x0A | +//! | F9 | 0x43 | 0x01 | +//! | F10 | 0x44 | 0x09 | +//! | F11 | 0x57 | 0x78 | +//! | F12 | 0x58 | 0x07 | +//! | PrintScreen | 0xE037 | 0xE07C | +//! | SysRq | 0x54 | 0x7F | +//! | ScrollLock | 0x46 | 0x7E | +//! | PauseBreak | -- | -- | +//! | - | -- | -- | +//! | Oem8 | 0x29 | 0x0E | +//! | Key1 | 0x02 | 0x16 | +//! | Key2 | 0x03 | 0x1E | +//! | Key3 | 0x04 | 0x26 | +//! | Key4 | 0x05 | 0x25 | +//! | Key5 | 0x06 | 0x2E | +//! | Key6 | 0x07 | 0x36 | +//! | Key7 | 0x08 | 0x3D | +//! | Key8 | 0x09 | 0x3E | +//! | Key9 | 0x0A | 0x46 | +//! | Key0 | 0x0B | 0x45 | +//! | OemMinus | 0x0C | 0x4E | +//! | OemPlus | 0x0D | 0x55 | +//! | Backspace | 0x0E | 0x66 | +//! | Insert | 0xE052 | 0xE070 | +//! | Home | 0xE047 | 0xE06C | +//! | PageUp | 0xE049 | 0xE07D | +//! | NumpadLock | 0x45 | 0x77 | +//! | NumpadDivide | 0xE035 | 0xE04A | +//! | NumpadMultiply | 0x37 | 0x7C | +//! | NumpadSubtract | 0x4A | 0x7B | +//! | - | -- | -- | +//! | Tab | 0x0F | 0x0D | +//! | Q | 0x10 | 0x15 | +//! | W | 0x11 | 0x1D | +//! | E | 0x12 | 0x24 | +//! | R | 0x13 | 0x2D | +//! | T | 0x14 | 0x2C | +//! | Y | 0x15 | 0x35 | +//! | U | 0x16 | 0x3C | +//! | I | 0x17 | 0x43 | +//! | O | 0x18 | 0x44 | +//! | P | 0x19 | 0x4D | +//! | Oem4 | 0x1A | 0x54 | +//! | Oem6 | 0x1B | 0x5B | +//! | Oem5 | 0x56 | 0x61 | +//! | Oem7 | 0x2B | 0x5D | +//! | Delete | 0xE053 | 0xE071 | +//! | End | 0xE04F | 0xE069 | +//! | PageDown | 0xE051 | 0xE07A | +//! | Numpad7 | 0x47 | 0x6C | +//! | Numpad8 | 0x48 | 0x75 | +//! | Numpad9 | 0x49 | 0x7D | +//! | NumpadAdd | 0x4E | 0x79 | +//! | - | -- | -- | +//! | CapsLock | 0x3A | 0x58 | +//! | A | 0x1E | 0x1C | +//! | S | 0x1F | 0x1B | +//! | D | 0x20 | 0x23 | +//! | F | 0x21 | 0x2B | +//! | G | 0x22 | 0x34 | +//! | H | 0x23 | 0x33 | +//! | J | 0x24 | 0x3B | +//! | K | 0x25 | 0x42 | +//! | L | 0x26 | 0x4B | +//! | Oem1 | 0x27 | 0x4C | +//! | Oem3 | 0x28 | 0x52 | +//! | Return | 0x1C | 0x5A | +//! | Numpad4 | 0x4B | 0x6B | +//! | Numpad5 | 0x4C | 0x73 | +//! | Numpad6 | 0x4D | 0x74 | +//! | - | -- | -- | +//! | LShift | 0x2A | 0x12 | +//! | Z | 0x2C | 0x1A | +//! | X | 0x2D | 0x22 | +//! | C | 0x2E | 0x21 | +//! | V | 0x2F | 0x2A | +//! | B | 0x30 | 0x32 | +//! | N | 0x31 | 0x31 | +//! | M | 0x32 | 0x3A | +//! | OemComma | 0x33 | 0x41 | +//! | OemPeriod | 0x34 | 0x49 | +//! | Oem2 | 0x35 | 0x4A | +//! | RShift | 0x36 | 0x59 | +//! | ArrowUp | 0xE048 | 0xE075 | +//! | Numpad1 | 0x4F | 0x69 | +//! | Numpad2 | 0x50 | 0x72 | +//! | Numpad3 | 0x51 | 0x7A | +//! | NumpadEnter | 0xE01C | 0xE075 | +//! | - | -- | -- | +//! | LControl | 0x1D | 0x14 | +//! | LWin | 0xE05B | 0xE01F | +//! | LAlt | 0x38 | 0x11 | +//! | Spacebar | 0x39 | 0x29 | +//! | RAltGr | 0xE038 | 0xE011 | +//! | RWin | 0xE05C | 0xE027 | +//! | Apps | 0xE05C | 0xE02F | +//! | RControl | 0xE01D | 0xE014 | +//! | ArrowLeft | 0xE04B | 0xE06B | +//! | ArrowDown | 0xE050 | 0xE072 | +//! | ArrowRight | 0xE04D | 0xE074 | +//! | Numpad0 | 0x52 | 0x70 | +//! | NumpadPeriod | 0x53 | 0x71 | +//! | - | -- | -- | +//! | Oem9 | 0x7B | 0x67 | +//! | Oem10 | 0x79 | 0x64 | +//! | Oem11 | 0x70 | 0x13 | +//! | Oem12 | 0x73 | 0x51 | +//! | Oem13 | 0x7D | 0x6A | +//! | - | -- | -- | +//! | PrevTrack | 0xE010 | 0xE015 | +//! | NextTrack | 0xE019 | 0xE04D | +//! | Mute | 0xE020 | 0xE023 | +//! | Calculator | 0xE021 | 0xE02B | +//! | Play | 0xE022 | 0xE034 | +//! | Stop | 0xE024 | 0xE03B | +//! | VolumeDown | 0xE02E | 0xE021 | +//! | VolumeUp | 0xE030 | 0xE032 | +//! | WWWHome | 0xE032 | 0xE03A | +//! | TooManyKeys | -- | 0x00 | +//! | PowerOnTestOk | -- | 0xAA | +//! | RControl2 | 0xE11D | 0xE114 | +//! | RAlt2 | 0xE02A | 0xE012 | +//! +//! __Note 1:__ `PauseBreak` does not have a scancode because it's something we infer from a +//! sequence of other keypresses (`NumLock` with `RControl2` held). +//! +//! __Note 2:__ `SysReq` doesn't have a key on the diagram, because the scancode is +//! only generated when you do `Alt` + `PrintScreen`. #![cfg_attr(not(test), no_std)] From 393e223e28c40a85f52d3e2044adcf8e5f1dc60b Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Mon, 2 Jun 2025 13:42:07 +0100 Subject: [PATCH 02/18] Use Unicode literals Using Unicode Literals ('\u{0000}') is more consistent with the diagrams I am about to add, and forces us to standardise on one notation instead of a mixture of decimal and hexadecimal. --- src/layouts/azerty.rs | 14 +++++++------- src/layouts/colemak.rs | 14 +++++++------- src/layouts/de105.rs | 8 ++++---- src/layouts/dvorak_programmer104.rs | 14 +++++++------- src/layouts/jis109.rs | 2 +- src/layouts/no105.rs | 10 +++++----- src/layouts/us104.rs | 14 +++++++------- 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/layouts/azerty.rs b/src/layouts/azerty.rs index 9c721c7..6924dd3 100644 --- a/src/layouts/azerty.rs +++ b/src/layouts/azerty.rs @@ -20,7 +20,7 @@ impl KeyboardLayout for Azerty { ) -> DecodedKey { let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Oem8 => DecodedKey::Unicode('²'), KeyCode::Oem5 => { if modifiers.is_shifted() { @@ -135,8 +135,8 @@ impl KeyboardLayout for Azerty { DecodedKey::Unicode('=') } } - KeyCode::Backspace => DecodedKey::Unicode(0x08.into()), - KeyCode::Tab => DecodedKey::Unicode(0x09.into()), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), KeyCode::Q => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{0001}') @@ -350,7 +350,7 @@ impl KeyboardLayout for Azerty { } } // Enter gives LF, not CRLF or CR - KeyCode::Return => DecodedKey::Unicode(10.into()), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), KeyCode::Z => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{0017}') @@ -434,7 +434,7 @@ impl KeyboardLayout for Azerty { } } KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode(127.into()), + KeyCode::Delete => DecodedKey::Unicode('\u{007F}'), KeyCode::NumpadDivide => DecodedKey::Unicode('/'), KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), @@ -507,10 +507,10 @@ impl KeyboardLayout for Azerty { if modifiers.numlock { DecodedKey::Unicode('.') } else { - DecodedKey::Unicode(127.into()) + DecodedKey::Unicode('\u{007F}') } } - KeyCode::NumpadEnter => DecodedKey::Unicode(10.into()), + KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), k => DecodedKey::RawKey(k), } } diff --git a/src/layouts/colemak.rs b/src/layouts/colemak.rs index 1114946..8bac2cc 100644 --- a/src/layouts/colemak.rs +++ b/src/layouts/colemak.rs @@ -23,7 +23,7 @@ impl KeyboardLayout for Colemak { DecodedKey::Unicode('`') } } - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Key1 => { if modifiers.is_shifted() { DecodedKey::Unicode('!') @@ -108,8 +108,8 @@ impl KeyboardLayout for Colemak { DecodedKey::Unicode('=') } } - KeyCode::Backspace => DecodedKey::Unicode(0x08.into()), - KeyCode::Tab => DecodedKey::Unicode(0x09.into()), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), KeyCode::Q => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{0011}') @@ -317,7 +317,7 @@ impl KeyboardLayout for Colemak { } } // Enter gives LF, not CRLF or CR - KeyCode::Return => DecodedKey::Unicode(10.into()), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), KeyCode::Z => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{001A}') @@ -403,7 +403,7 @@ impl KeyboardLayout for Colemak { } } KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode(127.into()), + KeyCode::Delete => DecodedKey::Unicode('\u{007F}'), KeyCode::NumpadDivide => DecodedKey::Unicode('/'), KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), @@ -476,10 +476,10 @@ impl KeyboardLayout for Colemak { if modifiers.numlock { DecodedKey::Unicode('.') } else { - DecodedKey::Unicode(127.into()) + DecodedKey::Unicode('\u{007F}') } } - KeyCode::NumpadEnter => DecodedKey::Unicode(10.into()), + KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), k => DecodedKey::RawKey(k), } } diff --git a/src/layouts/de105.rs b/src/layouts/de105.rs index 96e57e7..e40fdb1 100644 --- a/src/layouts/de105.rs +++ b/src/layouts/de105.rs @@ -18,7 +18,7 @@ impl KeyboardLayout for De105Key { ) -> DecodedKey { let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Oem8 => { if modifiers.is_shifted() { DecodedKey::Unicode('°') @@ -124,8 +124,8 @@ impl KeyboardLayout for De105Key { DecodedKey::Unicode('´') } } - KeyCode::Backspace => DecodedKey::Unicode(0x08.into()), - KeyCode::Tab => DecodedKey::Unicode(0x09.into()), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), KeyCode::Q => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{0011}') @@ -173,7 +173,7 @@ impl KeyboardLayout for De105Key { DecodedKey::Unicode('+') } } - KeyCode::Return => DecodedKey::Unicode(10.into()), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), KeyCode::Oem7 => { if modifiers.is_shifted() { DecodedKey::Unicode('\'') diff --git a/src/layouts/dvorak_programmer104.rs b/src/layouts/dvorak_programmer104.rs index 7c3bf4c..3f5efce 100644 --- a/src/layouts/dvorak_programmer104.rs +++ b/src/layouts/dvorak_programmer104.rs @@ -23,7 +23,7 @@ impl KeyboardLayout for DVP104Key { DecodedKey::Unicode('$') } } - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Key1 => { if modifiers.is_shifted() { DecodedKey::Unicode('%') @@ -108,8 +108,8 @@ impl KeyboardLayout for DVP104Key { DecodedKey::Unicode('=') } } - KeyCode::Backspace => DecodedKey::Unicode(0x08.into()), - KeyCode::Tab => DecodedKey::Unicode(0x09.into()), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), KeyCode::Q => { if modifiers.is_shifted() { DecodedKey::Unicode(':') @@ -312,7 +312,7 @@ impl KeyboardLayout for DVP104Key { DecodedKey::Unicode('-') } } - KeyCode::Return => DecodedKey::Unicode(10.into()), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), KeyCode::Z => { if modifiers.is_shifted() { DecodedKey::Unicode('"') @@ -402,7 +402,7 @@ impl KeyboardLayout for DVP104Key { } } KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode(127.into()), + KeyCode::Delete => DecodedKey::Unicode('\u{007F}'), KeyCode::NumpadDivide => DecodedKey::Unicode('/'), KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), @@ -475,10 +475,10 @@ impl KeyboardLayout for DVP104Key { if modifiers.numlock { DecodedKey::Unicode('.') } else { - DecodedKey::Unicode(127.into()) + DecodedKey::Unicode('\u{007F}') } } - KeyCode::NumpadEnter => DecodedKey::Unicode(10.into()), + KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), k => DecodedKey::RawKey(k), } } diff --git a/src/layouts/jis109.rs b/src/layouts/jis109.rs index 8bcf617..bb6b921 100644 --- a/src/layouts/jis109.rs +++ b/src/layouts/jis109.rs @@ -22,7 +22,7 @@ impl KeyboardLayout for Jis109Key { // hankaku/zenkaku/kanji DecodedKey::RawKey(KeyCode::Oem8) } - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Key1 => { if modifiers.is_shifted() { DecodedKey::Unicode('!') diff --git a/src/layouts/no105.rs b/src/layouts/no105.rs index 1c3a8bb..0e24fb0 100644 --- a/src/layouts/no105.rs +++ b/src/layouts/no105.rs @@ -16,7 +16,7 @@ impl KeyboardLayout for No105Key { ) -> DecodedKey { let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Oem8 => { if modifiers.is_shifted() { DecodedKey::Unicode('§') @@ -126,8 +126,8 @@ impl KeyboardLayout for No105Key { DecodedKey::Unicode('\\') } } - KeyCode::Backspace => DecodedKey::Unicode(0x08.into()), - KeyCode::Tab => DecodedKey::Unicode(0x09.into()), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), KeyCode::E => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{0005}') @@ -155,7 +155,7 @@ impl KeyboardLayout for No105Key { DecodedKey::Unicode('¨') } } - KeyCode::Return => DecodedKey::Unicode(10.into()), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), KeyCode::Oem7 => { if modifiers.is_shifted() { DecodedKey::Unicode('*') @@ -220,7 +220,7 @@ impl KeyboardLayout for No105Key { if modifiers.numlock { DecodedKey::Unicode(',') } else { - DecodedKey::Unicode(127.into()) + DecodedKey::Unicode('\u{007F}') } } e => { diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs index 6bcf85f..30f3f1f 100644 --- a/src/layouts/us104.rs +++ b/src/layouts/us104.rs @@ -23,7 +23,7 @@ impl KeyboardLayout for Us104Key { DecodedKey::Unicode('`') } } - KeyCode::Escape => DecodedKey::Unicode(0x1B.into()), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), KeyCode::Key1 => { if modifiers.is_shifted() { DecodedKey::Unicode('!') @@ -108,8 +108,8 @@ impl KeyboardLayout for Us104Key { DecodedKey::Unicode('=') } } - KeyCode::Backspace => DecodedKey::Unicode(0x08.into()), - KeyCode::Tab => DecodedKey::Unicode(0x09.into()), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), KeyCode::Q => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{0011}') @@ -317,7 +317,7 @@ impl KeyboardLayout for Us104Key { } } // Enter gives LF, not CRLF or CR - KeyCode::Return => DecodedKey::Unicode(10.into()), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), KeyCode::Z => { if map_to_unicode && modifiers.is_ctrl() { DecodedKey::Unicode('\u{001A}') @@ -403,7 +403,7 @@ impl KeyboardLayout for Us104Key { } } KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode(127.into()), + KeyCode::Delete => DecodedKey::Unicode('\u{007f}'), KeyCode::NumpadDivide => DecodedKey::Unicode('/'), KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), @@ -476,10 +476,10 @@ impl KeyboardLayout for Us104Key { if modifiers.numlock { DecodedKey::Unicode('.') } else { - DecodedKey::Unicode(127.into()) + DecodedKey::Unicode('\u{007f}') } } - KeyCode::NumpadEnter => DecodedKey::Unicode(10.into()), + KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), k => DecodedKey::RawKey(k), } } From 5676c985e24953b58445bd32c6b42697dfd8e9da Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Mon, 2 Jun 2025 14:01:47 +0100 Subject: [PATCH 03/18] Add diagrams, and tool to generate them, plus helper functions. --- examples/print_keyboard.rs | 373 +++++++++++++++++++ src/layouts/colemak.rs | 582 ++++++----------------------- src/layouts/uk105.rs | 204 ++++++++--- src/layouts/us104.rs | 732 +++++++++++++------------------------ src/lib.rs | 93 +++++ 5 files changed, 991 insertions(+), 993 deletions(-) create mode 100644 examples/print_keyboard.rs diff --git a/examples/print_keyboard.rs b/examples/print_keyboard.rs new file mode 100644 index 0000000..5ccdb57 --- /dev/null +++ b/examples/print_keyboard.rs @@ -0,0 +1,373 @@ +//! Prints a keyboard as a Unicode graphic + +use std::collections::HashMap; + +use pc_keyboard::{DecodedKey, KeyCode, KeyboardLayout, Modifiers}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum KeyboardKind { + Ansi, + Iso, +} + +fn main() { + println!("Keyboard Layouts"); + println!("================"); + println!(); + println!("Us104Key:"); + show_kb(KeyboardKind::Ansi, &pc_keyboard::layouts::Us104Key); + println!("Uk105Key:"); + show_kb(KeyboardKind::Iso, &pc_keyboard::layouts::Uk105Key); + println!("Colemak:"); + show_kb(KeyboardKind::Ansi, &pc_keyboard::layouts::Colemak); +} + +fn show_kb(kind: KeyboardKind, layout: &dyn KeyboardLayout) { + let mut modifiers = Modifiers { + lshift: false, + rshift: false, + lctrl: false, + rctrl: false, + numlock: true, + capslock: false, + lalt: false, + ralt: false, + rctrl2: false, + }; + println!("/// ## Unmodified"); + show_kb_modifiers(kind, layout, &modifiers); + + modifiers.capslock = true; + println!("/// ## Caps Lock"); + show_kb_modifiers(kind, layout, &modifiers); + modifiers.capslock = false; + + modifiers.lshift = true; + println!("/// ## Shifted"); + show_kb_modifiers(kind, layout, &modifiers); + modifiers.lshift = false; + + modifiers.rctrl = true; + println!("/// ## Control"); + show_kb_modifiers(kind, layout, &modifiers); + modifiers.rctrl = false; + + modifiers.ralt = true; + println!("/// ## AltGr"); + show_kb_modifiers(kind, layout, &modifiers); + modifiers.ralt = false; + + modifiers.ralt = true; + modifiers.lshift = true; + println!("/// ## Shift AltGr"); + show_kb_modifiers(kind, layout, &modifiers); + modifiers.ralt = false; + modifiers.lshift = false; +} + +fn show_kb_modifiers(kind: KeyboardKind, layout: &dyn KeyboardLayout, modifiers: &Modifiers) { + let mut map = Map::new(modifiers); + map.insert("esc", KeyCode::Escape, layout); + map.insert("oem8", KeyCode::Oem8, layout); + map.insert("key1", KeyCode::Key1, layout); + map.insert("key2", KeyCode::Key2, layout); + map.insert("key3", KeyCode::Key3, layout); + map.insert("key4", KeyCode::Key4, layout); + map.insert("key5", KeyCode::Key5, layout); + map.insert("key6", KeyCode::Key6, layout); + map.insert("key7", KeyCode::Key7, layout); + map.insert("key8", KeyCode::Key8, layout); + map.insert("key9", KeyCode::Key9, layout); + map.insert("key0", KeyCode::Key0, layout); + map.insert("oem_minus", KeyCode::OemMinus, layout); + map.insert("oem_plus", KeyCode::OemPlus, layout); + map.insert("backspace", KeyCode::Backspace, layout); + map.insert("numpad_divide", KeyCode::NumpadDivide, layout); + map.insert("numpad_multiply", KeyCode::NumpadMultiply, layout); + map.insert("numpad_subtract", KeyCode::NumpadSubtract, layout); + map.insert("tab", KeyCode::Tab, layout); + map.insert("oem4", KeyCode::Oem4, layout); + map.insert("oem6", KeyCode::Oem6, layout); + map.insert("oem7", KeyCode::Oem7, layout); + map.insert("delete", KeyCode::Delete, layout); + map.insert("numpad7", KeyCode::Numpad7, layout); + map.insert("numpad8", KeyCode::Numpad8, layout); + map.insert("numpad9", KeyCode::Numpad9, layout); + map.insert("numpadl", KeyCode::NumpadAdd, layout); + map.insert("oem1", KeyCode::Oem1, layout); + map.insert("oem3", KeyCode::Oem3, layout); + map.insert("enter", KeyCode::Return, layout); + map.insert("numpad4", KeyCode::Numpad4, layout); + map.insert("numpad5", KeyCode::Numpad5, layout); + map.insert("numpad6", KeyCode::Numpad6, layout); + map.insert("oem_comma", KeyCode::OemComma, layout); + map.insert("oem_period", KeyCode::OemPeriod, layout); + map.insert("oem2", KeyCode::Oem2, layout); + map.insert("numpad1", KeyCode::Numpad1, layout); + map.insert("numpad2", KeyCode::Numpad2, layout); + map.insert("numpad3", KeyCode::Numpad3, layout); + map.insert("numpade", KeyCode::NumpadEnter, layout); + map.insert("space", KeyCode::Spacebar, layout); + map.insert("numpad0", KeyCode::Numpad0, layout); + map.insert("numpad_period", KeyCode::NumpadPeriod, layout); + map.insert("q", KeyCode::Q, layout); + map.insert("w", KeyCode::W, layout); + map.insert("e", KeyCode::E, layout); + map.insert("r", KeyCode::R, layout); + map.insert("t", KeyCode::T, layout); + map.insert("y", KeyCode::Y, layout); + map.insert("u", KeyCode::U, layout); + map.insert("i", KeyCode::I, layout); + map.insert("o", KeyCode::O, layout); + map.insert("p", KeyCode::P, layout); + map.insert("a", KeyCode::A, layout); + map.insert("s", KeyCode::S, layout); + map.insert("d", KeyCode::D, layout); + map.insert("f", KeyCode::F, layout); + map.insert("g", KeyCode::G, layout); + map.insert("h", KeyCode::H, layout); + map.insert("j", KeyCode::J, layout); + map.insert("k", KeyCode::K, layout); + map.insert("l", KeyCode::L, layout); + map.insert("z", KeyCode::Z, layout); + map.insert("x", KeyCode::X, layout); + map.insert("c", KeyCode::C, layout); + map.insert("v", KeyCode::V, layout); + map.insert("b", KeyCode::B, layout); + map.insert("n", KeyCode::N, layout); + map.insert("m", KeyCode::M, layout); + if kind == KeyboardKind::Iso { + map.insert("oem5", KeyCode::Oem5, layout); + map.print_iso(); + } else { + map.print_ansi(); + } +} + +struct Map { + inner: HashMap<&'static str, char>, + modifiers: Modifiers, +} + +impl Map { + fn new(modifiers: &Modifiers) -> Map { + Map { + inner: HashMap::new(), + modifiers: modifiers.clone(), + } + } + + fn insert(&mut self, label: &'static str, keycode: KeyCode, layout: &dyn KeyboardLayout) { + match layout.map_keycode( + keycode, + &self.modifiers, + pc_keyboard::HandleControl::MapLettersToUnicode, + ) { + DecodedKey::Unicode(c) => self.inner.insert(label, c), + e => { + panic!("Wanted unicode from {:?}, got {:?}!", keycode, e); + } + }; + } + + fn get(&self, label: &'static str) -> String { + let c = self.inner.get(label).unwrap(); + let c_value = *c as u32; + if c_value <= 32 || c_value == 0x7F { + format!("{:04x}", c_value) + } else { + format!("{:^4}", c) + } + } + + fn print_ansi(&self) { + let es = self.get("esc"); + let o8 = self.get("oem8"); + let k1 = self.get("key1"); + let k2 = self.get("key2"); + let k3 = self.get("key3"); + let k4 = self.get("key4"); + let k5 = self.get("key5"); + let k6 = self.get("key6"); + let k7 = self.get("key7"); + let k8 = self.get("key8"); + let k9 = self.get("key9"); + let k0 = self.get("key0"); + let om = self.get("oem_minus"); + let ol = self.get("oem_plus"); + let bs = self.get("backspace"); + let nd = self.get("numpad_divide"); + let nm = self.get("numpad_multiply"); + let ns = self.get("numpad_subtract"); + let tb = self.get("tab"); + let o4 = self.get("oem4"); + let o6 = self.get("oem6"); + let o7 = self.get("oem7"); + let de = self.get("delete"); + let n7 = self.get("numpad7"); + let n8 = self.get("numpad8"); + let n9 = self.get("numpad9"); + let nl = self.get("numpadl"); + let o1 = self.get("oem1"); + let o3 = self.get("oem3"); + let en = self.get("enter"); + let n4 = self.get("numpad4"); + let n5 = self.get("numpad5"); + let n6 = self.get("numpad6"); + let oc = self.get("oem_comma"); + let op = self.get("oem_period"); + let o2 = self.get("oem2"); + let n1 = self.get("numpad1"); + let n2 = self.get("numpad2"); + let n3 = self.get("numpad3"); + let ne = self.get("numpade"); + let sp = self.get("space"); + let n0 = self.get("numpad0"); + let np = self.get("numpad_period"); + + let kq = self.get("q"); + let kw = self.get("w"); + let ke = self.get("e"); + let kr = self.get("r"); + let kt = self.get("t"); + let ky = self.get("y"); + let ku = self.get("u"); + let ki = self.get("i"); + let ko = self.get("o"); + let kp = self.get("p"); + let ka = self.get("a"); + let ks = self.get("s"); + let kd = self.get("d"); + let kf = self.get("f"); + let kg = self.get("g"); + let kh = self.get("h"); + let kj = self.get("j"); + let kk = self.get("k"); + let kl = self.get("l"); + let kz = self.get("z"); + let kx = self.get("x"); + let kc = self.get("c"); + let kv = self.get("v"); + let kb = self.get("b"); + let kn = self.get("n"); + let km = self.get("m"); + + println!( + r#"/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │{es}│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │{o8}│{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│{bs} │ │ │ │ │ │ │{nd}│{nm}│{ns}│ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │{tb} │{kq}│{kw}│{ke}│{kr}│{kt}│{ky}│{ku}│{ki}│{ko}│{kp}│{o4}│{o6}│ {o7} │ │{de}│ │ │ │{n7}│{n8}│{n9}│ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤{nl}│ +/// │ │{ka}│{ks}│{kd}│{kf}│{kg}│{kh}│{kj}│{kk}│{kl}│{o1}│{o3}│ {en} │ │{n4}│{n5}│{n6}│ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │{kz}│{kx}│{kc}│{kv}│{kb}│{kn}│{km}│{oc}│{op}│{o2}│ │ │ │ │{n1}│{n2}│{n3}│ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤{ne}│ +/// │ │ │ │ {sp} │ │ │ │ │ │ │ │ │ │{n0} │{np}│ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +///"# + ); + } + + fn print_iso(&self) { + let es = self.get("esc"); + let o8 = self.get("oem8"); + let k1 = self.get("key1"); + let k2 = self.get("key2"); + let k3 = self.get("key3"); + let k4 = self.get("key4"); + let k5 = self.get("key5"); + let k6 = self.get("key6"); + let k7 = self.get("key7"); + let k8 = self.get("key8"); + let k9 = self.get("key9"); + let k0 = self.get("key0"); + let om = self.get("oem_minus"); + let ol = self.get("oem_plus"); + let bs = self.get("backspace"); + let nd = self.get("numpad_divide"); + let nm = self.get("numpad_multiply"); + let ns = self.get("numpad_subtract"); + let tb = self.get("tab"); + let o4 = self.get("oem4"); + let o6 = self.get("oem6"); + let o7 = self.get("oem7"); + let de = self.get("delete"); + let n7 = self.get("numpad7"); + let n8 = self.get("numpad8"); + let n9 = self.get("numpad9"); + let nl = self.get("numpadl"); + let o1 = self.get("oem1"); + let o3 = self.get("oem3"); + let en = self.get("enter"); + let n4 = self.get("numpad4"); + let n5 = self.get("numpad5"); + let n6 = self.get("numpad6"); + let oc = self.get("oem_comma"); + let op = self.get("oem_period"); + let o2 = self.get("oem2"); + let n1 = self.get("numpad1"); + let n2 = self.get("numpad2"); + let n3 = self.get("numpad3"); + let ne = self.get("numpade"); + let sp = self.get("space"); + let n0 = self.get("numpad0"); + let np = self.get("numpad_period"); + let o5 = self.get("oem5"); + + let kq = self.get("q"); + let kw = self.get("w"); + let ke = self.get("e"); + let kr = self.get("r"); + let kt = self.get("t"); + let ky = self.get("y"); + let ku = self.get("u"); + let ki = self.get("i"); + let ko = self.get("o"); + let kp = self.get("p"); + let ka = self.get("a"); + let ks = self.get("s"); + let kd = self.get("d"); + let kf = self.get("f"); + let kg = self.get("g"); + let kh = self.get("h"); + let kj = self.get("j"); + let kk = self.get("k"); + let kl = self.get("l"); + let kz = self.get("z"); + let kx = self.get("x"); + let kc = self.get("c"); + let kv = self.get("v"); + let kb = self.get("b"); + let kn = self.get("n"); + let km = self.get("m"); + + println!( + r#"/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │{es}│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │{o8}│{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│{bs} │ │ │ │ │ │ │{nd}│{nm}│{ns}│ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │{tb} │{kq}│{kw}│{ke}│{kr}│{kt}│{ky}│{ku}│{ki}│{ko}│{kp}│{o4}│{o6}│ {en} │ │{de}│ │ │ │{n7}│{n8}│{n9}│ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤{nl}│ +/// │ │{ka}│{ks}│{kd}│{kf}│{kg}│{kh}│{kj}│{kk}│{kl}│{o1}│{o3}│{o7}│ │ │{n4}│{n5}│{n6}│ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │{o5}│{kz}│{kx}│{kc}│{kv}│{kb}│{kn}│{km}│{oc}│{op}│{o2}│ │ │ │ │{n1}│{n2}│{n3}│ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤{ne}│ +/// │ │ │ │ {sp} │ │ │ │ │ │ │ │ │ │{n0} │{np}│ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +///"# + ); + } +} diff --git a/src/layouts/colemak.rs b/src/layouts/colemak.rs index 8bac2cc..c2e3854 100644 --- a/src/layouts/colemak.rs +++ b/src/layouts/colemak.rs @@ -1,486 +1,134 @@ -//! The Colemak keyboard support +//! Colemak keyboard support use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; /// A Colemak 101-key (or 104-key including Windows keys) keyboard. /// /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). +/// +/// Based on US 101/104 key, with the letters re-arranged. +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are +/// sometimes Unicode and sometimes not, depending on modifiers. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ f │ p │ g │ j │ l │ u │ y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ r │ s │ t │ d │ h │ n │ e │ i │ o │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ z │ x │ c │ v │ b │ k │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ K │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ : │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ " │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ K │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0006│0010│0007│000a│000c│0015│0019│ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0012│0013│0014│0004│0008│000e│0005│0009│000f│ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │001a│0018│0003│0016│0002│000b│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// pub struct Colemak; impl KeyboardLayout for Colemak { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Oem8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('`') - } - } - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('!') - } else { - DecodedKey::Unicode('1') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('@') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('#') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else { - DecodedKey::Unicode('5') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('^') - } else { - DecodedKey::Unicode('6') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('&') - } else { - DecodedKey::Unicode('7') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('*') - } else { - DecodedKey::Unicode('8') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('(') - } else { - DecodedKey::Unicode('9') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode(')') - } else { - DecodedKey::Unicode('0') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('+') - } else { - DecodedKey::Unicode('=') - } - } - KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), - KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::Q => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0011}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Q') - } else { - DecodedKey::Unicode('q') - } - } - KeyCode::W => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0017}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('W') - } else { - DecodedKey::Unicode('w') - } - } - KeyCode::E => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0006}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('F') - } else { - DecodedKey::Unicode('f') - } - } - KeyCode::R => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0010}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('P') - } else { - DecodedKey::Unicode('p') - } - } - KeyCode::T => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0007}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('G') - } else { - DecodedKey::Unicode('g') - } - } - KeyCode::Y => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('J') - } else { - DecodedKey::Unicode('j') - } - } - KeyCode::U => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000C}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('L') - } else { - DecodedKey::Unicode('l') - } - } - KeyCode::I => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0015}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('U') - } else { - DecodedKey::Unicode('u') - } - } - KeyCode::O => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0019}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Y') - } else { - DecodedKey::Unicode('y') - } - } - KeyCode::P => { - if modifiers.is_caps() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode(';') - } - } - KeyCode::Oem4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('[') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode(']') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('\\') - } - } - KeyCode::A => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0001}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('A') - } else { - DecodedKey::Unicode('a') - } - } - KeyCode::S => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0012}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('R') - } else { - DecodedKey::Unicode('r') - } - } - KeyCode::D => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0013}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('S') - } else { - DecodedKey::Unicode('s') - } - } - KeyCode::F => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0014}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('T') - } else { - DecodedKey::Unicode('t') - } - } - KeyCode::G => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0004}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('D') - } else { - DecodedKey::Unicode('d') - } - } - KeyCode::H => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0008}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('H') - } else { - DecodedKey::Unicode('h') - } - } - KeyCode::J => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000E}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('N') - } else { - DecodedKey::Unicode('n') - } - } - KeyCode::K => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::L => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0009}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('I') - } else { - DecodedKey::Unicode('i') - } - } - KeyCode::Oem1 => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000F}') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('O') - } else { - DecodedKey::Unicode('o') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('\'') - } - } - // Enter gives LF, not CRLF or CR - KeyCode::Return => DecodedKey::Unicode('\u{000A}'), - KeyCode::Z => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{001A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Z') - } else { - DecodedKey::Unicode('z') - } - } - KeyCode::X => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0018}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('X') - } else { - DecodedKey::Unicode('x') - } - } - KeyCode::C => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0003}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('C') - } else { - DecodedKey::Unicode('c') - } - } - KeyCode::V => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0016}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('V') - } else { - DecodedKey::Unicode('v') - } - } - KeyCode::B => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0002}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('B') - } else { - DecodedKey::Unicode('b') - } - } - KeyCode::N => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000B}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('K') - } else { - DecodedKey::Unicode('k') - } - } - KeyCode::M => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::OemComma => { - if modifiers.is_shifted() { - DecodedKey::Unicode('<') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::OemPeriod => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::Oem2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode('/') - } - } - KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode('\u{007F}'), - KeyCode::NumpadDivide => DecodedKey::Unicode('/'), - KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), - KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), - KeyCode::Numpad7 => { - if modifiers.numlock { - DecodedKey::Unicode('7') - } else { - DecodedKey::RawKey(KeyCode::Home) - } - } - KeyCode::Numpad8 => { - if modifiers.numlock { - DecodedKey::Unicode('8') - } else { - DecodedKey::RawKey(KeyCode::ArrowUp) - } - } - KeyCode::Numpad9 => { - if modifiers.numlock { - DecodedKey::Unicode('9') - } else { - DecodedKey::RawKey(KeyCode::PageUp) - } - } - KeyCode::NumpadAdd => DecodedKey::Unicode('+'), - KeyCode::Numpad4 => { - if modifiers.numlock { - DecodedKey::Unicode('4') - } else { - DecodedKey::RawKey(KeyCode::ArrowLeft) - } - } - KeyCode::Numpad5 => DecodedKey::Unicode('5'), - KeyCode::Numpad6 => { - if modifiers.numlock { - DecodedKey::Unicode('6') - } else { - DecodedKey::RawKey(KeyCode::ArrowRight) - } - } - KeyCode::Numpad1 => { - if modifiers.numlock { - DecodedKey::Unicode('1') - } else { - DecodedKey::RawKey(KeyCode::End) - } - } - KeyCode::Numpad2 => { - if modifiers.numlock { - DecodedKey::Unicode('2') - } else { - DecodedKey::RawKey(KeyCode::ArrowDown) - } - } - KeyCode::Numpad3 => { - if modifiers.numlock { - DecodedKey::Unicode('3') - } else { - DecodedKey::RawKey(KeyCode::PageDown) - } - } - KeyCode::Numpad0 => { - if modifiers.numlock { - DecodedKey::Unicode('0') - } else { - DecodedKey::RawKey(KeyCode::Insert) - } - } - KeyCode::NumpadPeriod => { - if modifiers.numlock { - DecodedKey::Unicode('.') - } else { - DecodedKey::Unicode('\u{007F}') - } - } - KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), - k => DecodedKey::RawKey(k), + // ========= Row 3 (QWERTY) ========= + KeyCode::E => modifiers.handle_alpha('F', handle_ctrl), + KeyCode::R => modifiers.handle_alpha('P', handle_ctrl), + KeyCode::T => modifiers.handle_alpha('G', handle_ctrl), + KeyCode::Y => modifiers.handle_alpha('J', handle_ctrl), + KeyCode::U => modifiers.handle_alpha('L', handle_ctrl), + KeyCode::I => modifiers.handle_alpha('U', handle_ctrl), + KeyCode::O => modifiers.handle_alpha('Y', handle_ctrl), + KeyCode::P => modifiers.handle_shift(';', ':'), + // ========= Row 4 (ASDFG) ========= + KeyCode::S => modifiers.handle_alpha('R', handle_ctrl), + KeyCode::D => modifiers.handle_alpha('S', handle_ctrl), + KeyCode::F => modifiers.handle_alpha('T', handle_ctrl), + KeyCode::G => modifiers.handle_alpha('D', handle_ctrl), + KeyCode::J => modifiers.handle_alpha('N', handle_ctrl), + KeyCode::K => modifiers.handle_alpha('E', handle_ctrl), + KeyCode::L => modifiers.handle_alpha('I', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_alpha('O', handle_ctrl), + // ========= Row 5 (ZXCVB) ========= + KeyCode::N => modifiers.handle_alpha('K', handle_ctrl), + // ========= Fallback ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } } diff --git a/src/layouts/uk105.rs b/src/layouts/uk105.rs index a189913..c75cf49 100644 --- a/src/layouts/uk105.rs +++ b/src/layouts/uk105.rs @@ -1,13 +1,145 @@ //! United Kingdom keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, QUO, SLS}; /// A standard United Kingdom 102-key (or 105-key including Windows keys) keyboard. /// /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). +/// +/// Based on US 101/104 key, with minor changes. +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are +/// sometimes Unicode and sometimes not, depending on modifiers. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ \ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ \ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ | │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ \ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ¦ │ 1 │ 2 │ 3 │ € │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ é │ r │ t │ y │ ú │ í │ ó │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ á │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ \ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ¦ │ ! │ " │ £ │ € │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ É │ R │ T │ Y │ Ú │ Í │ Ó │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ Á │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ | │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// pub struct Uk105Key; impl KeyboardLayout for Uk105Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, @@ -15,63 +147,19 @@ impl KeyboardLayout for Uk105Key { handle_ctrl: HandleControl, ) -> DecodedKey { match keycode { - KeyCode::Oem8 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('|') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('¬') - } else { - DecodedKey::Unicode('`') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('@') - } else { - DecodedKey::Unicode('\'') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('£') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('€') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('#') - } - } - KeyCode::Oem5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('\\') - } - } - e => { - let us = super::Us104Key; - us.map_keycode(e, modifiers, handle_ctrl) - } + KeyCode::Key2 => modifiers.handle_shift('2', '"'), + KeyCode::Key3 => modifiers.handle_shift('3', '£'), + KeyCode::Key4 => modifiers.handle_altsh('4', '$', '€'), + KeyCode::Oem3 => modifiers.handle_shift(QUO, '@'), + KeyCode::Oem5 => modifiers.handle_shift(SLS, '|'), + KeyCode::Oem7 => modifiers.handle_shift('#', '~'), + KeyCode::Oem8 => modifiers.handle_altsh('`', '¬', '¦'), + KeyCode::E => modifiers.handle_alalt('E', 'é', 'É', handle_ctrl), + KeyCode::U => modifiers.handle_alalt('U', 'ú', 'Ú', handle_ctrl), + KeyCode::I => modifiers.handle_alalt('I', 'í', 'Í', handle_ctrl), + KeyCode::O => modifiers.handle_alalt('O', 'ó', 'Ó', handle_ctrl), + KeyCode::A => modifiers.handle_alalt('A', 'á', 'Á', handle_ctrl), + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } } diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs index 30f3f1f..761c8cc 100644 --- a/src/layouts/us104.rs +++ b/src/layouts/us104.rs @@ -1,486 +1,187 @@ -//! United States keyboard support +//! # United States keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, QUO, SLS}; /// A standard United States 101-key (or 104-key including Windows keys) keyboard. /// /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are +/// sometimes Unicode and sometimes not, depending on modifiers. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// pub struct Us104Key; impl KeyboardLayout for Us104Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Oem8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('`') - } - } - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('!') - } else { - DecodedKey::Unicode('1') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('@') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('#') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else { - DecodedKey::Unicode('5') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('^') - } else { - DecodedKey::Unicode('6') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('&') - } else { - DecodedKey::Unicode('7') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('*') - } else { - DecodedKey::Unicode('8') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('(') - } else { - DecodedKey::Unicode('9') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode(')') - } else { - DecodedKey::Unicode('0') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('+') - } else { - DecodedKey::Unicode('=') - } - } - KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), - KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::Q => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0011}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Q') - } else { - DecodedKey::Unicode('q') - } - } - KeyCode::W => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0017}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('W') - } else { - DecodedKey::Unicode('w') - } - } - KeyCode::E => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::R => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0012}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('R') - } else { - DecodedKey::Unicode('r') - } - } - KeyCode::T => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0014}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('T') - } else { - DecodedKey::Unicode('t') - } - } - KeyCode::Y => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0019}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Y') - } else { - DecodedKey::Unicode('y') - } - } - KeyCode::U => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0015}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('U') - } else { - DecodedKey::Unicode('u') - } - } - KeyCode::I => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0009}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('I') - } else { - DecodedKey::Unicode('i') - } - } - KeyCode::O => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000F}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('O') - } else { - DecodedKey::Unicode('o') - } - } - KeyCode::P => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0010}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('P') - } else { - DecodedKey::Unicode('p') - } - } - KeyCode::Oem4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('[') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode(']') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('\\') - } - } - KeyCode::A => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0001}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('A') - } else { - DecodedKey::Unicode('a') - } - } - KeyCode::S => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0013}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('S') - } else { - DecodedKey::Unicode('s') - } - } - KeyCode::D => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0004}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('D') - } else { - DecodedKey::Unicode('d') - } - } - KeyCode::F => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0006}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('F') - } else { - DecodedKey::Unicode('f') - } - } - KeyCode::G => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0007}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('G') - } else { - DecodedKey::Unicode('g') - } - } - KeyCode::H => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0008}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('H') - } else { - DecodedKey::Unicode('h') - } - } - KeyCode::J => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('J') - } else { - DecodedKey::Unicode('j') - } - } - KeyCode::K => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000B}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('K') - } else { - DecodedKey::Unicode('k') - } - } - KeyCode::L => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000C}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('L') - } else { - DecodedKey::Unicode('l') - } - } - KeyCode::Oem1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode(';') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('\'') - } - } - // Enter gives LF, not CRLF or CR - KeyCode::Return => DecodedKey::Unicode('\u{000A}'), - KeyCode::Z => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{001A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Z') - } else { - DecodedKey::Unicode('z') - } - } - KeyCode::X => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0018}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('X') - } else { - DecodedKey::Unicode('x') - } - } - KeyCode::C => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0003}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('C') - } else { - DecodedKey::Unicode('c') - } - } - KeyCode::V => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0016}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('V') - } else { - DecodedKey::Unicode('v') - } - } - KeyCode::B => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0002}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('B') - } else { - DecodedKey::Unicode('b') - } - } - KeyCode::N => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000E}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('N') - } else { - DecodedKey::Unicode('n') - } - } - KeyCode::M => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::OemComma => { - if modifiers.is_shifted() { - DecodedKey::Unicode('<') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::OemPeriod => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::Oem2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode('/') - } - } - KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode('\u{007f}'), - KeyCode::NumpadDivide => DecodedKey::Unicode('/'), - KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), - KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), - KeyCode::Numpad7 => { - if modifiers.numlock { - DecodedKey::Unicode('7') - } else { - DecodedKey::RawKey(KeyCode::Home) - } - } - KeyCode::Numpad8 => { - if modifiers.numlock { - DecodedKey::Unicode('8') - } else { - DecodedKey::RawKey(KeyCode::ArrowUp) - } - } - KeyCode::Numpad9 => { - if modifiers.numlock { - DecodedKey::Unicode('9') - } else { - DecodedKey::RawKey(KeyCode::PageUp) - } - } - KeyCode::NumpadAdd => DecodedKey::Unicode('+'), - KeyCode::Numpad4 => { - if modifiers.numlock { - DecodedKey::Unicode('4') - } else { - DecodedKey::RawKey(KeyCode::ArrowLeft) - } - } - KeyCode::Numpad5 => DecodedKey::Unicode('5'), - KeyCode::Numpad6 => { - if modifiers.numlock { - DecodedKey::Unicode('6') - } else { - DecodedKey::RawKey(KeyCode::ArrowRight) - } - } - KeyCode::Numpad1 => { - if modifiers.numlock { - DecodedKey::Unicode('1') - } else { - DecodedKey::RawKey(KeyCode::End) - } - } - KeyCode::Numpad2 => { - if modifiers.numlock { - DecodedKey::Unicode('2') - } else { - DecodedKey::RawKey(KeyCode::ArrowDown) - } - } - KeyCode::Numpad3 => { - if modifiers.numlock { - DecodedKey::Unicode('3') - } else { - DecodedKey::RawKey(KeyCode::PageDown) - } - } - KeyCode::Numpad0 => { - if modifiers.numlock { - DecodedKey::Unicode('0') - } else { - DecodedKey::RawKey(KeyCode::Insert) - } - } - KeyCode::NumpadPeriod => { - if modifiers.numlock { - DecodedKey::Unicode('.') - } else { - DecodedKey::Unicode('\u{007f}') - } - } - KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), - k => DecodedKey::RawKey(k), + // ========= Row 2 (the numbers) ========= + KeyCode::Oem8 => modifiers.handle_shift('`', '~'), + KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), + KeyCode::Key1 => modifiers.handle_shift('1', '!'), + KeyCode::Key2 => modifiers.handle_shift('2', '@'), + KeyCode::Key3 => modifiers.handle_shift('3', '#'), + KeyCode::Key4 => modifiers.handle_shift('4', '$'), + KeyCode::Key5 => modifiers.handle_shift('5', '%'), + KeyCode::Key6 => modifiers.handle_shift('6', '^'), + KeyCode::Key7 => modifiers.handle_shift('7', '&'), + KeyCode::Key8 => modifiers.handle_shift('8', '*'), + KeyCode::Key9 => modifiers.handle_shift('9', '('), + KeyCode::Key0 => modifiers.handle_shift('0', ')'), + KeyCode::OemMinus => modifiers.handle_shift('-', '_'), + KeyCode::OemPlus => modifiers.handle_shift('=', '+'), + KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), + // ========= Row 3 (QWERTY) ========= + KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), + KeyCode::Q => modifiers.handle_alpha('Q', handle_ctrl), + KeyCode::W => modifiers.handle_alpha('W', handle_ctrl), + KeyCode::E => modifiers.handle_alpha('E', handle_ctrl), + KeyCode::R => modifiers.handle_alpha('R', handle_ctrl), + KeyCode::T => modifiers.handle_alpha('T', handle_ctrl), + KeyCode::Y => modifiers.handle_alpha('Y', handle_ctrl), + KeyCode::U => modifiers.handle_alpha('U', handle_ctrl), + KeyCode::I => modifiers.handle_alpha('I', handle_ctrl), + KeyCode::O => modifiers.handle_alpha('O', handle_ctrl), + KeyCode::P => modifiers.handle_alpha('P', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_shift('[', '{'), + KeyCode::Oem6 => modifiers.handle_shift(']', '}'), + KeyCode::Oem7 => modifiers.handle_shift(SLS, '|'), + // ========= Row 4 (ASDFG) ========= + KeyCode::A => modifiers.handle_alpha('A', handle_ctrl), + KeyCode::S => modifiers.handle_alpha('S', handle_ctrl), + KeyCode::D => modifiers.handle_alpha('D', handle_ctrl), + KeyCode::F => modifiers.handle_alpha('F', handle_ctrl), + KeyCode::G => modifiers.handle_alpha('G', handle_ctrl), + KeyCode::H => modifiers.handle_alpha('H', handle_ctrl), + KeyCode::J => modifiers.handle_alpha('J', handle_ctrl), + KeyCode::K => modifiers.handle_alpha('K', handle_ctrl), + KeyCode::L => modifiers.handle_alpha('L', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_shift(';', ':'), + KeyCode::Oem3 => modifiers.handle_shift(QUO, '"'), + KeyCode::Return => DecodedKey::Unicode('\u{000A}'), + // ========= Row 5 (ZXCVB) ========= + KeyCode::Z => modifiers.handle_alpha('Z', handle_ctrl), + KeyCode::X => modifiers.handle_alpha('X', handle_ctrl), + KeyCode::C => modifiers.handle_alpha('C', handle_ctrl), + KeyCode::V => modifiers.handle_alpha('V', handle_ctrl), + KeyCode::B => modifiers.handle_alpha('B', handle_ctrl), + KeyCode::N => modifiers.handle_alpha('N', handle_ctrl), + KeyCode::M => modifiers.handle_alpha('M', handle_ctrl), + KeyCode::OemComma => modifiers.handle_shift(',', '<'), + KeyCode::OemPeriod => modifiers.handle_shift('.', '>'), + KeyCode::Oem2 => modifiers.handle_shift('/', '?'), + // ========= Unicode Specials ========= + KeyCode::Spacebar => DecodedKey::Unicode(' '), + KeyCode::Delete => DecodedKey::Unicode('\u{007f}'), + // ========= Numpad ========= + KeyCode::NumpadDivide => DecodedKey::Unicode('/'), + KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), + KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), + KeyCode::Numpad7 => modifiers.handle_numpad('7', KeyCode::Home), + KeyCode::Numpad8 => modifiers.handle_numpad('8', KeyCode::ArrowUp), + KeyCode::Numpad9 => modifiers.handle_numpad('9', KeyCode::PageUp), + KeyCode::NumpadAdd => DecodedKey::Unicode('+'), + KeyCode::Numpad4 => modifiers.handle_numpad('4', KeyCode::ArrowLeft), + KeyCode::Numpad5 => DecodedKey::Unicode('5'), + KeyCode::Numpad6 => modifiers.handle_numpad('6', KeyCode::ArrowRight), + KeyCode::Numpad1 => modifiers.handle_numpad('1', KeyCode::End), + KeyCode::Numpad2 => modifiers.handle_numpad('2', KeyCode::ArrowDown), + KeyCode::Numpad3 => modifiers.handle_numpad('3', KeyCode::PageDown), + KeyCode::Numpad0 => modifiers.handle_numpad('0', KeyCode::Insert), + KeyCode::NumpadPeriod => modifiers.handle_numpad_pair('.', '\u{007f}'), + KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), + // ========= Fallack ========= + k => DecodedKey::RawKey(k), } } } @@ -551,4 +252,99 @@ mod test { assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev)); } } + + #[test] + fn lowercase() { + let modifiers = Modifiers { + capslock: false, + lalt: false, + lctrl: false, + lshift: false, + numlock: false, + ralt: false, + rctrl: false, + rctrl2: false, + rshift: false, + }; + assert_eq!( + modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + DecodedKey::Unicode('a') + ); + } + + #[test] + fn uppercase() { + let modifiers = Modifiers { + capslock: true, + lalt: false, + lctrl: false, + lshift: false, + numlock: false, + ralt: false, + rctrl: false, + rctrl2: false, + rshift: false, + }; + assert_eq!( + modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + DecodedKey::Unicode('A') + ); + } + + #[test] + fn shifted() { + let modifiers = Modifiers { + capslock: false, + lalt: false, + lctrl: false, + lshift: true, + numlock: false, + ralt: false, + rctrl: false, + rctrl2: false, + rshift: false, + }; + assert_eq!( + modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + DecodedKey::Unicode('A') + ); + } + + #[test] + fn shift_caps() { + let modifiers = Modifiers { + capslock: true, + lalt: false, + lctrl: false, + lshift: true, + numlock: false, + ralt: false, + rctrl: false, + rctrl2: false, + rshift: false, + }; + assert_eq!( + modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + DecodedKey::Unicode('a') + ); + } + + #[test] + fn ctrl() { + let modifiers = Modifiers { + capslock: true, + lalt: false, + lctrl: true, + lshift: true, + numlock: false, + ralt: false, + rctrl: false, + rctrl2: false, + rshift: false, + }; + assert_eq!( + modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + DecodedKey::Unicode('\u{0001}') + ); + } } diff --git a/src/lib.rs b/src/lib.rs index f6e55d1..b24968a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -723,6 +723,96 @@ pub struct Modifiers { pub rctrl2: bool, } +impl Modifiers { + /// Handle the standard letters + /// + /// ONLY pass 'A'..='Z' - nothing else + pub(crate) fn handle_alpha(&self, letter: char, handle_control: HandleControl) -> DecodedKey { + debug_assert!(letter.is_ascii_uppercase()); + if handle_control == HandleControl::MapLettersToUnicode && self.is_ctrl() { + // Get a Control code, like Ctrl+C => U+0003 + const ASCII_UPPERCASE_START_OFFSET: u8 = 64; + DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + } else if self.is_caps() { + // Capital letter + DecodedKey::Unicode(letter) + } else { + // Lowercase letter + const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; + DecodedKey::Unicode((letter as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) + } + } + + /// Handle the standard letters, with an Alt-Gr alternative + /// + /// ONLY pass 'A'..='Z' - nothing else + pub(crate) fn handle_alalt( + &self, + letter: char, + alt_letter_lower: char, + alt_letter_upper: char, + handle_control: HandleControl, + ) -> DecodedKey { + debug_assert!(letter.is_ascii_uppercase()); + if handle_control == HandleControl::MapLettersToUnicode && self.is_ctrl() { + // Get a Control code, like Ctrl+C => U+0003 + const ASCII_UPPERCASE_START_OFFSET: u8 = 64; + DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + } else if self.ralt && self.is_caps() { + // Capital letter + DecodedKey::Unicode(alt_letter_upper) + } else if self.ralt { + // Lowercase letter + DecodedKey::Unicode(alt_letter_lower) + } else if self.is_caps() { + // Capital letter + DecodedKey::Unicode(letter) + } else { + // Lowercase letter + const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; + DecodedKey::Unicode((letter as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) + } + } + + /// Handle numpad keys which are either a character or a raw key + pub(crate) fn handle_numpad(&self, letter: char, key: KeyCode) -> DecodedKey { + if self.numlock { + DecodedKey::Unicode(letter) + } else { + DecodedKey::RawKey(key) + } + } + + /// Handle numpad keys which are one of two characters + pub(crate) fn handle_numpad_pair(&self, letter: char, other: char) -> DecodedKey { + if self.numlock { + DecodedKey::Unicode(letter) + } else { + DecodedKey::Unicode(other) + } + } + + /// Handle standard two-glyph shifted keys + pub(crate) fn handle_shift(&self, plain: char, shifted: char) -> DecodedKey { + if self.is_shifted() { + DecodedKey::Unicode(shifted) + } else { + DecodedKey::Unicode(plain) + } + } + + /// Handle standard three-glyph shifted keys + pub(crate) fn handle_altsh(&self, plain: char, shifted: char, alt: char) -> DecodedKey { + if self.is_altgr() { + DecodedKey::Unicode(alt) + } else if self.is_shifted() { + DecodedKey::Unicode(shifted) + } else { + DecodedKey::Unicode(plain) + } + } +} + /// Contains either a Unicode character, or a raw key code. #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum DecodedKey { @@ -766,6 +856,9 @@ const EXTENDED_KEY_CODE: u8 = 0xE0; const EXTENDED2_KEY_CODE: u8 = 0xE1; const KEY_RELEASE_CODE: u8 = 0xF0; +const QUO: char = '\''; +const SLS: char = '\\'; + // **************************************************************************** // // Public Functions and Implementation From 329b71ede5f8bec2dcfe5e361477eb99e600a6a6 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Tue, 3 Jun 2025 23:06:24 +0100 Subject: [PATCH 04/18] Clean up Azerty --- examples/print_keyboard.rs | 2 + src/layouts/azerty.rs | 668 ++++++++++--------------------------- src/layouts/us104.rs | 2 +- 3 files changed, 174 insertions(+), 498 deletions(-) diff --git a/examples/print_keyboard.rs b/examples/print_keyboard.rs index 5ccdb57..a238cb7 100644 --- a/examples/print_keyboard.rs +++ b/examples/print_keyboard.rs @@ -20,6 +20,8 @@ fn main() { show_kb(KeyboardKind::Iso, &pc_keyboard::layouts::Uk105Key); println!("Colemak:"); show_kb(KeyboardKind::Ansi, &pc_keyboard::layouts::Colemak); + println!("Azerty:"); + show_kb(KeyboardKind::Iso, &pc_keyboard::layouts::Azerty); } fn show_kb(kind: KeyboardKind, layout: &dyn KeyboardLayout) { diff --git a/src/layouts/azerty.rs b/src/layouts/azerty.rs index 6924dd3..514d7da 100644 --- a/src/layouts/azerty.rs +++ b/src/layouts/azerty.rs @@ -1,517 +1,191 @@ //! French keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, QUO, SLS}; /// A standard French 102-key (or 105-key including Windows keys) keyboard. /// -/// The top row spells `AZERTY`. -/// -/// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). +/// The top row spells `AZERTY`. Has a 2-row high Enter key, with Oem5 next to +/// the left shift (ISO format). /// /// NB: no "dead key" support for now +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are +/// sometimes Unicode and sometimes not, depending on modifiers. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ a │ z │ e │ r │ t │ y │ u │ i │ o │ p │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ q │ s │ d │ f │ g │ h │ j │ k │ l │ m │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ w │ x │ c │ v │ b │ n │ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ W │ X │ C │ V │ B │ N │ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ² │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ £ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ % │ µ │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ > │ W │ X │ C │ V │ B │ N │ ? │ . │ / │ § │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0001│001a│0005│0012│0014│0019│0015│0009│000f│0010│ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0011│0013│0004│0006│0007│0008│000a│000b│000c│000d│ ù │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │0017│0018│0003│0016│0002│000e│ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ² │ & │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ a │ z │ € │ r │ t │ y │ u │ i │ o │ p │ ^ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ q │ s │ d │ f │ g │ h │ j │ k │ l │ m │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ w │ x │ c │ v │ b │ n │ , │ ; │ : │ ! │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ² │ 1 │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ A │ Z │ € │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ % │ µ │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ > │ W │ X │ C │ V │ B │ N │ ? │ . │ / │ § │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// pub struct Azerty; impl KeyboardLayout for Azerty { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Oem8 => DecodedKey::Unicode('²'), - KeyCode::Oem5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else { - DecodedKey::Unicode('<') - } - } - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('1') - } else { - DecodedKey::Unicode('&') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('2') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('é') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('3') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('#') - } else { - DecodedKey::Unicode('"') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('4') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('\'') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('5') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('[') - } else { - DecodedKey::Unicode('(') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('6') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('7') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('`') - } else { - DecodedKey::Unicode('è') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('8') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('\\') - } else { - DecodedKey::Unicode('_') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('9') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('^') - } else { - DecodedKey::Unicode('ç') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('0') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('@') - } else { - DecodedKey::Unicode('à') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('°') - } else if modifiers.is_altgr() { - DecodedKey::Unicode(']') - } else { - DecodedKey::Unicode(')') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('+') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode('=') - } - } - KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), - KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::Q => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0001}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('A') - } else { - DecodedKey::Unicode('a') - } - } - KeyCode::W => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{001A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Z') - } else { - DecodedKey::Unicode('z') - } - } - KeyCode::E => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::R => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0012}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('R') - } else { - DecodedKey::Unicode('r') - } - } - KeyCode::T => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0014}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('T') - } else { - DecodedKey::Unicode('t') - } - } - KeyCode::Y => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0019}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Y') - } else { - DecodedKey::Unicode('y') - } - } - KeyCode::U => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0015}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('U') - } else { - DecodedKey::Unicode('u') - } - } - KeyCode::I => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0009}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('I') - } else { - DecodedKey::Unicode('i') - } - } - KeyCode::O => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000F}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('O') - } else { - DecodedKey::Unicode('o') - } - } - KeyCode::P => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0010}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('P') - } else { - DecodedKey::Unicode('p') - } - } - KeyCode::Oem4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('¨') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('ˇ') - } else { - DecodedKey::Unicode('^') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('£') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('¤') - } else { - DecodedKey::Unicode('$') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('µ') - } else { - DecodedKey::Unicode('*') - } - } - KeyCode::A => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0011}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Q') - } else { - DecodedKey::Unicode('q') - } - } - KeyCode::S => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0013}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('S') - } else { - DecodedKey::Unicode('s') - } - } - KeyCode::D => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0004}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('D') - } else { - DecodedKey::Unicode('d') - } - } - KeyCode::F => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0006}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('F') - } else { - DecodedKey::Unicode('f') - } - } - KeyCode::G => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0007}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('G') - } else { - DecodedKey::Unicode('g') - } - } - KeyCode::H => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0008}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('H') - } else { - DecodedKey::Unicode('h') - } - } - KeyCode::J => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('J') - } else { - DecodedKey::Unicode('j') - } - } - KeyCode::K => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000B}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('K') - } else { - DecodedKey::Unicode('k') - } - } - KeyCode::L => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000C}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('L') - } else { - DecodedKey::Unicode('l') - } - } - KeyCode::Oem1 => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else { - DecodedKey::Unicode('ù') - } - } - // Enter gives LF, not CRLF or CR - KeyCode::Return => DecodedKey::Unicode('\u{000A}'), - KeyCode::Z => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0017}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('W') - } else { - DecodedKey::Unicode('w') - } - } - KeyCode::X => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0018}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('X') - } else { - DecodedKey::Unicode('x') - } - } - KeyCode::C => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0003}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('C') - } else { - DecodedKey::Unicode('c') - } - } - KeyCode::V => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0016}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('V') - } else { - DecodedKey::Unicode('v') - } - } - KeyCode::B => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0002}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('B') - } else { - DecodedKey::Unicode('b') - } - } - KeyCode::N => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000E}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('N') - } else { - DecodedKey::Unicode('n') - } - } - KeyCode::M => { - if modifiers.is_caps() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::OemComma => { - if modifiers.is_shifted() { - DecodedKey::Unicode('.') - } else { - DecodedKey::Unicode(';') - } - } - KeyCode::OemPeriod => { - if modifiers.is_shifted() { - DecodedKey::Unicode('/') - } else { - DecodedKey::Unicode(':') - } - } - KeyCode::Oem2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('§') - } else { - DecodedKey::Unicode('!') - } - } - KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode('\u{007F}'), - KeyCode::NumpadDivide => DecodedKey::Unicode('/'), - KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), - KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), - KeyCode::Numpad7 => { - if modifiers.numlock { - DecodedKey::Unicode('7') - } else { - DecodedKey::RawKey(KeyCode::Home) - } - } - KeyCode::Numpad8 => { - if modifiers.numlock { - DecodedKey::Unicode('8') - } else { - DecodedKey::RawKey(KeyCode::ArrowUp) - } - } - KeyCode::Numpad9 => { - if modifiers.numlock { - DecodedKey::Unicode('9') - } else { - DecodedKey::RawKey(KeyCode::PageUp) - } - } - KeyCode::NumpadAdd => DecodedKey::Unicode('+'), - KeyCode::Numpad4 => { - if modifiers.numlock { - DecodedKey::Unicode('4') - } else { - DecodedKey::RawKey(KeyCode::ArrowLeft) - } - } - KeyCode::Numpad5 => DecodedKey::Unicode('5'), - KeyCode::Numpad6 => { - if modifiers.numlock { - DecodedKey::Unicode('6') - } else { - DecodedKey::RawKey(KeyCode::ArrowRight) - } - } - KeyCode::Numpad1 => { - if modifiers.numlock { - DecodedKey::Unicode('1') - } else { - DecodedKey::RawKey(KeyCode::End) - } - } - KeyCode::Numpad2 => { - if modifiers.numlock { - DecodedKey::Unicode('2') - } else { - DecodedKey::RawKey(KeyCode::ArrowDown) - } - } - KeyCode::Numpad3 => { - if modifiers.numlock { - DecodedKey::Unicode('3') - } else { - DecodedKey::RawKey(KeyCode::PageDown) - } - } - KeyCode::Numpad0 => { - if modifiers.numlock { - DecodedKey::Unicode('0') - } else { - DecodedKey::RawKey(KeyCode::Insert) - } - } - KeyCode::NumpadPeriod => { - if modifiers.numlock { - DecodedKey::Unicode('.') - } else { - DecodedKey::Unicode('\u{007F}') - } - } - KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), - k => DecodedKey::RawKey(k), + // ========= Row 2 (the numbers) ========= + KeyCode::Oem8 => DecodedKey::Unicode('²'), + KeyCode::Key1 => modifiers.handle_shift('&', '1'), + KeyCode::Key2 => modifiers.handle_altsh('é', '2', '~'), + KeyCode::Key3 => modifiers.handle_altsh('"', '3', '#'), + KeyCode::Key4 => modifiers.handle_altsh(QUO, '4', '{'), + KeyCode::Key5 => modifiers.handle_altsh('(', '5', '['), + KeyCode::Key6 => modifiers.handle_altsh('-', '6', '|'), + KeyCode::Key7 => modifiers.handle_altsh('è', '7', '`'), + KeyCode::Key8 => modifiers.handle_altsh('_', '8', SLS), + KeyCode::Key9 => modifiers.handle_altsh('ç', '9', '^'), + KeyCode::Key0 => modifiers.handle_altsh('à', '0', '@'), + KeyCode::OemMinus => modifiers.handle_altsh(')', '°', ']'), + KeyCode::OemPlus => modifiers.handle_altsh('=', '+', '}'), + + // ========= Row 3 (QWERTY) ========= + KeyCode::Q => modifiers.handle_alpha('A', handle_ctrl), + KeyCode::W => modifiers.handle_alpha('Z', handle_ctrl), + KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_shift('^', '¨'), + KeyCode::Oem6 => modifiers.handle_altsh('$', '£', '¤'), + + // ========= Row 4 (ASDFG) ========= + KeyCode::A => modifiers.handle_alpha('Q', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_alpha('M', handle_ctrl), + KeyCode::Oem3 => modifiers.handle_shift('ù', '%'), + KeyCode::Oem7 => modifiers.handle_shift('*', 'µ'), + + // ========= Row 5 (ZXCVB) ========= + KeyCode::Oem5 => modifiers.handle_shift('<', '>'), + KeyCode::Z => modifiers.handle_alpha('W', handle_ctrl), + KeyCode::M => modifiers.handle_shift(',', '?'), + KeyCode::OemComma => modifiers.handle_shift(';', '.'), + KeyCode::OemPeriod => modifiers.handle_shift(':', '/'), + KeyCode::Oem2 => modifiers.handle_shift('!', '§'), + + // ========= Fallback ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } } diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs index 761c8cc..b985382 100644 --- a/src/layouts/us104.rs +++ b/src/layouts/us104.rs @@ -180,7 +180,7 @@ impl KeyboardLayout for Us104Key { KeyCode::Numpad0 => modifiers.handle_numpad('0', KeyCode::Insert), KeyCode::NumpadPeriod => modifiers.handle_numpad_pair('.', '\u{007f}'), KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), - // ========= Fallack ========= + // ========= Fallback ========= k => DecodedKey::RawKey(k), } } From 9418a6b3b40f6d4daeb73cb2ce261fa4289b2b71 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 4 Jun 2025 21:52:55 +0100 Subject: [PATCH 05/18] Print all keyboard types (except JIS) Now keyboard layouts know their own physical layout. --- examples/print_keyboard.rs | 92 +++++++++++++++++++---------- src/layouts/azerty.rs | 8 ++- src/layouts/colemak.rs | 6 +- src/layouts/de105.rs | 5 +- src/layouts/dvorak104.rs | 6 +- src/layouts/dvorak_programmer104.rs | 6 +- src/layouts/fi_se105.rs | 6 +- src/layouts/jis109.rs | 6 +- src/layouts/mod.rs | 32 ++++++++++ src/layouts/no105.rs | 6 +- src/layouts/uk105.rs | 8 ++- src/layouts/us104.rs | 8 ++- src/lib.rs | 28 ++++++++- 13 files changed, 174 insertions(+), 43 deletions(-) diff --git a/examples/print_keyboard.rs b/examples/print_keyboard.rs index a238cb7..67949d9 100644 --- a/examples/print_keyboard.rs +++ b/examples/print_keyboard.rs @@ -4,27 +4,53 @@ use std::collections::HashMap; use pc_keyboard::{DecodedKey, KeyCode, KeyboardLayout, Modifiers}; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum KeyboardKind { - Ansi, - Iso, -} - fn main() { println!("Keyboard Layouts"); println!("================"); println!(); - println!("Us104Key:"); - show_kb(KeyboardKind::Ansi, &pc_keyboard::layouts::Us104Key); - println!("Uk105Key:"); - show_kb(KeyboardKind::Iso, &pc_keyboard::layouts::Uk105Key); - println!("Colemak:"); - show_kb(KeyboardKind::Ansi, &pc_keyboard::layouts::Colemak); - println!("Azerty:"); - show_kb(KeyboardKind::Iso, &pc_keyboard::layouts::Azerty); + println!("/// ****************************************"); + println!("/// # Azerty"); + println!("///"); + show_kb(&pc_keyboard::layouts::Azerty); + println!("/// ****************************************"); + println!("/// # Colemak"); + println!("///"); + show_kb(&pc_keyboard::layouts::Colemak); + println!("/// ****************************************"); + println!("/// # De105Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::De105Key); + println!("/// ****************************************"); + println!("/// # Dvorak104Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::Dvorak104Key); + println!("/// ****************************************"); + println!("/// # DVP104Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::DVP104Key); + println!("/// ****************************************"); + println!("/// # FiSe105Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::FiSe105Key); + // println!("/// ****************************************"); + // println!("/// # Jis109Key"); + // println!("///"); + // show_kb(&pc_keyboard::layouts::Jis109Key); + println!("/// ****************************************"); + println!("/// # No105Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::No105Key); + println!("/// ****************************************"); + println!("/// # Uk105Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::Uk105Key); + println!("/// ****************************************"); + println!("/// # Us104Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::Us104Key); } -fn show_kb(kind: KeyboardKind, layout: &dyn KeyboardLayout) { +fn show_kb(layout: &dyn KeyboardLayout) { let mut modifiers = Modifiers { lshift: false, rshift: false, @@ -37,37 +63,37 @@ fn show_kb(kind: KeyboardKind, layout: &dyn KeyboardLayout) { rctrl2: false, }; println!("/// ## Unmodified"); - show_kb_modifiers(kind, layout, &modifiers); + show_kb_modifiers(layout, &modifiers); modifiers.capslock = true; println!("/// ## Caps Lock"); - show_kb_modifiers(kind, layout, &modifiers); + show_kb_modifiers(layout, &modifiers); modifiers.capslock = false; modifiers.lshift = true; println!("/// ## Shifted"); - show_kb_modifiers(kind, layout, &modifiers); + show_kb_modifiers(layout, &modifiers); modifiers.lshift = false; modifiers.rctrl = true; println!("/// ## Control"); - show_kb_modifiers(kind, layout, &modifiers); + show_kb_modifiers(layout, &modifiers); modifiers.rctrl = false; modifiers.ralt = true; println!("/// ## AltGr"); - show_kb_modifiers(kind, layout, &modifiers); + show_kb_modifiers(layout, &modifiers); modifiers.ralt = false; modifiers.ralt = true; modifiers.lshift = true; println!("/// ## Shift AltGr"); - show_kb_modifiers(kind, layout, &modifiers); + show_kb_modifiers(layout, &modifiers); modifiers.ralt = false; modifiers.lshift = false; } -fn show_kb_modifiers(kind: KeyboardKind, layout: &dyn KeyboardLayout, modifiers: &Modifiers) { +fn show_kb_modifiers(layout: &dyn KeyboardLayout, modifiers: &Modifiers) { let mut map = Map::new(modifiers); map.insert("esc", KeyCode::Escape, layout); map.insert("oem8", KeyCode::Oem8, layout); @@ -138,11 +164,17 @@ fn show_kb_modifiers(kind: KeyboardKind, layout: &dyn KeyboardLayout, modifiers: map.insert("b", KeyCode::B, layout); map.insert("n", KeyCode::N, layout); map.insert("m", KeyCode::M, layout); - if kind == KeyboardKind::Iso { - map.insert("oem5", KeyCode::Oem5, layout); - map.print_iso(); - } else { - map.print_ansi(); + match layout.get_physical() { + pc_keyboard::PhysicalKeyboard::Iso => { + map.insert("oem5", KeyCode::Oem5, layout); + map.print_iso(); + } + pc_keyboard::PhysicalKeyboard::Ansi => { + map.print_ansi(); + } + pc_keyboard::PhysicalKeyboard::Jis => { + todo!() + } } } @@ -262,7 +294,7 @@ impl Map { /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │{o8}│{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│{bs} │ │ │ │ │ │ │{nd}│{nm}│{ns}│ +/// │{o8}│{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│ {bs} │ │ │ │ │ │ │{nd}│{nm}│{ns}│ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │{tb} │{kq}│{kw}│{ke}│{kr}│{kt}│{ky}│{ku}│{ki}│{ko}│{kp}│{o4}│{o6}│ {o7} │ │{de}│ │ │ │{n7}│{n8}│{n9}│ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤{nl}│ @@ -358,9 +390,9 @@ impl Map { /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │{o8}│{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│{bs} │ │ │ │ │ │ │{nd}│{nm}│{ns}│ +/// │{o8}│{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│ {bs} │ │ │ │ │ │ │{nd}│{nm}│{ns}│ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │{tb} │{kq}│{kw}│{ke}│{kr}│{kt}│{ky}│{ku}│{ki}│{ko}│{kp}│{o4}│{o6}│ {en} │ │{de}│ │ │ │{n7}│{n8}│{n9}│ │ +/// │{tb} │{kq}│{kw}│{ke}│{kr}│{kt}│{ky}│{ku}│{ki}│{ko}│{kp}│{o4}│{o6}│ {en} │ │{de}│ │ │ │{n7}│{n8}│{n9}│ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤{nl}│ /// │ │{ka}│{ks}│{kd}│{kf}│{kg}│{kh}│{kj}│{kk}│{kl}│{o1}│{o3}│{o7}│ │ │{n4}│{n5}│{n6}│ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ diff --git a/src/layouts/azerty.rs b/src/layouts/azerty.rs index 514d7da..7afd8f2 100644 --- a/src/layouts/azerty.rs +++ b/src/layouts/azerty.rs @@ -1,6 +1,8 @@ //! French keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, QUO, SLS}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard French 102-key (or 105-key including Windows keys) keyboard. /// @@ -188,6 +190,10 @@ impl KeyboardLayout for Azerty { e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Iso + } } #[cfg(test)] diff --git a/src/layouts/colemak.rs b/src/layouts/colemak.rs index c2e3854..ce11b98 100644 --- a/src/layouts/colemak.rs +++ b/src/layouts/colemak.rs @@ -1,6 +1,6 @@ //! Colemak keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; /// A Colemak 101-key (or 104-key including Windows keys) keyboard. /// @@ -131,4 +131,8 @@ impl KeyboardLayout for Colemak { e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Ansi + } } diff --git a/src/layouts/de105.rs b/src/layouts/de105.rs index e40fdb1..43bc65e 100644 --- a/src/layouts/de105.rs +++ b/src/layouts/de105.rs @@ -1,6 +1,6 @@ //! German keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO}; /// A standard German 102-key (or 105-key including Windows keys) keyboard. /// @@ -251,4 +251,7 @@ impl KeyboardLayout for De105Key { } } } + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Iso + } } diff --git a/src/layouts/dvorak104.rs b/src/layouts/dvorak104.rs index 58e9c0f..5027083 100644 --- a/src/layouts/dvorak104.rs +++ b/src/layouts/dvorak104.rs @@ -1,6 +1,6 @@ //! Dvorak keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; /// A Dvorak 101-key (or 104-key including Windows keys) keyboard. /// @@ -301,4 +301,8 @@ impl KeyboardLayout for Dvorak104Key { } } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Ansi + } } diff --git a/src/layouts/dvorak_programmer104.rs b/src/layouts/dvorak_programmer104.rs index 3f5efce..defcd16 100644 --- a/src/layouts/dvorak_programmer104.rs +++ b/src/layouts/dvorak_programmer104.rs @@ -1,6 +1,6 @@ //! Dvorak Programmer keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; /// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard. /// @@ -482,4 +482,8 @@ impl KeyboardLayout for DVP104Key { k => DecodedKey::RawKey(k), } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Ansi + } } diff --git a/src/layouts/fi_se105.rs b/src/layouts/fi_se105.rs index a59184e..0c2e3f4 100644 --- a/src/layouts/fi_se105.rs +++ b/src/layouts/fi_se105.rs @@ -1,6 +1,6 @@ //! Finnish/Swedish keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; /// A standard Finnish/Swedish 102-key (or 105-key including Windows keys) keyboard. /// @@ -223,4 +223,8 @@ impl KeyboardLayout for FiSe105Key { e => fallback.map_keycode(e, modifiers, handle_ctrl), } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Iso + } } diff --git a/src/layouts/jis109.rs b/src/layouts/jis109.rs index bb6b921..7533806 100644 --- a/src/layouts/jis109.rs +++ b/src/layouts/jis109.rs @@ -1,6 +1,6 @@ //! JIS keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; /// A standard Japan 106-key (or 109-key including Windows keys) keyboard. /// @@ -175,4 +175,8 @@ impl KeyboardLayout for Jis109Key { } } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Jis + } } diff --git a/src/layouts/mod.rs b/src/layouts/mod.rs index 54bbc34..2369f7b 100644 --- a/src/layouts/mod.rs +++ b/src/layouts/mod.rs @@ -5,6 +5,8 @@ //! see [`Uk105Key`] and [`Us104Key`] as an example of that. mod dvorak_programmer104; +use crate::PhysicalKeyboard; + pub use self::dvorak_programmer104::DVP104Key; mod dvorak104; @@ -68,6 +70,21 @@ impl super::KeyboardLayout for AnyLayout { AnyLayout::FiSe105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), } } + + fn get_physical(&self) -> PhysicalKeyboard { + match self { + AnyLayout::DVP104Key(inner) => inner.get_physical(), + AnyLayout::Dvorak104Key(inner) => inner.get_physical(), + AnyLayout::Us104Key(inner) => inner.get_physical(), + AnyLayout::Uk105Key(inner) => inner.get_physical(), + AnyLayout::Jis109Key(inner) => inner.get_physical(), + AnyLayout::Azerty(inner) => inner.get_physical(), + AnyLayout::Colemak(inner) => inner.get_physical(), + AnyLayout::De105Key(inner) => inner.get_physical(), + AnyLayout::No105Key(inner) => inner.get_physical(), + AnyLayout::FiSe105Key(inner) => inner.get_physical(), + } + } } impl super::KeyboardLayout for &AnyLayout { @@ -90,6 +107,21 @@ impl super::KeyboardLayout for &AnyLayout { AnyLayout::FiSe105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl), } } + + fn get_physical(&self) -> PhysicalKeyboard { + match self { + AnyLayout::DVP104Key(inner) => inner.get_physical(), + AnyLayout::Dvorak104Key(inner) => inner.get_physical(), + AnyLayout::Us104Key(inner) => inner.get_physical(), + AnyLayout::Uk105Key(inner) => inner.get_physical(), + AnyLayout::Jis109Key(inner) => inner.get_physical(), + AnyLayout::Azerty(inner) => inner.get_physical(), + AnyLayout::Colemak(inner) => inner.get_physical(), + AnyLayout::De105Key(inner) => inner.get_physical(), + AnyLayout::No105Key(inner) => inner.get_physical(), + AnyLayout::FiSe105Key(inner) => inner.get_physical(), + } + } } #[cfg(test)] diff --git a/src/layouts/no105.rs b/src/layouts/no105.rs index 0e24fb0..bff15d2 100644 --- a/src/layouts/no105.rs +++ b/src/layouts/no105.rs @@ -1,6 +1,6 @@ //! Norwegian keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; /// A standard Norwegian 102-key (or 105-key including Windows keys) keyboard. /// @@ -229,4 +229,8 @@ impl KeyboardLayout for No105Key { } } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Iso + } } diff --git a/src/layouts/uk105.rs b/src/layouts/uk105.rs index c75cf49..5da1813 100644 --- a/src/layouts/uk105.rs +++ b/src/layouts/uk105.rs @@ -1,6 +1,8 @@ //! United Kingdom keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, QUO, SLS}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard United Kingdom 102-key (or 105-key including Windows keys) keyboard. /// @@ -162,6 +164,10 @@ impl KeyboardLayout for Uk105Key { e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Iso + } } #[cfg(test)] diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs index b985382..02d2d91 100644 --- a/src/layouts/us104.rs +++ b/src/layouts/us104.rs @@ -1,6 +1,8 @@ //! # United States keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, QUO, SLS}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard United States 101-key (or 104-key including Windows keys) keyboard. /// @@ -184,6 +186,10 @@ impl KeyboardLayout for Us104Key { k => DecodedKey::RawKey(k), } } + + fn get_physical(&self) -> PhysicalKeyboard { + PhysicalKeyboard::Ansi + } } #[cfg(test)] diff --git a/src/lib.rs b/src/lib.rs index b24968a..9249891 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ //! come from one of three supported keyboards: 102/105 key ISO, 101/104 key //! ANSI and 106/109-key JIS. //! -//! ### 102/105 key ISO +//! ### 102/105 key [ISO](PhysicalKeyboard::Iso) //! //! This is the mapping of `KeyCode` to a 102/105-key ISO keyboard: //! @@ -86,7 +86,7 @@ //! //! (Reference: ) //! -//! ### 101/104 key ANSI +//! ### 101/104 key [ANSI](PhysicalKeyboard::Ansi) //! //! This is the mapping of `KeyCode` to a 101/104-key ANSI keyboard: //! @@ -114,7 +114,7 @@ //! //! (Reference: ) //! -//! ### 106/109 key JIS +//! ### 106/109 key [JIS](PhysicalKeyboard::Jis) //! //! This is the mapping of `KeyCode` to a 106/109-key JIS keyboard: //! @@ -676,6 +676,16 @@ pub struct KeyEvent { pub state: KeyState, } +/// Describes a physical keyboard +pub enum PhysicalKeyboard { + /// 102 or 105 key ISO, as used by UK English keyboards (and others) + Iso, + /// 101 or 104 key ANSI, as used by US English keyboards (and others) + Ansi, + /// 106 or 109 key JIS, as used by Japanese keyboards (and others) + Jis, +} + /// Describes a Keyboard Layout. /// /// Layouts might include "en_US", or "en_GB", or "de_GR". @@ -690,6 +700,9 @@ pub trait KeyboardLayout { modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey; + + /// Which physical keyboard does this layout work on? + fn get_physical(&self) -> PhysicalKeyboard; } /// A mechanism to convert bytes from a Keyboard into [`KeyCode`] values. @@ -774,6 +787,15 @@ impl Modifiers { } } + /// Handle accented letters + pub(crate) fn handle_accen(&self, lower: char, upper: char) -> DecodedKey { + if self.is_caps() { + DecodedKey::Unicode(upper) + } else { + DecodedKey::Unicode(lower) + } + } + /// Handle numpad keys which are either a character or a raw key pub(crate) fn handle_numpad(&self, letter: char, key: KeyCode) -> DecodedKey { if self.numlock { From f37e52d7a782d9aa695492cc6ca2c599d6be52d7 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 4 Jun 2025 21:53:26 +0100 Subject: [PATCH 06/18] Update De105Key --- src/layouts/de105.rs | 268 ++++++------------------------------------- 1 file changed, 35 insertions(+), 233 deletions(-) diff --git a/src/layouts/de105.rs b/src/layouts/de105.rs index 43bc65e..c6e9ed4 100644 --- a/src/layouts/de105.rs +++ b/src/layouts/de105.rs @@ -1,6 +1,8 @@ //! German keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard German 102-key (or 105-key including Windows keys) keyboard. /// @@ -10,247 +12,47 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi pub struct De105Key; impl KeyboardLayout for De105Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Oem8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('°') - } else { - DecodedKey::Unicode('^') - } - } - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('!') - } else { - DecodedKey::Unicode('1') - } - } - KeyCode::Key2 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('²') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Key3 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('³') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('§') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else { - DecodedKey::Unicode('5') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('&') - } else { - DecodedKey::Unicode('6') - } - } - KeyCode::Key7 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('{') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('/') - } else { - DecodedKey::Unicode('7') - } - } - KeyCode::Key8 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('[') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('(') - } else { - DecodedKey::Unicode('8') - } - } - KeyCode::Key9 => { - if modifiers.is_altgr() { - DecodedKey::Unicode(']') - } else if modifiers.is_shifted() { - DecodedKey::Unicode(')') - } else { - DecodedKey::Unicode('9') - } - } - KeyCode::Key0 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('}') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('=') - } else { - DecodedKey::Unicode('0') - } - } - KeyCode::OemMinus => { - if modifiers.is_altgr() { - DecodedKey::Unicode('\\') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode('ß') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('`') - } else { - DecodedKey::Unicode('´') - } - } - KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), - KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::Q => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0011}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('@') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Q') - } else { - DecodedKey::Unicode('q') - } - } - KeyCode::E => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('€') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::Y => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{001A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Z') - } else { - DecodedKey::Unicode('z') - } - } - KeyCode::Oem4 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Ü') - } else { - DecodedKey::Unicode('ü') - } - } - KeyCode::Oem6 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('~') - } else if modifiers.is_caps() { - DecodedKey::Unicode('*') - } else { - DecodedKey::Unicode('+') - } - } - KeyCode::Return => DecodedKey::Unicode('\u{000A}'), - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('\'') - } else { - DecodedKey::Unicode('#') - } - } - KeyCode::Oem1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('Ö') - } else { - DecodedKey::Unicode('ö') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('Ä') - } else { - DecodedKey::Unicode('ä') - } - } - KeyCode::Z => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0019}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Y') - } else { - DecodedKey::Unicode('y') - } - } - KeyCode::M => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('µ') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::OemComma => { - if modifiers.is_shifted() { - DecodedKey::Unicode(';') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::OemPeriod => { - if modifiers.is_shifted() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::Oem2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::Oem5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('<') - } - } - e => { - let us = super::Us104Key; - us.map_keycode(e, modifiers, handle_ctrl) - } + // ========= Row 2 (the numbers) ========= + KeyCode::Oem8 => modifiers.handle_shift('^', '°'), + KeyCode::Key2 => modifiers.handle_altsh('2', '"', '²'), + KeyCode::Key3 => modifiers.handle_altsh('3', '§', '³'), + KeyCode::Key6 => modifiers.handle_shift('6', '&'), + KeyCode::Key7 => modifiers.handle_altsh('7', '/', '{'), + KeyCode::Key8 => modifiers.handle_altsh('8', '(', '['), + KeyCode::Key9 => modifiers.handle_altsh('9', ')', ']'), + KeyCode::Key0 => modifiers.handle_altsh('0', '=', '}'), + KeyCode::OemMinus => modifiers.handle_altsh('ß', '?', SLS), + KeyCode::OemPlus => modifiers.handle_shift('´', '`'), + // ========= Row 3 (QWERTY) ========= + KeyCode::Q => modifiers.handle_alalt('Q', '@', '@', handle_ctrl), + KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), + KeyCode::Y => modifiers.handle_alpha('Z', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_accen('ü', 'Ü'), + KeyCode::Oem6 => modifiers.handle_altsh('+', '*', '~'), + // ========= Row 4 (ASDFG) ========= + KeyCode::Oem1 => modifiers.handle_accen('ö', 'Ö'), + KeyCode::Oem3 => modifiers.handle_accen('ä', 'Ä'), + KeyCode::Oem7 => modifiers.handle_shift('#', QUO), + // ========= Row 5 (ZXCVB) ========= + KeyCode::Oem5 => modifiers.handle_altsh('<', '>', '|'), + KeyCode::Z => modifiers.handle_alpha('Y', handle_ctrl), + KeyCode::M => modifiers.handle_alalt('M', 'µ', 'µ', handle_ctrl), + KeyCode::OemComma => modifiers.handle_shift(',', ';'), + KeyCode::OemPeriod => modifiers.handle_shift('.', ':'), + KeyCode::Oem2 => modifiers.handle_shift('-', '_'), + // ========= Fallback ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } + fn get_physical(&self) -> PhysicalKeyboard { PhysicalKeyboard::Iso } From bb5035753d1508dc1a28fb7e40d097f6a4443586 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 4 Jun 2025 22:09:33 +0100 Subject: [PATCH 07/18] Update Dvorak and Programmer's Dvorak --- src/layouts/dvorak104.rs | 326 +++-------------- src/layouts/dvorak_programmer104.rs | 523 +++------------------------- 2 files changed, 98 insertions(+), 751 deletions(-) diff --git a/src/layouts/dvorak104.rs b/src/layouts/dvorak104.rs index 5027083..3464c93 100644 --- a/src/layouts/dvorak104.rs +++ b/src/layouts/dvorak104.rs @@ -1,6 +1,6 @@ //! Dvorak keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; +use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO}; /// A Dvorak 101-key (or 104-key including Windows keys) keyboard. /// @@ -8,297 +8,53 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi pub struct Dvorak104Key; impl KeyboardLayout for Dvorak104Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('[') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode(']') - } - } - KeyCode::Q => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('\'') - } - } - KeyCode::W => { - if modifiers.is_shifted() { - DecodedKey::Unicode('<') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::E => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::R => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0010}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('P') - } else { - DecodedKey::Unicode('p') - } - } - KeyCode::T => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0019}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Y') - } else { - DecodedKey::Unicode('y') - } - } - KeyCode::Y => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0006}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('F') - } else { - DecodedKey::Unicode('f') - } - } - KeyCode::U => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0007}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('G') - } else { - DecodedKey::Unicode('g') - } - } - KeyCode::I => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0003}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('C') - } else { - DecodedKey::Unicode('c') - } - } - KeyCode::O => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0012}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('R') - } else { - DecodedKey::Unicode('r') - } - } - KeyCode::P => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000C}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('L') - } else { - DecodedKey::Unicode('l') - } - } - KeyCode::Oem4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode('/') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('+') - } else { - DecodedKey::Unicode('=') - } - } - KeyCode::S => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000F}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('O') - } else { - DecodedKey::Unicode('o') - } - } - KeyCode::D => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::F => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0015}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('U') - } else { - DecodedKey::Unicode('u') - } - } - KeyCode::G => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0009}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('I') - } else { - DecodedKey::Unicode('i') - } - } - KeyCode::H => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0004}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('D') - } else { - DecodedKey::Unicode('d') - } - } - KeyCode::J => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0008}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('H') - } else { - DecodedKey::Unicode('h') - } - } - KeyCode::K => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0014}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('T') - } else { - DecodedKey::Unicode('t') - } - } - KeyCode::L => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000E}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('N') - } else { - DecodedKey::Unicode('n') - } - } - KeyCode::Oem1 => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0013}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('S') - } else { - DecodedKey::Unicode('s') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::Z => { - if modifiers.is_shifted() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode(';') - } - } - KeyCode::X => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0011}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Q') - } else { - DecodedKey::Unicode('q') - } - } - KeyCode::C => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('J') - } else { - DecodedKey::Unicode('j') - } - } - KeyCode::V => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000B}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('K') - } else { - DecodedKey::Unicode('k') - } - } - KeyCode::B => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0018}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('X') - } else { - DecodedKey::Unicode('x') - } - } - KeyCode::N => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0002}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('B') - } else { - DecodedKey::Unicode('b') - } - } - KeyCode::OemComma => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0017}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('W') - } else { - DecodedKey::Unicode('w') - } - } - KeyCode::OemPeriod => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0016}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('V') - } else { - DecodedKey::Unicode('v') - } - } - KeyCode::Oem2 => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{001A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Z') - } else { - DecodedKey::Unicode('z') - } - } - e => { - let us = super::Us104Key; - us.map_keycode(e, modifiers, handle_ctrl) - } + // ========= Row 2 (the numbers) ========= + KeyCode::OemMinus => modifiers.handle_shift('[', '{'), + KeyCode::OemPlus => modifiers.handle_shift(']', '}'), + // ========= Row 3 (QWERTY) ========= + KeyCode::Q => modifiers.handle_shift(QUO, '"'), + KeyCode::W => modifiers.handle_shift(',', '<'), + KeyCode::E => modifiers.handle_shift('.', '>'), + KeyCode::R => modifiers.handle_alpha('P', handle_ctrl), + KeyCode::T => modifiers.handle_alpha('Y', handle_ctrl), + KeyCode::Y => modifiers.handle_alpha('F', handle_ctrl), + KeyCode::U => modifiers.handle_alpha('G', handle_ctrl), + KeyCode::I => modifiers.handle_alpha('C', handle_ctrl), + KeyCode::O => modifiers.handle_alpha('R', handle_ctrl), + KeyCode::P => modifiers.handle_alpha('L', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_shift('/', '?'), + KeyCode::Oem6 => modifiers.handle_shift('=', '+'), + // ========= Row 4 (ASDFG) ========= + KeyCode::S => modifiers.handle_alpha('O', handle_ctrl), + KeyCode::D => modifiers.handle_alpha('E', handle_ctrl), + KeyCode::F => modifiers.handle_alpha('U', handle_ctrl), + KeyCode::G => modifiers.handle_alpha('I', handle_ctrl), + KeyCode::H => modifiers.handle_alpha('D', handle_ctrl), + KeyCode::J => modifiers.handle_alpha('H', handle_ctrl), + KeyCode::K => modifiers.handle_alpha('T', handle_ctrl), + KeyCode::L => modifiers.handle_alpha('N', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_alpha('S', handle_ctrl), + KeyCode::Oem3 => modifiers.handle_shift('-', '_'), + // ========= Row 5 (ZXCVB) ========= + KeyCode::Z => modifiers.handle_shift(';', ':'), + KeyCode::X => modifiers.handle_alpha('Q', handle_ctrl), + KeyCode::C => modifiers.handle_alpha('J', handle_ctrl), + KeyCode::V => modifiers.handle_alpha('K', handle_ctrl), + KeyCode::B => modifiers.handle_alpha('X', handle_ctrl), + KeyCode::N => modifiers.handle_alpha('B', handle_ctrl), + KeyCode::OemComma => modifiers.handle_alpha('W', handle_ctrl), + KeyCode::OemPeriod => modifiers.handle_alpha('V', handle_ctrl), + KeyCode::Oem2 => modifiers.handle_alpha('Z', handle_ctrl), + // ========= Fallback ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } diff --git a/src/layouts/dvorak_programmer104.rs b/src/layouts/dvorak_programmer104.rs index defcd16..32ba412 100644 --- a/src/layouts/dvorak_programmer104.rs +++ b/src/layouts/dvorak_programmer104.rs @@ -1,6 +1,8 @@ //! Dvorak Programmer keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard. /// @@ -8,478 +10,67 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi pub struct DVP104Key; impl KeyboardLayout for DVP104Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Oem8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('$') - } - } - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else { - DecodedKey::Unicode('&') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('7') - } else { - DecodedKey::Unicode('[') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('5') - } else { - DecodedKey::Unicode('{') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('3') - } else { - DecodedKey::Unicode('}') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('1') - } else { - DecodedKey::Unicode('(') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('9') - } else { - DecodedKey::Unicode('=') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('0') - } else { - DecodedKey::Unicode('*') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('2') - } else { - DecodedKey::Unicode(')') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('4') - } else { - DecodedKey::Unicode('+') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('6') - } else { - DecodedKey::Unicode(']') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('8') - } else { - DecodedKey::Unicode('!') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('`') - } else { - DecodedKey::Unicode('=') - } - } - KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), - KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::Q => { - if modifiers.is_shifted() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode(';') - } - } - KeyCode::W => { - if modifiers.is_shifted() { - DecodedKey::Unicode('<') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::E => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::R => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0010}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('P') - } else { - DecodedKey::Unicode('p') - } - } - KeyCode::T => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0019}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Y') - } else { - DecodedKey::Unicode('y') - } - } - KeyCode::Y => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0006}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('F') - } else { - DecodedKey::Unicode('f') - } - } - KeyCode::U => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0007}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('G') - } else { - DecodedKey::Unicode('g') - } - } - KeyCode::I => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0003}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('C') - } else { - DecodedKey::Unicode('c') - } - } - KeyCode::O => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0012}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('R') - } else { - DecodedKey::Unicode('r') - } - } - KeyCode::P => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000C}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('L') - } else { - DecodedKey::Unicode('l') - } - } - KeyCode::Oem4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode('/') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('^') - } else { - DecodedKey::Unicode('@') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('\\') - } - } - KeyCode::A => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0001}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('A') - } else { - DecodedKey::Unicode('a') - } - } - KeyCode::S => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000F}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('O') - } else { - DecodedKey::Unicode('o') - } - } - KeyCode::D => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::F => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0015}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('U') - } else { - DecodedKey::Unicode('u') - } - } - KeyCode::G => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0009}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('I') - } else { - DecodedKey::Unicode('i') - } - } - KeyCode::H => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0004}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('D') - } else { - DecodedKey::Unicode('d') - } - } - KeyCode::J => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0008}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('H') - } else { - DecodedKey::Unicode('h') - } - } - KeyCode::K => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0014}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('T') - } else { - DecodedKey::Unicode('t') - } - } - KeyCode::L => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000E}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('N') - } else { - DecodedKey::Unicode('n') - } - } - KeyCode::Oem1 => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0013}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('S') - } else { - DecodedKey::Unicode('s') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::Return => DecodedKey::Unicode('\u{000A}'), - KeyCode::Z => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('\'') - } - } - KeyCode::X => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0011}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Q') - } else { - DecodedKey::Unicode('q') - } - } - KeyCode::C => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('J') - } else { - DecodedKey::Unicode('j') - } - } - KeyCode::V => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000B}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('K') - } else { - DecodedKey::Unicode('k') - } - } - KeyCode::B => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0018}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('X') - } else { - DecodedKey::Unicode('x') - } - } - KeyCode::N => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0002}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('B') - } else { - DecodedKey::Unicode('b') - } - } - KeyCode::M => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::OemComma => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0017}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('W') - } else { - DecodedKey::Unicode('w') - } - } - KeyCode::OemPeriod => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0016}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('V') - } else { - DecodedKey::Unicode('v') - } - } - KeyCode::Oem2 => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{001A}') - } else if modifiers.is_caps() { - DecodedKey::Unicode('Z') - } else { - DecodedKey::Unicode('z') - } - } - KeyCode::Spacebar => DecodedKey::Unicode(' '), - KeyCode::Delete => DecodedKey::Unicode('\u{007F}'), - KeyCode::NumpadDivide => DecodedKey::Unicode('/'), - KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), - KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), - KeyCode::Numpad7 => { - if modifiers.numlock { - DecodedKey::Unicode('7') - } else { - DecodedKey::RawKey(KeyCode::Home) - } - } - KeyCode::Numpad8 => { - if modifiers.numlock { - DecodedKey::Unicode('8') - } else { - DecodedKey::RawKey(KeyCode::ArrowUp) - } - } - KeyCode::Numpad9 => { - if modifiers.numlock { - DecodedKey::Unicode('9') - } else { - DecodedKey::RawKey(KeyCode::PageUp) - } - } - KeyCode::NumpadAdd => DecodedKey::Unicode('+'), - KeyCode::Numpad4 => { - if modifiers.numlock { - DecodedKey::Unicode('4') - } else { - DecodedKey::RawKey(KeyCode::ArrowLeft) - } - } - KeyCode::Numpad5 => DecodedKey::Unicode('5'), - KeyCode::Numpad6 => { - if modifiers.numlock { - DecodedKey::Unicode('6') - } else { - DecodedKey::RawKey(KeyCode::ArrowRight) - } - } - KeyCode::Numpad1 => { - if modifiers.numlock { - DecodedKey::Unicode('1') - } else { - DecodedKey::RawKey(KeyCode::End) - } - } - KeyCode::Numpad2 => { - if modifiers.numlock { - DecodedKey::Unicode('2') - } else { - DecodedKey::RawKey(KeyCode::ArrowDown) - } - } - KeyCode::Numpad3 => { - if modifiers.numlock { - DecodedKey::Unicode('3') - } else { - DecodedKey::RawKey(KeyCode::PageDown) - } - } - KeyCode::Numpad0 => { - if modifiers.numlock { - DecodedKey::Unicode('0') - } else { - DecodedKey::RawKey(KeyCode::Insert) - } - } - KeyCode::NumpadPeriod => { - if modifiers.numlock { - DecodedKey::Unicode('.') - } else { - DecodedKey::Unicode('\u{007F}') - } - } - KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), - k => DecodedKey::RawKey(k), + // ========= Row 2 (the numbers) ========= + KeyCode::Oem8 => modifiers.handle_shift('$', '~'), + KeyCode::Key1 => modifiers.handle_shift('&', '%'), + KeyCode::Key2 => modifiers.handle_shift('[', '7'), + KeyCode::Key3 => modifiers.handle_shift('{', '5'), + KeyCode::Key4 => modifiers.handle_shift('}', '3'), + KeyCode::Key5 => modifiers.handle_shift('(', '1'), + KeyCode::Key6 => modifiers.handle_shift('=', '9'), + KeyCode::Key7 => modifiers.handle_shift('*', '0'), + KeyCode::Key8 => modifiers.handle_shift(')', '2'), + KeyCode::Key9 => modifiers.handle_shift('+', '4'), + KeyCode::Key0 => modifiers.handle_shift(']', '6'), + KeyCode::OemMinus => modifiers.handle_shift('!', '8'), + KeyCode::OemPlus => modifiers.handle_shift('=', '`'), + // ========= Row 3 (QWERTY) ========= + KeyCode::Q => modifiers.handle_shift(';', ':'), + KeyCode::W => modifiers.handle_shift(',', '<'), + KeyCode::E => modifiers.handle_shift('.', '>'), + KeyCode::R => modifiers.handle_alpha('P', handle_ctrl), + KeyCode::T => modifiers.handle_alpha('Y', handle_ctrl), + KeyCode::Y => modifiers.handle_alpha('F', handle_ctrl), + KeyCode::U => modifiers.handle_alpha('G', handle_ctrl), + KeyCode::I => modifiers.handle_alpha('C', handle_ctrl), + KeyCode::O => modifiers.handle_alpha('R', handle_ctrl), + KeyCode::P => modifiers.handle_alpha('L', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_shift('/', '?'), + KeyCode::Oem6 => modifiers.handle_shift('@', '^'), + KeyCode::Oem7 => modifiers.handle_shift(SLS, '|'), + // ========= Row 4 (ASDFG) ========= + KeyCode::A => modifiers.handle_alpha('A', handle_ctrl), + KeyCode::S => modifiers.handle_alpha('O', handle_ctrl), + KeyCode::D => modifiers.handle_alpha('E', handle_ctrl), + KeyCode::F => modifiers.handle_alpha('U', handle_ctrl), + KeyCode::G => modifiers.handle_alpha('I', handle_ctrl), + KeyCode::H => modifiers.handle_alpha('D', handle_ctrl), + KeyCode::J => modifiers.handle_alpha('H', handle_ctrl), + KeyCode::K => modifiers.handle_alpha('T', handle_ctrl), + KeyCode::L => modifiers.handle_alpha('N', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_alpha('S', handle_ctrl), + KeyCode::Oem3 => modifiers.handle_shift('-', '_'), + // ========= Row 5 (ZXCVB) ========= + KeyCode::Z => modifiers.handle_shift(QUO, '"'), + KeyCode::X => modifiers.handle_alpha('Q', handle_ctrl), + KeyCode::C => modifiers.handle_alpha('J', handle_ctrl), + KeyCode::V => modifiers.handle_alpha('K', handle_ctrl), + KeyCode::B => modifiers.handle_alpha('X', handle_ctrl), + KeyCode::N => modifiers.handle_alpha('B', handle_ctrl), + KeyCode::M => modifiers.handle_alpha('M', handle_ctrl), + KeyCode::OemComma => modifiers.handle_alpha('W', handle_ctrl), + KeyCode::OemPeriod => modifiers.handle_alpha('V', handle_ctrl), + KeyCode::Oem2 => modifiers.handle_alpha('Z', handle_ctrl), + // ========= Fallback ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } From f99aed8f3561f4819d9f6171cfb90e657ff4321e Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 4 Jun 2025 22:22:12 +0100 Subject: [PATCH 08/18] Update FiSe105 --- src/layouts/fi_se105.rs | 231 +++++----------------------------------- 1 file changed, 29 insertions(+), 202 deletions(-) diff --git a/src/layouts/fi_se105.rs b/src/layouts/fi_se105.rs index 0c2e3f4..f8120e3 100644 --- a/src/layouts/fi_se105.rs +++ b/src/layouts/fi_se105.rs @@ -1,6 +1,8 @@ //! Finnish/Swedish keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard Finnish/Swedish 102-key (or 105-key including Windows keys) keyboard. /// @@ -8,219 +10,44 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi pub struct FiSe105Key; impl KeyboardLayout for FiSe105Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; - let fallback = super::Us104Key; match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::Oem8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('½') - } else { - DecodedKey::Unicode('§') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('@') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('#') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('£') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('¤') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('€') - } else { - DecodedKey::Unicode('5') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('&') - } else { - DecodedKey::Unicode('6') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('/') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('7') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('(') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('[') - } else { - DecodedKey::Unicode('8') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode(')') - } else if modifiers.is_altgr() { - DecodedKey::Unicode(']') - } else { - DecodedKey::Unicode('9') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('=') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode('0') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('\\') - } else { - DecodedKey::Unicode('+') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('`') - } else { - DecodedKey::Unicode('´') - } - } + KeyCode::Oem8 => modifiers.handle_shift('§', '½'), + KeyCode::Key2 => modifiers.handle_altsh('2', '"', '@'), + KeyCode::Key3 => modifiers.handle_altsh('3', '#', '£'), + KeyCode::Key4 => modifiers.handle_altsh('4', '¤', '$'), + KeyCode::Key5 => modifiers.handle_altsh('5', '%', '€'), + KeyCode::Key6 => modifiers.handle_shift('6', '&'), + KeyCode::Key7 => modifiers.handle_altsh('7', '/', '{'), + KeyCode::Key8 => modifiers.handle_altsh('8', '(', '['), + KeyCode::Key9 => modifiers.handle_altsh('9', ')', ']'), + KeyCode::Key0 => modifiers.handle_altsh('0', '=', '}'), + KeyCode::OemMinus => modifiers.handle_altsh('+', '?', SLS), + KeyCode::OemPlus => modifiers.handle_shift('´', '`'), // ========= Row 3 (QWERTY) ========= - KeyCode::E => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('€') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::Oem4 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Å') - } else { - DecodedKey::Unicode('å') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('^') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('¨') - } - } + KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_accen('å', 'Å'), + KeyCode::Oem6 => modifiers.handle_altsh('¨', '^', '~'), // ========= Row 4 (ASDF) ========= - KeyCode::Oem1 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Ö') - } else { - DecodedKey::Unicode('ö') - } - } - KeyCode::Oem3 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Ä') - } else { - DecodedKey::Unicode('ä') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('*') - } else { - DecodedKey::Unicode('\'') - } - } + KeyCode::Oem1 => modifiers.handle_accen('ö', 'Ö'), + KeyCode::Oem3 => modifiers.handle_accen('ä', 'Ä'), + KeyCode::Oem7 => modifiers.handle_shift(QUO, '*'), // ========= Row 5 (ZXCV) ========= - KeyCode::Oem5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('<') - } - } - KeyCode::M => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('µ') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::OemComma => { - if modifiers.is_shifted() { - DecodedKey::Unicode(';') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::OemPeriod => { - if modifiers.is_shifted() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::Oem2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } + KeyCode::Oem5 => modifiers.handle_altsh('<', '>', '|'), + KeyCode::M => modifiers.handle_alalt('M', 'µ', 'µ', handle_ctrl), + KeyCode::OemComma => modifiers.handle_shift(',', ';'), + KeyCode::OemPeriod => modifiers.handle_shift('.', ':'), + KeyCode::Oem2 => modifiers.handle_shift('-', '_'), // ========= Row 6 (modifers and space bar) ========= - KeyCode::NumpadPeriod => { - if modifiers.numlock { - DecodedKey::Unicode(',') - } else { - fallback.map_keycode(keycode, modifiers, handle_ctrl) - } - } - e => fallback.map_keycode(e, modifiers, handle_ctrl), + KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } From 4a06354bd7368fd442f6047ba97a90978f1ec4a3 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 4 Jun 2025 22:37:57 +0100 Subject: [PATCH 09/18] Update No105 --- src/layouts/no105.rs | 247 ++++++------------------------------------- 1 file changed, 34 insertions(+), 213 deletions(-) diff --git a/src/layouts/no105.rs b/src/layouts/no105.rs index bff15d2..8742374 100644 --- a/src/layouts/no105.rs +++ b/src/layouts/no105.rs @@ -1,6 +1,8 @@ //! Norwegian keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard Norwegian 102-key (or 105-key including Windows keys) keyboard. /// @@ -8,225 +10,44 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi pub struct No105Key; impl KeyboardLayout for No105Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, modifiers: &Modifiers, handle_ctrl: HandleControl, ) -> DecodedKey { - let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode; match keycode { - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Oem8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('§') - } else { - DecodedKey::Unicode('|') - } - } - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('!') - } else { - DecodedKey::Unicode('1') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('@') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('#') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('£') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('¤') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('€') - } else { - DecodedKey::Unicode('5') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('&') - } else { - DecodedKey::Unicode('6') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('/') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('7') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('(') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('[') - } else { - DecodedKey::Unicode('8') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode(')') - } else if modifiers.is_altgr() { - DecodedKey::Unicode(']') - } else { - DecodedKey::Unicode('9') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('=') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode('0') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('?') - } else { - DecodedKey::Unicode('+') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('`') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('´') - } else { - DecodedKey::Unicode('\\') - } - } - KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), - KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::E => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{0005}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('€') - } else if modifiers.is_caps() { - DecodedKey::Unicode('E') - } else { - DecodedKey::Unicode('e') - } - } - KeyCode::Oem4 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Å') - } else { - DecodedKey::Unicode('å') - } - } - KeyCode::Oem6 => { - if modifiers.is_altgr() { - DecodedKey::Unicode('~') - } else if modifiers.is_shifted() { - DecodedKey::Unicode('^') - } else { - DecodedKey::Unicode('¨') - } - } - KeyCode::Return => DecodedKey::Unicode('\u{000A}'), - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('*') - } else { - DecodedKey::Unicode('\'') - } - } - KeyCode::Oem1 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Ø') - } else { - DecodedKey::Unicode('ø') - } - } - KeyCode::Oem3 => { - if modifiers.is_caps() { - DecodedKey::Unicode('Æ') - } else { - DecodedKey::Unicode('æ') - } - } - KeyCode::M => { - if map_to_unicode && modifiers.is_ctrl() { - DecodedKey::Unicode('\u{000D}') - } else if modifiers.is_altgr() { - DecodedKey::Unicode('µ') - } else if modifiers.is_caps() { - DecodedKey::Unicode('M') - } else { - DecodedKey::Unicode('m') - } - } - KeyCode::OemComma => { - if modifiers.is_shifted() { - DecodedKey::Unicode(';') - } else { - DecodedKey::Unicode(',') - } - } - KeyCode::OemPeriod => { - if modifiers.is_shifted() { - DecodedKey::Unicode(':') - } else { - DecodedKey::Unicode('.') - } - } - KeyCode::Oem2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::Oem5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('>') - } else { - DecodedKey::Unicode('<') - } - } - KeyCode::NumpadPeriod => { - if modifiers.numlock { - DecodedKey::Unicode(',') - } else { - DecodedKey::Unicode('\u{007F}') - } - } - e => { - let us = super::Us104Key; - us.map_keycode(e, modifiers, handle_ctrl) - } + // ========= Row 2 (the numbers) ========= + KeyCode::Oem8 => modifiers.handle_shift('|', '§'), + KeyCode::Key2 => modifiers.handle_altsh('2', '"', '@'), + KeyCode::Key3 => modifiers.handle_altsh('3', '#', '£'), + KeyCode::Key4 => modifiers.handle_altsh('4', '¤', '$'), + KeyCode::Key5 => modifiers.handle_shift('5', '%'), + KeyCode::Key6 => modifiers.handle_shift('6', '&'), + KeyCode::Key7 => modifiers.handle_altsh('7', '/', '{'), + KeyCode::Key8 => modifiers.handle_altsh('8', '(', '['), + KeyCode::Key9 => modifiers.handle_altsh('9', ')', ']'), + KeyCode::Key0 => modifiers.handle_altsh('0', '=', '}'), + KeyCode::OemMinus => modifiers.handle_shift('+', '?'), + KeyCode::OemPlus => modifiers.handle_altsh(SLS, '`', '´'), + // ========= Row 3 (QWERTY) ========= + KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_accen('å', 'Å'), + KeyCode::Oem6 => modifiers.handle_altsh('¨', '^', '~'), + // ========= Row 4 (ASDF) ========= + KeyCode::Oem7 => modifiers.handle_shift(QUO, '*'), + KeyCode::Oem1 => modifiers.handle_accen('ø', 'Ø'), + KeyCode::Oem3 => modifiers.handle_accen('æ', 'Æ'), + // ========= Row 5 (ZXCV) ========= + KeyCode::Oem5 => modifiers.handle_shift('<', '>'), + KeyCode::M => modifiers.handle_alalt('M', 'µ', 'µ', handle_ctrl), + KeyCode::OemComma => modifiers.handle_shift(',', ';'), + KeyCode::OemPeriod => modifiers.handle_shift('.', ':'), + KeyCode::Oem2 => modifiers.handle_shift('-', '_'), + KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), + // ========= Row 6 (modifers and space bar) ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } From 02f9296099d09b2207d8fd68e80ca2c79ee728cf Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 5 Jun 2025 20:00:46 +0100 Subject: [PATCH 10/18] Add missing diagrams. Also clean up description text - we now longer show raw keys. --- src/layouts/azerty.rs | 28 +++--- src/layouts/colemak.rs | 50 +++++++++-- src/layouts/de105.rs | 127 ++++++++++++++++++++++++++++ src/layouts/dvorak104.rs | 127 ++++++++++++++++++++++++++++ src/layouts/dvorak_programmer104.rs | 127 ++++++++++++++++++++++++++++ src/layouts/fi_se105.rs | 127 ++++++++++++++++++++++++++++ src/layouts/no105.rs | 127 ++++++++++++++++++++++++++++ src/layouts/uk105.rs | 28 +++--- src/layouts/us104.rs | 66 ++++++++++++--- src/lib.rs | 11 ++- 10 files changed, 765 insertions(+), 53 deletions(-) diff --git a/src/layouts/azerty.rs b/src/layouts/azerty.rs index 7afd8f2..04a414f 100644 --- a/src/layouts/azerty.rs +++ b/src/layouts/azerty.rs @@ -14,8 +14,7 @@ use crate::{ /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We /// show either a Unicode glyph, or a hex number if the glyph isn't a /// printable character. Blank spaces are passed through as -/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are -/// sometimes Unicode and sometimes not, depending on modifiers. +/// [`DecodedKey::RawKey`]. /// /// Run the `print_keyboard` example to re-generate these images. /// @@ -27,9 +26,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ a │ z │ e │ r │ t │ y │ u │ i │ o │ p │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ a │ z │ e │ r │ t │ y │ u │ i │ o │ p │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ q │ s │ d │ f │ g │ h │ j │ k │ l │ m │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -47,9 +46,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -67,9 +66,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ² │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ² │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ £ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ £ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ % │ µ │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -87,9 +86,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ² │ & │ é │ " │ ' │ ( │ - │ è │ _ │ ç │ à │ ) │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │0001│001a│0005│0012│0014│0019│0015│0009│000f│0010│ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │0001│001a│0005│0012│0014│0019│0015│0009│000f│0010│ ^ │ $ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │0011│0013│0004│0006│0007│0008│000a│000b│000c│000d│ ù │ * │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -107,9 +106,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ² │ & │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ² │ & │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ a │ z │ € │ r │ t │ y │ u │ i │ o │ p │ ^ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ a │ z │ € │ r │ t │ y │ u │ i │ o │ p │ ^ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ q │ s │ d │ f │ g │ h │ j │ k │ l │ m │ ù │ * │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -127,9 +126,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ² │ 1 │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ² │ 1 │ ~ │ # │ { │ [ │ | │ ` │ \ │ ^ │ @ │ ] │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ A │ Z │ € │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ A │ Z │ € │ R │ T │ Y │ U │ I │ O │ P │ ¨ │ ¤ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ % │ µ │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -138,7 +137,6 @@ use crate::{ /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` -/// pub struct Azerty; impl KeyboardLayout for Azerty { diff --git a/src/layouts/colemak.rs b/src/layouts/colemak.rs index ce11b98..6ea3d8d 100644 --- a/src/layouts/colemak.rs +++ b/src/layouts/colemak.rs @@ -11,8 +11,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We /// show either a Unicode glyph, or a hex number if the glyph isn't a /// printable character. Blank spaces are passed through as -/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are -/// sometimes Unicode and sometimes not, depending on modifiers. +/// [`DecodedKey::RawKey`]. /// /// Run the `print_keyboard` example to re-generate these images. /// @@ -24,7 +23,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │0009 │ q │ w │ f │ p │ g │ j │ l │ u │ y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ @@ -44,7 +43,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ @@ -64,7 +63,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ : │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ @@ -84,7 +83,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │0009 │0011│0017│0006│0010│0007│000a│000c│0015│0019│ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ @@ -96,6 +95,45 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` /// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ f │ p │ g │ j │ l │ u │ y │ ; │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ r │ s │ t │ d │ h │ n │ e │ i │ o │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ z │ x │ c │ v │ b │ k │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ F │ P │ G │ J │ L │ U │ Y │ : │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ R │ S │ T │ D │ H │ N │ E │ I │ O │ " │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ K │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct Colemak; impl KeyboardLayout for Colemak { diff --git a/src/layouts/de105.rs b/src/layouts/de105.rs index c6e9ed4..9f98d57 100644 --- a/src/layouts/de105.rs +++ b/src/layouts/de105.rs @@ -9,6 +9,133 @@ use crate::{ /// The top row spells `QWERTZ`. /// /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ z │ u │ i │ o │ p │ ü │ + │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ y │ x │ c │ v │ b │ n │ m │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ Ü │ + │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ Y │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ° │ ! │ " │ § │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ Ü │ * │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ > │ Y │ X │ C │ V │ B │ N │ M │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0005│0012│0014│001a│0015│0009│000f│0010│ ü │ + │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ö │ ä │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │0019│0018│0003│0016│0002│000e│000d│ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ^ │ 1 │ ² │ ³ │ 4 │ 5 │ 6 │ { │ [ │ ] │ } │ \ │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ @ │ w │ € │ r │ t │ z │ u │ i │ o │ p │ ü │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ # │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ | │ y │ x │ c │ v │ b │ n │ µ │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ° │ ! │ ² │ ³ │ $ │ % │ & │ { │ [ │ ] │ } │ \ │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ @ │ W │ € │ R │ T │ Z │ U │ I │ O │ P │ Ü │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ | │ Y │ X │ C │ V │ B │ N │ µ │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct De105Key; impl KeyboardLayout for De105Key { diff --git a/src/layouts/dvorak104.rs b/src/layouts/dvorak104.rs index 3464c93..5c1c0f9 100644 --- a/src/layouts/dvorak104.rs +++ b/src/layouts/dvorak104.rs @@ -5,6 +5,133 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// A Dvorak 101-key (or 104-key including Windows keys) keyboard. /// /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ' │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ; │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ' │ , │ . │ P │ Y │ F │ G │ C │ R │ L │ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ; │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ { │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ " │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ + │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ : │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ' │ , │ . │0010│0019│0006│0007│0003│0012│000c│ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│000f│0005│0015│0009│0004│0008│0014│000e│0013│ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ; │0011│000a│000b│0018│0002│000d│0017│0016│001a│ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ [ │ ] │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ' │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ = │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ; │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ { │ } │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ " │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ + │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ : │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct Dvorak104Key; impl KeyboardLayout for Dvorak104Key { diff --git a/src/layouts/dvorak_programmer104.rs b/src/layouts/dvorak_programmer104.rs index 32ba412..b7546de 100644 --- a/src/layouts/dvorak_programmer104.rs +++ b/src/layouts/dvorak_programmer104.rs @@ -7,6 +7,133 @@ use crate::{ /// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard. /// /// Has a 1-row high Enter key, with Oem5 above (ANSI layout). +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ; │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ' │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ; │ , │ . │ P │ Y │ F │ G │ C │ R │ L │ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ' │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ % │ 7 │ 5 │ 3 │ 1 │ 9 │ 0 │ 2 │ 4 │ 6 │ 8 │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ : │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ ^ │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ " │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ; │ , │ . │0010│0019│0006│0007│0003│0012│000c│ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│000f│0005│0015│0009│0004│0008│0014│000e│0013│ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ' │0011│000a│000b│0018│0002│000d│0017│0016│001a│ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ $ │ & │ [ │ { │ } │ ( │ = │ * │ ) │ + │ ] │ ! │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ ; │ , │ . │ p │ y │ f │ g │ c │ r │ l │ / │ @ │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ o │ e │ u │ i │ d │ h │ t │ n │ s │ - │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ ' │ q │ j │ k │ x │ b │ m │ w │ v │ z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ % │ 7 │ 5 │ 3 │ 1 │ 9 │ 0 │ 2 │ 4 │ 6 │ 8 │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ : │ < │ > │ P │ Y │ F │ G │ C │ R │ L │ ? │ ^ │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ O │ E │ U │ I │ D │ H │ T │ N │ S │ _ │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ " │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct DVP104Key; impl KeyboardLayout for DVP104Key { diff --git a/src/layouts/fi_se105.rs b/src/layouts/fi_se105.rs index f8120e3..b6fda79 100644 --- a/src/layouts/fi_se105.rs +++ b/src/layouts/fi_se105.rs @@ -7,6 +7,133 @@ use crate::{ /// A standard Finnish/Swedish 102-key (or 105-key including Windows keys) keyboard. /// /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ z │ x │ c │ v │ b │ n │ m │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ½ │ ! │ " │ # │ ¤ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ^ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ > │ Z │ X │ C │ V │ B │ N │ M │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ö │ ä │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │001a│0018│0003│0016│0002│000e│000d│ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ § │ 1 │ @ │ £ │ $ │ € │ 6 │ { │ [ │ ] │ } │ \ │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ € │ r │ t │ y │ u │ i │ o │ p │ å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ö │ ä │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ | │ z │ x │ c │ v │ b │ n │ µ │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ½ │ ! │ @ │ £ │ $ │ € │ & │ { │ [ │ ] │ } │ \ │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ € │ R │ T │ Y │ U │ I │ O │ P │ Å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ | │ Z │ X │ C │ V │ B │ N │ µ │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct FiSe105Key; impl KeyboardLayout for FiSe105Key { diff --git a/src/layouts/no105.rs b/src/layouts/no105.rs index 8742374..69a07a5 100644 --- a/src/layouts/no105.rs +++ b/src/layouts/no105.rs @@ -7,6 +7,133 @@ use crate::{ /// A standard Norwegian 102-key (or 105-key including Windows keys) keyboard. /// /// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format). +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ | │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ \ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ø │ æ │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ z │ x │ c │ v │ b │ n │ m │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ | │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ \ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ø │ Æ │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ § │ ! │ " │ # │ ¤ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ Å │ ^ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ø │ Æ │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ > │ Z │ X │ C │ V │ B │ N │ M │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ | │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ + │ \ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ å │ ¨ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ø │ æ │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │001a│0018│0003│0016│0002│000e│000d│ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ | │ 1 │ @ │ £ │ $ │ 5 │ 6 │ { │ [ │ ] │ } │ + │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ € │ r │ t │ y │ u │ i │ o │ p │ å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ø │ æ │ ' │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ < │ z │ x │ c │ v │ b │ n │ µ │ , │ . │ - │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ § │ ! │ @ │ £ │ $ │ % │ & │ { │ [ │ ] │ } │ ? │ ´ │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ € │ R │ T │ Y │ U │ I │ O │ P │ Å │ ~ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ø │ Æ │ * │ │ │ 4 │ 5 │ 6 │ │ +/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ > │ Z │ X │ C │ V │ B │ N │ µ │ ; │ : │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ , │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct No105Key; impl KeyboardLayout for No105Key { diff --git a/src/layouts/uk105.rs b/src/layouts/uk105.rs index 5da1813..b5c3875 100644 --- a/src/layouts/uk105.rs +++ b/src/layouts/uk105.rs @@ -13,8 +13,7 @@ use crate::{ /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We /// show either a Unicode glyph, or a hex number if the glyph isn't a /// printable character. Blank spaces are passed through as -/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are -/// sometimes Unicode and sometimes not, depending on modifiers. +/// [`DecodedKey::RawKey`]. /// /// Run the `print_keyboard` example to re-generate these images. /// @@ -26,9 +25,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -46,9 +45,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -66,9 +65,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -86,9 +85,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -106,9 +105,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ¦ │ 1 │ 2 │ 3 │ € │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ¦ │ 1 │ 2 │ 3 │ € │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ q │ w │ é │ r │ t │ y │ ú │ í │ ó │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ q │ w │ é │ r │ t │ y │ ú │ í │ ó │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ á │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -126,9 +125,9 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ¦ │ ! │ " │ £ │ € │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ¦ │ ! │ " │ £ │ € │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ Q │ W │ É │ R │ T │ Y │ Ú │ Í │ Ó │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ Q │ W │ É │ R │ T │ Y │ Ú │ Í │ Ó │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ /// │ │ Á │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │ /// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤ @@ -137,7 +136,6 @@ use crate::{ /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` -/// pub struct Uk105Key; impl KeyboardLayout for Uk105Key { diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs index 02d2d91..cbb4bd0 100644 --- a/src/layouts/us104.rs +++ b/src/layouts/us104.rs @@ -11,8 +11,7 @@ use crate::{ /// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We /// show either a Unicode glyph, or a hex number if the glyph isn't a /// printable character. Blank spaces are passed through as -/// [`DecodedKey::RawKey`]. We also show Raw outputs on keys that are -/// sometimes Unicode and sometimes not, depending on modifiers. +/// [`DecodedKey::RawKey`]. /// /// Run the `print_keyboard` example to re-generate these images. /// @@ -24,7 +23,7 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ @@ -36,7 +35,7 @@ use crate::{ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` /// -/// ## Shifted +/// ## Caps Lock /// /// ```text /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ @@ -44,19 +43,19 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ -/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " │ 000a │ │ 4 │ 5 │ 6 │ │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ -/// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` /// -/// ## Caps Lock +/// ## Shifted /// /// ```text /// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ @@ -64,13 +63,13 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ -/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ -/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " │ 000a │ │ 4 │ 5 │ 6 │ │ /// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ -/// │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ /// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ /// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ @@ -84,7 +83,7 @@ use crate::{ /// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ /// /// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ -/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │0008 │ │ │ │ │ │ │ / │ * │ - │ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ /// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ /// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ /// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ @@ -96,6 +95,45 @@ use crate::{ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` /// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ \ │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " │ 000a │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct Us104Key; impl KeyboardLayout for Us104Key { diff --git a/src/lib.rs b/src/lib.rs index 9249891..8842de8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,8 +57,11 @@ //! //! This crate uses symbolic keycodes to abstract over Scancode Set 1 and //! Scancode Set 2. They represented by the `KeyCode` enum. The scancodes can -//! come from one of three supported keyboards: 102/105 key ISO, 101/104 key -//! ANSI and 106/109-key JIS. +//! come from one of three supported physical keyboard layouts: 102/105 key +//! ISO, 101/104 key ANSI and 106/109-key JIS. Note that the symbolic +//! keycodes for letter keys are named after how the keys are used on a US or +//! UK English Keyboard. If you use a French AZERTY layout, the `KeyCode::Q` +//! key will produce the Unicode character `'A'`. //! //! ### 102/105 key [ISO](PhysicalKeyboard::Iso) //! @@ -136,7 +139,9 @@ //! └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ //! ``` //! -//! Note that the `Oem5` is missing on the 109-key JIS layout, but `Oem9` (Muhenkan), `Oem10` (Henkan/Zenkouho), `Oem11` (Hiragana/Katakana), `Oem12` (Backslash) and `Oem13` (¥) are added. +//! Note that the `Oem5` is missing on the 109-key JIS layout, but `Oem9` +//! (Muhenkan), `Oem10` (Henkan/Zenkouho), `Oem11` +//! (Hiragana/Katakana), `Oem12` (Backslash) and `Oem13` (¥) are added. //! //! The 106-key is missing `LWin`, `RWin`, and `Menu`. //! From 4339cdf1225c848bd01ee9fcb5546285408f3b04 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 5 Jun 2025 20:01:14 +0100 Subject: [PATCH 11/18] Rename handler functions. Also add one where the Alt key is the same regardless of shift status. --- src/layouts/azerty.rs | 58 ++++++------- src/layouts/colemak.rs | 34 ++++---- src/layouts/de105.rs | 48 +++++------ src/layouts/dvorak104.rs | 66 +++++++-------- src/layouts/dvorak_programmer104.rs | 94 ++++++++++----------- src/layouts/fi_se105.rs | 47 +++++------ src/layouts/no105.rs | 49 +++++------ src/layouts/uk105.rs | 24 +++--- src/layouts/us104.rs | 124 ++++++++++++++-------------- src/lib.rs | 118 ++++++++++++++++++++------ 10 files changed, 362 insertions(+), 300 deletions(-) diff --git a/src/layouts/azerty.rs b/src/layouts/azerty.rs index 04a414f..35fc007 100644 --- a/src/layouts/azerty.rs +++ b/src/layouts/azerty.rs @@ -150,40 +150,36 @@ impl KeyboardLayout for Azerty { match keycode { // ========= Row 2 (the numbers) ========= KeyCode::Oem8 => DecodedKey::Unicode('²'), - KeyCode::Key1 => modifiers.handle_shift('&', '1'), - KeyCode::Key2 => modifiers.handle_altsh('é', '2', '~'), - KeyCode::Key3 => modifiers.handle_altsh('"', '3', '#'), - KeyCode::Key4 => modifiers.handle_altsh(QUO, '4', '{'), - KeyCode::Key5 => modifiers.handle_altsh('(', '5', '['), - KeyCode::Key6 => modifiers.handle_altsh('-', '6', '|'), - KeyCode::Key7 => modifiers.handle_altsh('è', '7', '`'), - KeyCode::Key8 => modifiers.handle_altsh('_', '8', SLS), - KeyCode::Key9 => modifiers.handle_altsh('ç', '9', '^'), - KeyCode::Key0 => modifiers.handle_altsh('à', '0', '@'), - KeyCode::OemMinus => modifiers.handle_altsh(')', '°', ']'), - KeyCode::OemPlus => modifiers.handle_altsh('=', '+', '}'), - + KeyCode::Key1 => modifiers.handle_symbol2('&', '1'), + KeyCode::Key2 => modifiers.handle_symbol3('é', '2', '~'), + KeyCode::Key3 => modifiers.handle_symbol3('"', '3', '#'), + KeyCode::Key4 => modifiers.handle_symbol3(QUO, '4', '{'), + KeyCode::Key5 => modifiers.handle_symbol3('(', '5', '['), + KeyCode::Key6 => modifiers.handle_symbol3('-', '6', '|'), + KeyCode::Key7 => modifiers.handle_symbol3('è', '7', '`'), + KeyCode::Key8 => modifiers.handle_symbol3('_', '8', SLS), + KeyCode::Key9 => modifiers.handle_symbol3('ç', '9', '^'), + KeyCode::Key0 => modifiers.handle_symbol3('à', '0', '@'), + KeyCode::OemMinus => modifiers.handle_symbol3(')', '°', ']'), + KeyCode::OemPlus => modifiers.handle_symbol3('=', '+', '}'), // ========= Row 3 (QWERTY) ========= - KeyCode::Q => modifiers.handle_alpha('A', handle_ctrl), - KeyCode::W => modifiers.handle_alpha('Z', handle_ctrl), - KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_shift('^', '¨'), - KeyCode::Oem6 => modifiers.handle_altsh('$', '£', '¤'), - + KeyCode::Q => modifiers.handle_ascii_2('A', handle_ctrl), + KeyCode::W => modifiers.handle_ascii_2('Z', handle_ctrl), + KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_symbol2('^', '¨'), + KeyCode::Oem6 => modifiers.handle_symbol3('$', '£', '¤'), // ========= Row 4 (ASDFG) ========= - KeyCode::A => modifiers.handle_alpha('Q', handle_ctrl), - KeyCode::Oem1 => modifiers.handle_alpha('M', handle_ctrl), - KeyCode::Oem3 => modifiers.handle_shift('ù', '%'), - KeyCode::Oem7 => modifiers.handle_shift('*', 'µ'), - + KeyCode::A => modifiers.handle_ascii_2('Q', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_ascii_2('M', handle_ctrl), + KeyCode::Oem3 => modifiers.handle_symbol2('ù', '%'), + KeyCode::Oem7 => modifiers.handle_symbol2('*', 'µ'), // ========= Row 5 (ZXCVB) ========= - KeyCode::Oem5 => modifiers.handle_shift('<', '>'), - KeyCode::Z => modifiers.handle_alpha('W', handle_ctrl), - KeyCode::M => modifiers.handle_shift(',', '?'), - KeyCode::OemComma => modifiers.handle_shift(';', '.'), - KeyCode::OemPeriod => modifiers.handle_shift(':', '/'), - KeyCode::Oem2 => modifiers.handle_shift('!', '§'), - + KeyCode::Oem5 => modifiers.handle_symbol2('<', '>'), + KeyCode::Z => modifiers.handle_ascii_2('W', handle_ctrl), + KeyCode::M => modifiers.handle_symbol2(',', '?'), + KeyCode::OemComma => modifiers.handle_symbol2(';', '.'), + KeyCode::OemPeriod => modifiers.handle_symbol2(':', '/'), + KeyCode::Oem2 => modifiers.handle_symbol2('!', '§'), // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } diff --git a/src/layouts/colemak.rs b/src/layouts/colemak.rs index 6ea3d8d..b1b6bc4 100644 --- a/src/layouts/colemak.rs +++ b/src/layouts/colemak.rs @@ -146,25 +146,25 @@ impl KeyboardLayout for Colemak { ) -> DecodedKey { match keycode { // ========= Row 3 (QWERTY) ========= - KeyCode::E => modifiers.handle_alpha('F', handle_ctrl), - KeyCode::R => modifiers.handle_alpha('P', handle_ctrl), - KeyCode::T => modifiers.handle_alpha('G', handle_ctrl), - KeyCode::Y => modifiers.handle_alpha('J', handle_ctrl), - KeyCode::U => modifiers.handle_alpha('L', handle_ctrl), - KeyCode::I => modifiers.handle_alpha('U', handle_ctrl), - KeyCode::O => modifiers.handle_alpha('Y', handle_ctrl), - KeyCode::P => modifiers.handle_shift(';', ':'), + KeyCode::E => modifiers.handle_ascii_2('F', handle_ctrl), + KeyCode::R => modifiers.handle_ascii_2('P', handle_ctrl), + KeyCode::T => modifiers.handle_ascii_2('G', handle_ctrl), + KeyCode::Y => modifiers.handle_ascii_2('J', handle_ctrl), + KeyCode::U => modifiers.handle_ascii_2('L', handle_ctrl), + KeyCode::I => modifiers.handle_ascii_2('U', handle_ctrl), + KeyCode::O => modifiers.handle_ascii_2('Y', handle_ctrl), + KeyCode::P => modifiers.handle_symbol2(';', ':'), // ========= Row 4 (ASDFG) ========= - KeyCode::S => modifiers.handle_alpha('R', handle_ctrl), - KeyCode::D => modifiers.handle_alpha('S', handle_ctrl), - KeyCode::F => modifiers.handle_alpha('T', handle_ctrl), - KeyCode::G => modifiers.handle_alpha('D', handle_ctrl), - KeyCode::J => modifiers.handle_alpha('N', handle_ctrl), - KeyCode::K => modifiers.handle_alpha('E', handle_ctrl), - KeyCode::L => modifiers.handle_alpha('I', handle_ctrl), - KeyCode::Oem1 => modifiers.handle_alpha('O', handle_ctrl), + KeyCode::S => modifiers.handle_ascii_2('R', handle_ctrl), + KeyCode::D => modifiers.handle_ascii_2('S', handle_ctrl), + KeyCode::F => modifiers.handle_ascii_2('T', handle_ctrl), + KeyCode::G => modifiers.handle_ascii_2('D', handle_ctrl), + KeyCode::J => modifiers.handle_ascii_2('N', handle_ctrl), + KeyCode::K => modifiers.handle_ascii_2('E', handle_ctrl), + KeyCode::L => modifiers.handle_ascii_2('I', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_ascii_2('O', handle_ctrl), // ========= Row 5 (ZXCVB) ========= - KeyCode::N => modifiers.handle_alpha('K', handle_ctrl), + KeyCode::N => modifiers.handle_ascii_2('K', handle_ctrl), // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } diff --git a/src/layouts/de105.rs b/src/layouts/de105.rs index 9f98d57..c74cdda 100644 --- a/src/layouts/de105.rs +++ b/src/layouts/de105.rs @@ -148,33 +148,33 @@ impl KeyboardLayout for De105Key { ) -> DecodedKey { match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::Oem8 => modifiers.handle_shift('^', '°'), - KeyCode::Key2 => modifiers.handle_altsh('2', '"', '²'), - KeyCode::Key3 => modifiers.handle_altsh('3', '§', '³'), - KeyCode::Key6 => modifiers.handle_shift('6', '&'), - KeyCode::Key7 => modifiers.handle_altsh('7', '/', '{'), - KeyCode::Key8 => modifiers.handle_altsh('8', '(', '['), - KeyCode::Key9 => modifiers.handle_altsh('9', ')', ']'), - KeyCode::Key0 => modifiers.handle_altsh('0', '=', '}'), - KeyCode::OemMinus => modifiers.handle_altsh('ß', '?', SLS), - KeyCode::OemPlus => modifiers.handle_shift('´', '`'), + KeyCode::Oem8 => modifiers.handle_symbol2('^', '°'), + KeyCode::Key2 => modifiers.handle_symbol3('2', '"', '²'), + KeyCode::Key3 => modifiers.handle_symbol3('3', '§', '³'), + KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), + KeyCode::Key7 => modifiers.handle_symbol3('7', '/', '{'), + KeyCode::Key8 => modifiers.handle_symbol3('8', '(', '['), + KeyCode::Key9 => modifiers.handle_symbol3('9', ')', ']'), + KeyCode::Key0 => modifiers.handle_symbol3('0', '=', '}'), + KeyCode::OemMinus => modifiers.handle_symbol3('ß', '?', SLS), + KeyCode::OemPlus => modifiers.handle_symbol2('´', '`'), // ========= Row 3 (QWERTY) ========= - KeyCode::Q => modifiers.handle_alalt('Q', '@', '@', handle_ctrl), - KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), - KeyCode::Y => modifiers.handle_alpha('Z', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_accen('ü', 'Ü'), - KeyCode::Oem6 => modifiers.handle_altsh('+', '*', '~'), + KeyCode::Q => modifiers.handle_ascii_3('Q', '@', handle_ctrl), + KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), + KeyCode::Y => modifiers.handle_ascii_2('Z', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_letter2('ü', 'Ü'), + KeyCode::Oem6 => modifiers.handle_symbol3('+', '*', '~'), // ========= Row 4 (ASDFG) ========= - KeyCode::Oem1 => modifiers.handle_accen('ö', 'Ö'), - KeyCode::Oem3 => modifiers.handle_accen('ä', 'Ä'), - KeyCode::Oem7 => modifiers.handle_shift('#', QUO), + KeyCode::Oem1 => modifiers.handle_letter2('ö', 'Ö'), + KeyCode::Oem3 => modifiers.handle_letter2('ä', 'Ä'), + KeyCode::Oem7 => modifiers.handle_symbol2('#', QUO), // ========= Row 5 (ZXCVB) ========= - KeyCode::Oem5 => modifiers.handle_altsh('<', '>', '|'), - KeyCode::Z => modifiers.handle_alpha('Y', handle_ctrl), - KeyCode::M => modifiers.handle_alalt('M', 'µ', 'µ', handle_ctrl), - KeyCode::OemComma => modifiers.handle_shift(',', ';'), - KeyCode::OemPeriod => modifiers.handle_shift('.', ':'), - KeyCode::Oem2 => modifiers.handle_shift('-', '_'), + KeyCode::Oem5 => modifiers.handle_symbol3('<', '>', '|'), + KeyCode::Z => modifiers.handle_ascii_2('Y', handle_ctrl), + KeyCode::M => modifiers.handle_ascii_3('M', 'µ', handle_ctrl), + KeyCode::OemComma => modifiers.handle_symbol2(',', ';'), + KeyCode::OemPeriod => modifiers.handle_symbol2('.', ':'), + KeyCode::Oem2 => modifiers.handle_symbol2('-', '_'), // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } diff --git a/src/layouts/dvorak104.rs b/src/layouts/dvorak104.rs index 5c1c0f9..631f2dd 100644 --- a/src/layouts/dvorak104.rs +++ b/src/layouts/dvorak104.rs @@ -144,42 +144,42 @@ impl KeyboardLayout for Dvorak104Key { ) -> DecodedKey { match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::OemMinus => modifiers.handle_shift('[', '{'), - KeyCode::OemPlus => modifiers.handle_shift(']', '}'), + KeyCode::OemMinus => modifiers.handle_symbol2('[', '{'), + KeyCode::OemPlus => modifiers.handle_symbol2(']', '}'), // ========= Row 3 (QWERTY) ========= - KeyCode::Q => modifiers.handle_shift(QUO, '"'), - KeyCode::W => modifiers.handle_shift(',', '<'), - KeyCode::E => modifiers.handle_shift('.', '>'), - KeyCode::R => modifiers.handle_alpha('P', handle_ctrl), - KeyCode::T => modifiers.handle_alpha('Y', handle_ctrl), - KeyCode::Y => modifiers.handle_alpha('F', handle_ctrl), - KeyCode::U => modifiers.handle_alpha('G', handle_ctrl), - KeyCode::I => modifiers.handle_alpha('C', handle_ctrl), - KeyCode::O => modifiers.handle_alpha('R', handle_ctrl), - KeyCode::P => modifiers.handle_alpha('L', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_shift('/', '?'), - KeyCode::Oem6 => modifiers.handle_shift('=', '+'), + KeyCode::Q => modifiers.handle_symbol2(QUO, '"'), + KeyCode::W => modifiers.handle_symbol2(',', '<'), + KeyCode::E => modifiers.handle_symbol2('.', '>'), + KeyCode::R => modifiers.handle_ascii_2('P', handle_ctrl), + KeyCode::T => modifiers.handle_ascii_2('Y', handle_ctrl), + KeyCode::Y => modifiers.handle_ascii_2('F', handle_ctrl), + KeyCode::U => modifiers.handle_ascii_2('G', handle_ctrl), + KeyCode::I => modifiers.handle_ascii_2('C', handle_ctrl), + KeyCode::O => modifiers.handle_ascii_2('R', handle_ctrl), + KeyCode::P => modifiers.handle_ascii_2('L', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_symbol2('/', '?'), + KeyCode::Oem6 => modifiers.handle_symbol2('=', '+'), // ========= Row 4 (ASDFG) ========= - KeyCode::S => modifiers.handle_alpha('O', handle_ctrl), - KeyCode::D => modifiers.handle_alpha('E', handle_ctrl), - KeyCode::F => modifiers.handle_alpha('U', handle_ctrl), - KeyCode::G => modifiers.handle_alpha('I', handle_ctrl), - KeyCode::H => modifiers.handle_alpha('D', handle_ctrl), - KeyCode::J => modifiers.handle_alpha('H', handle_ctrl), - KeyCode::K => modifiers.handle_alpha('T', handle_ctrl), - KeyCode::L => modifiers.handle_alpha('N', handle_ctrl), - KeyCode::Oem1 => modifiers.handle_alpha('S', handle_ctrl), - KeyCode::Oem3 => modifiers.handle_shift('-', '_'), + KeyCode::S => modifiers.handle_ascii_2('O', handle_ctrl), + KeyCode::D => modifiers.handle_ascii_2('E', handle_ctrl), + KeyCode::F => modifiers.handle_ascii_2('U', handle_ctrl), + KeyCode::G => modifiers.handle_ascii_2('I', handle_ctrl), + KeyCode::H => modifiers.handle_ascii_2('D', handle_ctrl), + KeyCode::J => modifiers.handle_ascii_2('H', handle_ctrl), + KeyCode::K => modifiers.handle_ascii_2('T', handle_ctrl), + KeyCode::L => modifiers.handle_ascii_2('N', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_ascii_2('S', handle_ctrl), + KeyCode::Oem3 => modifiers.handle_symbol2('-', '_'), // ========= Row 5 (ZXCVB) ========= - KeyCode::Z => modifiers.handle_shift(';', ':'), - KeyCode::X => modifiers.handle_alpha('Q', handle_ctrl), - KeyCode::C => modifiers.handle_alpha('J', handle_ctrl), - KeyCode::V => modifiers.handle_alpha('K', handle_ctrl), - KeyCode::B => modifiers.handle_alpha('X', handle_ctrl), - KeyCode::N => modifiers.handle_alpha('B', handle_ctrl), - KeyCode::OemComma => modifiers.handle_alpha('W', handle_ctrl), - KeyCode::OemPeriod => modifiers.handle_alpha('V', handle_ctrl), - KeyCode::Oem2 => modifiers.handle_alpha('Z', handle_ctrl), + KeyCode::Z => modifiers.handle_symbol2(';', ':'), + KeyCode::X => modifiers.handle_ascii_2('Q', handle_ctrl), + KeyCode::C => modifiers.handle_ascii_2('J', handle_ctrl), + KeyCode::V => modifiers.handle_ascii_2('K', handle_ctrl), + KeyCode::B => modifiers.handle_ascii_2('X', handle_ctrl), + KeyCode::N => modifiers.handle_ascii_2('B', handle_ctrl), + KeyCode::OemComma => modifiers.handle_ascii_2('W', handle_ctrl), + KeyCode::OemPeriod => modifiers.handle_ascii_2('V', handle_ctrl), + KeyCode::Oem2 => modifiers.handle_ascii_2('Z', handle_ctrl), // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } diff --git a/src/layouts/dvorak_programmer104.rs b/src/layouts/dvorak_programmer104.rs index b7546de..b24eee4 100644 --- a/src/layouts/dvorak_programmer104.rs +++ b/src/layouts/dvorak_programmer104.rs @@ -146,56 +146,56 @@ impl KeyboardLayout for DVP104Key { ) -> DecodedKey { match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::Oem8 => modifiers.handle_shift('$', '~'), - KeyCode::Key1 => modifiers.handle_shift('&', '%'), - KeyCode::Key2 => modifiers.handle_shift('[', '7'), - KeyCode::Key3 => modifiers.handle_shift('{', '5'), - KeyCode::Key4 => modifiers.handle_shift('}', '3'), - KeyCode::Key5 => modifiers.handle_shift('(', '1'), - KeyCode::Key6 => modifiers.handle_shift('=', '9'), - KeyCode::Key7 => modifiers.handle_shift('*', '0'), - KeyCode::Key8 => modifiers.handle_shift(')', '2'), - KeyCode::Key9 => modifiers.handle_shift('+', '4'), - KeyCode::Key0 => modifiers.handle_shift(']', '6'), - KeyCode::OemMinus => modifiers.handle_shift('!', '8'), - KeyCode::OemPlus => modifiers.handle_shift('=', '`'), + KeyCode::Oem8 => modifiers.handle_symbol2('$', '~'), + KeyCode::Key1 => modifiers.handle_symbol2('&', '%'), + KeyCode::Key2 => modifiers.handle_symbol2('[', '7'), + KeyCode::Key3 => modifiers.handle_symbol2('{', '5'), + KeyCode::Key4 => modifiers.handle_symbol2('}', '3'), + KeyCode::Key5 => modifiers.handle_symbol2('(', '1'), + KeyCode::Key6 => modifiers.handle_symbol2('=', '9'), + KeyCode::Key7 => modifiers.handle_symbol2('*', '0'), + KeyCode::Key8 => modifiers.handle_symbol2(')', '2'), + KeyCode::Key9 => modifiers.handle_symbol2('+', '4'), + KeyCode::Key0 => modifiers.handle_symbol2(']', '6'), + KeyCode::OemMinus => modifiers.handle_symbol2('!', '8'), + KeyCode::OemPlus => modifiers.handle_symbol2('=', '`'), // ========= Row 3 (QWERTY) ========= - KeyCode::Q => modifiers.handle_shift(';', ':'), - KeyCode::W => modifiers.handle_shift(',', '<'), - KeyCode::E => modifiers.handle_shift('.', '>'), - KeyCode::R => modifiers.handle_alpha('P', handle_ctrl), - KeyCode::T => modifiers.handle_alpha('Y', handle_ctrl), - KeyCode::Y => modifiers.handle_alpha('F', handle_ctrl), - KeyCode::U => modifiers.handle_alpha('G', handle_ctrl), - KeyCode::I => modifiers.handle_alpha('C', handle_ctrl), - KeyCode::O => modifiers.handle_alpha('R', handle_ctrl), - KeyCode::P => modifiers.handle_alpha('L', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_shift('/', '?'), - KeyCode::Oem6 => modifiers.handle_shift('@', '^'), - KeyCode::Oem7 => modifiers.handle_shift(SLS, '|'), + KeyCode::Q => modifiers.handle_symbol2(';', ':'), + KeyCode::W => modifiers.handle_symbol2(',', '<'), + KeyCode::E => modifiers.handle_symbol2('.', '>'), + KeyCode::R => modifiers.handle_ascii_2('P', handle_ctrl), + KeyCode::T => modifiers.handle_ascii_2('Y', handle_ctrl), + KeyCode::Y => modifiers.handle_ascii_2('F', handle_ctrl), + KeyCode::U => modifiers.handle_ascii_2('G', handle_ctrl), + KeyCode::I => modifiers.handle_ascii_2('C', handle_ctrl), + KeyCode::O => modifiers.handle_ascii_2('R', handle_ctrl), + KeyCode::P => modifiers.handle_ascii_2('L', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_symbol2('/', '?'), + KeyCode::Oem6 => modifiers.handle_symbol2('@', '^'), + KeyCode::Oem7 => modifiers.handle_symbol2(SLS, '|'), // ========= Row 4 (ASDFG) ========= - KeyCode::A => modifiers.handle_alpha('A', handle_ctrl), - KeyCode::S => modifiers.handle_alpha('O', handle_ctrl), - KeyCode::D => modifiers.handle_alpha('E', handle_ctrl), - KeyCode::F => modifiers.handle_alpha('U', handle_ctrl), - KeyCode::G => modifiers.handle_alpha('I', handle_ctrl), - KeyCode::H => modifiers.handle_alpha('D', handle_ctrl), - KeyCode::J => modifiers.handle_alpha('H', handle_ctrl), - KeyCode::K => modifiers.handle_alpha('T', handle_ctrl), - KeyCode::L => modifiers.handle_alpha('N', handle_ctrl), - KeyCode::Oem1 => modifiers.handle_alpha('S', handle_ctrl), - KeyCode::Oem3 => modifiers.handle_shift('-', '_'), + KeyCode::A => modifiers.handle_ascii_2('A', handle_ctrl), + KeyCode::S => modifiers.handle_ascii_2('O', handle_ctrl), + KeyCode::D => modifiers.handle_ascii_2('E', handle_ctrl), + KeyCode::F => modifiers.handle_ascii_2('U', handle_ctrl), + KeyCode::G => modifiers.handle_ascii_2('I', handle_ctrl), + KeyCode::H => modifiers.handle_ascii_2('D', handle_ctrl), + KeyCode::J => modifiers.handle_ascii_2('H', handle_ctrl), + KeyCode::K => modifiers.handle_ascii_2('T', handle_ctrl), + KeyCode::L => modifiers.handle_ascii_2('N', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_ascii_2('S', handle_ctrl), + KeyCode::Oem3 => modifiers.handle_symbol2('-', '_'), // ========= Row 5 (ZXCVB) ========= - KeyCode::Z => modifiers.handle_shift(QUO, '"'), - KeyCode::X => modifiers.handle_alpha('Q', handle_ctrl), - KeyCode::C => modifiers.handle_alpha('J', handle_ctrl), - KeyCode::V => modifiers.handle_alpha('K', handle_ctrl), - KeyCode::B => modifiers.handle_alpha('X', handle_ctrl), - KeyCode::N => modifiers.handle_alpha('B', handle_ctrl), - KeyCode::M => modifiers.handle_alpha('M', handle_ctrl), - KeyCode::OemComma => modifiers.handle_alpha('W', handle_ctrl), - KeyCode::OemPeriod => modifiers.handle_alpha('V', handle_ctrl), - KeyCode::Oem2 => modifiers.handle_alpha('Z', handle_ctrl), + KeyCode::Z => modifiers.handle_symbol2(QUO, '"'), + KeyCode::X => modifiers.handle_ascii_2('Q', handle_ctrl), + KeyCode::C => modifiers.handle_ascii_2('J', handle_ctrl), + KeyCode::V => modifiers.handle_ascii_2('K', handle_ctrl), + KeyCode::B => modifiers.handle_ascii_2('X', handle_ctrl), + KeyCode::N => modifiers.handle_ascii_2('B', handle_ctrl), + KeyCode::M => modifiers.handle_ascii_2('M', handle_ctrl), + KeyCode::OemComma => modifiers.handle_ascii_2('W', handle_ctrl), + KeyCode::OemPeriod => modifiers.handle_ascii_2('V', handle_ctrl), + KeyCode::Oem2 => modifiers.handle_ascii_2('Z', handle_ctrl), // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } diff --git a/src/layouts/fi_se105.rs b/src/layouts/fi_se105.rs index b6fda79..39664df 100644 --- a/src/layouts/fi_se105.rs +++ b/src/layouts/fi_se105.rs @@ -146,34 +146,35 @@ impl KeyboardLayout for FiSe105Key { ) -> DecodedKey { match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::Oem8 => modifiers.handle_shift('§', '½'), - KeyCode::Key2 => modifiers.handle_altsh('2', '"', '@'), - KeyCode::Key3 => modifiers.handle_altsh('3', '#', '£'), - KeyCode::Key4 => modifiers.handle_altsh('4', '¤', '$'), - KeyCode::Key5 => modifiers.handle_altsh('5', '%', '€'), - KeyCode::Key6 => modifiers.handle_shift('6', '&'), - KeyCode::Key7 => modifiers.handle_altsh('7', '/', '{'), - KeyCode::Key8 => modifiers.handle_altsh('8', '(', '['), - KeyCode::Key9 => modifiers.handle_altsh('9', ')', ']'), - KeyCode::Key0 => modifiers.handle_altsh('0', '=', '}'), - KeyCode::OemMinus => modifiers.handle_altsh('+', '?', SLS), - KeyCode::OemPlus => modifiers.handle_shift('´', '`'), + KeyCode::Oem8 => modifiers.handle_symbol2('§', '½'), + KeyCode::Key2 => modifiers.handle_symbol3('2', '"', '@'), + KeyCode::Key3 => modifiers.handle_symbol3('3', '#', '£'), + KeyCode::Key4 => modifiers.handle_symbol3('4', '¤', '$'), + KeyCode::Key5 => modifiers.handle_symbol3('5', '%', '€'), + KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), + KeyCode::Key7 => modifiers.handle_symbol3('7', '/', '{'), + KeyCode::Key8 => modifiers.handle_symbol3('8', '(', '['), + KeyCode::Key9 => modifiers.handle_symbol3('9', ')', ']'), + KeyCode::Key0 => modifiers.handle_symbol3('0', '=', '}'), + KeyCode::OemMinus => modifiers.handle_symbol3('+', '?', SLS), + KeyCode::OemPlus => modifiers.handle_symbol2('´', '`'), // ========= Row 3 (QWERTY) ========= - KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_accen('å', 'Å'), - KeyCode::Oem6 => modifiers.handle_altsh('¨', '^', '~'), + KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_letter2('å', 'Å'), + KeyCode::Oem6 => modifiers.handle_symbol3('¨', '^', '~'), // ========= Row 4 (ASDF) ========= - KeyCode::Oem1 => modifiers.handle_accen('ö', 'Ö'), - KeyCode::Oem3 => modifiers.handle_accen('ä', 'Ä'), - KeyCode::Oem7 => modifiers.handle_shift(QUO, '*'), + KeyCode::Oem1 => modifiers.handle_letter2('ö', 'Ö'), + KeyCode::Oem3 => modifiers.handle_letter2('ä', 'Ä'), + KeyCode::Oem7 => modifiers.handle_symbol2(QUO, '*'), // ========= Row 5 (ZXCV) ========= - KeyCode::Oem5 => modifiers.handle_altsh('<', '>', '|'), - KeyCode::M => modifiers.handle_alalt('M', 'µ', 'µ', handle_ctrl), - KeyCode::OemComma => modifiers.handle_shift(',', ';'), - KeyCode::OemPeriod => modifiers.handle_shift('.', ':'), - KeyCode::Oem2 => modifiers.handle_shift('-', '_'), + KeyCode::Oem5 => modifiers.handle_symbol3('<', '>', '|'), + KeyCode::M => modifiers.handle_ascii_3('M', 'µ', handle_ctrl), + KeyCode::OemComma => modifiers.handle_symbol2(',', ';'), + KeyCode::OemPeriod => modifiers.handle_symbol2('.', ':'), + KeyCode::Oem2 => modifiers.handle_symbol2('-', '_'), // ========= Row 6 (modifers and space bar) ========= KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), + // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } diff --git a/src/layouts/no105.rs b/src/layouts/no105.rs index 69a07a5..f77ef1d 100644 --- a/src/layouts/no105.rs +++ b/src/layouts/no105.rs @@ -146,34 +146,35 @@ impl KeyboardLayout for No105Key { ) -> DecodedKey { match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::Oem8 => modifiers.handle_shift('|', '§'), - KeyCode::Key2 => modifiers.handle_altsh('2', '"', '@'), - KeyCode::Key3 => modifiers.handle_altsh('3', '#', '£'), - KeyCode::Key4 => modifiers.handle_altsh('4', '¤', '$'), - KeyCode::Key5 => modifiers.handle_shift('5', '%'), - KeyCode::Key6 => modifiers.handle_shift('6', '&'), - KeyCode::Key7 => modifiers.handle_altsh('7', '/', '{'), - KeyCode::Key8 => modifiers.handle_altsh('8', '(', '['), - KeyCode::Key9 => modifiers.handle_altsh('9', ')', ']'), - KeyCode::Key0 => modifiers.handle_altsh('0', '=', '}'), - KeyCode::OemMinus => modifiers.handle_shift('+', '?'), - KeyCode::OemPlus => modifiers.handle_altsh(SLS, '`', '´'), + KeyCode::Oem8 => modifiers.handle_symbol2('|', '§'), + KeyCode::Key2 => modifiers.handle_symbol3('2', '"', '@'), + KeyCode::Key3 => modifiers.handle_symbol3('3', '#', '£'), + KeyCode::Key4 => modifiers.handle_symbol3('4', '¤', '$'), + KeyCode::Key5 => modifiers.handle_symbol2('5', '%'), + KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), + KeyCode::Key7 => modifiers.handle_symbol3('7', '/', '{'), + KeyCode::Key8 => modifiers.handle_symbol3('8', '(', '['), + KeyCode::Key9 => modifiers.handle_symbol3('9', ')', ']'), + KeyCode::Key0 => modifiers.handle_symbol3('0', '=', '}'), + KeyCode::OemMinus => modifiers.handle_symbol2('+', '?'), + KeyCode::OemPlus => modifiers.handle_symbol3(SLS, '`', '´'), // ========= Row 3 (QWERTY) ========= - KeyCode::E => modifiers.handle_alalt('E', '€', '€', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_accen('å', 'Å'), - KeyCode::Oem6 => modifiers.handle_altsh('¨', '^', '~'), + KeyCode::E => modifiers.handle_ascii_3('E', '€', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_letter2('å', 'Å'), + KeyCode::Oem6 => modifiers.handle_symbol3('¨', '^', '~'), // ========= Row 4 (ASDF) ========= - KeyCode::Oem7 => modifiers.handle_shift(QUO, '*'), - KeyCode::Oem1 => modifiers.handle_accen('ø', 'Ø'), - KeyCode::Oem3 => modifiers.handle_accen('æ', 'Æ'), + KeyCode::Oem7 => modifiers.handle_symbol2(QUO, '*'), + KeyCode::Oem1 => modifiers.handle_letter2('ø', 'Ø'), + KeyCode::Oem3 => modifiers.handle_letter2('æ', 'Æ'), // ========= Row 5 (ZXCV) ========= - KeyCode::Oem5 => modifiers.handle_shift('<', '>'), - KeyCode::M => modifiers.handle_alalt('M', 'µ', 'µ', handle_ctrl), - KeyCode::OemComma => modifiers.handle_shift(',', ';'), - KeyCode::OemPeriod => modifiers.handle_shift('.', ':'), - KeyCode::Oem2 => modifiers.handle_shift('-', '_'), - KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), + KeyCode::Oem5 => modifiers.handle_symbol2('<', '>'), + KeyCode::M => modifiers.handle_ascii_3('M', 'µ', handle_ctrl), + KeyCode::OemComma => modifiers.handle_symbol2(',', ';'), + KeyCode::OemPeriod => modifiers.handle_symbol2('.', ':'), + KeyCode::Oem2 => modifiers.handle_symbol2('-', '_'), // ========= Row 6 (modifers and space bar) ========= + KeyCode::NumpadPeriod if modifiers.numlock => DecodedKey::Unicode(','), + // ========= Fallback ========= e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } diff --git a/src/layouts/uk105.rs b/src/layouts/uk105.rs index b5c3875..88812ab 100644 --- a/src/layouts/uk105.rs +++ b/src/layouts/uk105.rs @@ -147,18 +147,18 @@ impl KeyboardLayout for Uk105Key { handle_ctrl: HandleControl, ) -> DecodedKey { match keycode { - KeyCode::Key2 => modifiers.handle_shift('2', '"'), - KeyCode::Key3 => modifiers.handle_shift('3', '£'), - KeyCode::Key4 => modifiers.handle_altsh('4', '$', '€'), - KeyCode::Oem3 => modifiers.handle_shift(QUO, '@'), - KeyCode::Oem5 => modifiers.handle_shift(SLS, '|'), - KeyCode::Oem7 => modifiers.handle_shift('#', '~'), - KeyCode::Oem8 => modifiers.handle_altsh('`', '¬', '¦'), - KeyCode::E => modifiers.handle_alalt('E', 'é', 'É', handle_ctrl), - KeyCode::U => modifiers.handle_alalt('U', 'ú', 'Ú', handle_ctrl), - KeyCode::I => modifiers.handle_alalt('I', 'í', 'Í', handle_ctrl), - KeyCode::O => modifiers.handle_alalt('O', 'ó', 'Ó', handle_ctrl), - KeyCode::A => modifiers.handle_alalt('A', 'á', 'Á', handle_ctrl), + KeyCode::Key2 => modifiers.handle_symbol2('2', '"'), + KeyCode::Key3 => modifiers.handle_symbol2('3', '£'), + KeyCode::Key4 => modifiers.handle_symbol3('4', '$', '€'), + KeyCode::Oem3 => modifiers.handle_symbol2(QUO, '@'), + KeyCode::Oem5 => modifiers.handle_symbol2(SLS, '|'), + KeyCode::Oem7 => modifiers.handle_symbol2('#', '~'), + KeyCode::Oem8 => modifiers.handle_symbol3('`', '¬', '¦'), + KeyCode::E => modifiers.handle_ascii_4('E', 'é', 'É', handle_ctrl), + KeyCode::U => modifiers.handle_ascii_4('U', 'ú', 'Ú', handle_ctrl), + KeyCode::I => modifiers.handle_ascii_4('I', 'í', 'Í', handle_ctrl), + KeyCode::O => modifiers.handle_ascii_4('O', 'ó', 'Ó', handle_ctrl), + KeyCode::A => modifiers.handle_ascii_4('A', 'á', 'Á', handle_ctrl), e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl), } } diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs index cbb4bd0..c9e0b64 100644 --- a/src/layouts/us104.rs +++ b/src/layouts/us104.rs @@ -146,60 +146,60 @@ impl KeyboardLayout for Us104Key { ) -> DecodedKey { match keycode { // ========= Row 2 (the numbers) ========= - KeyCode::Oem8 => modifiers.handle_shift('`', '~'), + KeyCode::Oem8 => modifiers.handle_symbol2('`', '~'), KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Key1 => modifiers.handle_shift('1', '!'), - KeyCode::Key2 => modifiers.handle_shift('2', '@'), - KeyCode::Key3 => modifiers.handle_shift('3', '#'), - KeyCode::Key4 => modifiers.handle_shift('4', '$'), - KeyCode::Key5 => modifiers.handle_shift('5', '%'), - KeyCode::Key6 => modifiers.handle_shift('6', '^'), - KeyCode::Key7 => modifiers.handle_shift('7', '&'), - KeyCode::Key8 => modifiers.handle_shift('8', '*'), - KeyCode::Key9 => modifiers.handle_shift('9', '('), - KeyCode::Key0 => modifiers.handle_shift('0', ')'), - KeyCode::OemMinus => modifiers.handle_shift('-', '_'), - KeyCode::OemPlus => modifiers.handle_shift('=', '+'), + KeyCode::Key1 => modifiers.handle_symbol2('1', '!'), + KeyCode::Key2 => modifiers.handle_symbol2('2', '@'), + KeyCode::Key3 => modifiers.handle_symbol2('3', '#'), + KeyCode::Key4 => modifiers.handle_symbol2('4', '$'), + KeyCode::Key5 => modifiers.handle_symbol2('5', '%'), + KeyCode::Key6 => modifiers.handle_symbol2('6', '^'), + KeyCode::Key7 => modifiers.handle_symbol2('7', '&'), + KeyCode::Key8 => modifiers.handle_symbol2('8', '*'), + KeyCode::Key9 => modifiers.handle_symbol2('9', '('), + KeyCode::Key0 => modifiers.handle_symbol2('0', ')'), + KeyCode::OemMinus => modifiers.handle_symbol2('-', '_'), + KeyCode::OemPlus => modifiers.handle_symbol2('=', '+'), KeyCode::Backspace => DecodedKey::Unicode('\u{0008}'), // ========= Row 3 (QWERTY) ========= KeyCode::Tab => DecodedKey::Unicode('\u{0009}'), - KeyCode::Q => modifiers.handle_alpha('Q', handle_ctrl), - KeyCode::W => modifiers.handle_alpha('W', handle_ctrl), - KeyCode::E => modifiers.handle_alpha('E', handle_ctrl), - KeyCode::R => modifiers.handle_alpha('R', handle_ctrl), - KeyCode::T => modifiers.handle_alpha('T', handle_ctrl), - KeyCode::Y => modifiers.handle_alpha('Y', handle_ctrl), - KeyCode::U => modifiers.handle_alpha('U', handle_ctrl), - KeyCode::I => modifiers.handle_alpha('I', handle_ctrl), - KeyCode::O => modifiers.handle_alpha('O', handle_ctrl), - KeyCode::P => modifiers.handle_alpha('P', handle_ctrl), - KeyCode::Oem4 => modifiers.handle_shift('[', '{'), - KeyCode::Oem6 => modifiers.handle_shift(']', '}'), - KeyCode::Oem7 => modifiers.handle_shift(SLS, '|'), + KeyCode::Q => modifiers.handle_ascii_2('Q', handle_ctrl), + KeyCode::W => modifiers.handle_ascii_2('W', handle_ctrl), + KeyCode::E => modifiers.handle_ascii_2('E', handle_ctrl), + KeyCode::R => modifiers.handle_ascii_2('R', handle_ctrl), + KeyCode::T => modifiers.handle_ascii_2('T', handle_ctrl), + KeyCode::Y => modifiers.handle_ascii_2('Y', handle_ctrl), + KeyCode::U => modifiers.handle_ascii_2('U', handle_ctrl), + KeyCode::I => modifiers.handle_ascii_2('I', handle_ctrl), + KeyCode::O => modifiers.handle_ascii_2('O', handle_ctrl), + KeyCode::P => modifiers.handle_ascii_2('P', handle_ctrl), + KeyCode::Oem4 => modifiers.handle_symbol2('[', '{'), + KeyCode::Oem6 => modifiers.handle_symbol2(']', '}'), + KeyCode::Oem7 => modifiers.handle_symbol2(SLS, '|'), // ========= Row 4 (ASDFG) ========= - KeyCode::A => modifiers.handle_alpha('A', handle_ctrl), - KeyCode::S => modifiers.handle_alpha('S', handle_ctrl), - KeyCode::D => modifiers.handle_alpha('D', handle_ctrl), - KeyCode::F => modifiers.handle_alpha('F', handle_ctrl), - KeyCode::G => modifiers.handle_alpha('G', handle_ctrl), - KeyCode::H => modifiers.handle_alpha('H', handle_ctrl), - KeyCode::J => modifiers.handle_alpha('J', handle_ctrl), - KeyCode::K => modifiers.handle_alpha('K', handle_ctrl), - KeyCode::L => modifiers.handle_alpha('L', handle_ctrl), - KeyCode::Oem1 => modifiers.handle_shift(';', ':'), - KeyCode::Oem3 => modifiers.handle_shift(QUO, '"'), + KeyCode::A => modifiers.handle_ascii_2('A', handle_ctrl), + KeyCode::S => modifiers.handle_ascii_2('S', handle_ctrl), + KeyCode::D => modifiers.handle_ascii_2('D', handle_ctrl), + KeyCode::F => modifiers.handle_ascii_2('F', handle_ctrl), + KeyCode::G => modifiers.handle_ascii_2('G', handle_ctrl), + KeyCode::H => modifiers.handle_ascii_2('H', handle_ctrl), + KeyCode::J => modifiers.handle_ascii_2('J', handle_ctrl), + KeyCode::K => modifiers.handle_ascii_2('K', handle_ctrl), + KeyCode::L => modifiers.handle_ascii_2('L', handle_ctrl), + KeyCode::Oem1 => modifiers.handle_symbol2(';', ':'), + KeyCode::Oem3 => modifiers.handle_symbol2(QUO, '"'), KeyCode::Return => DecodedKey::Unicode('\u{000A}'), // ========= Row 5 (ZXCVB) ========= - KeyCode::Z => modifiers.handle_alpha('Z', handle_ctrl), - KeyCode::X => modifiers.handle_alpha('X', handle_ctrl), - KeyCode::C => modifiers.handle_alpha('C', handle_ctrl), - KeyCode::V => modifiers.handle_alpha('V', handle_ctrl), - KeyCode::B => modifiers.handle_alpha('B', handle_ctrl), - KeyCode::N => modifiers.handle_alpha('N', handle_ctrl), - KeyCode::M => modifiers.handle_alpha('M', handle_ctrl), - KeyCode::OemComma => modifiers.handle_shift(',', '<'), - KeyCode::OemPeriod => modifiers.handle_shift('.', '>'), - KeyCode::Oem2 => modifiers.handle_shift('/', '?'), + KeyCode::Z => modifiers.handle_ascii_2('Z', handle_ctrl), + KeyCode::X => modifiers.handle_ascii_2('X', handle_ctrl), + KeyCode::C => modifiers.handle_ascii_2('C', handle_ctrl), + KeyCode::V => modifiers.handle_ascii_2('V', handle_ctrl), + KeyCode::B => modifiers.handle_ascii_2('B', handle_ctrl), + KeyCode::N => modifiers.handle_ascii_2('N', handle_ctrl), + KeyCode::M => modifiers.handle_ascii_2('M', handle_ctrl), + KeyCode::OemComma => modifiers.handle_symbol2(',', '<'), + KeyCode::OemPeriod => modifiers.handle_symbol2('.', '>'), + KeyCode::Oem2 => modifiers.handle_symbol2('/', '?'), // ========= Unicode Specials ========= KeyCode::Spacebar => DecodedKey::Unicode(' '), KeyCode::Delete => DecodedKey::Unicode('\u{007f}'), @@ -207,18 +207,18 @@ impl KeyboardLayout for Us104Key { KeyCode::NumpadDivide => DecodedKey::Unicode('/'), KeyCode::NumpadMultiply => DecodedKey::Unicode('*'), KeyCode::NumpadSubtract => DecodedKey::Unicode('-'), - KeyCode::Numpad7 => modifiers.handle_numpad('7', KeyCode::Home), - KeyCode::Numpad8 => modifiers.handle_numpad('8', KeyCode::ArrowUp), - KeyCode::Numpad9 => modifiers.handle_numpad('9', KeyCode::PageUp), + KeyCode::Numpad7 => modifiers.handle_num_pad('7', KeyCode::Home), + KeyCode::Numpad8 => modifiers.handle_num_pad('8', KeyCode::ArrowUp), + KeyCode::Numpad9 => modifiers.handle_num_pad('9', KeyCode::PageUp), KeyCode::NumpadAdd => DecodedKey::Unicode('+'), - KeyCode::Numpad4 => modifiers.handle_numpad('4', KeyCode::ArrowLeft), + KeyCode::Numpad4 => modifiers.handle_num_pad('4', KeyCode::ArrowLeft), KeyCode::Numpad5 => DecodedKey::Unicode('5'), - KeyCode::Numpad6 => modifiers.handle_numpad('6', KeyCode::ArrowRight), - KeyCode::Numpad1 => modifiers.handle_numpad('1', KeyCode::End), - KeyCode::Numpad2 => modifiers.handle_numpad('2', KeyCode::ArrowDown), - KeyCode::Numpad3 => modifiers.handle_numpad('3', KeyCode::PageDown), - KeyCode::Numpad0 => modifiers.handle_numpad('0', KeyCode::Insert), - KeyCode::NumpadPeriod => modifiers.handle_numpad_pair('.', '\u{007f}'), + KeyCode::Numpad6 => modifiers.handle_num_pad('6', KeyCode::ArrowRight), + KeyCode::Numpad1 => modifiers.handle_num_pad('1', KeyCode::End), + KeyCode::Numpad2 => modifiers.handle_num_pad('2', KeyCode::ArrowDown), + KeyCode::Numpad3 => modifiers.handle_num_pad('3', KeyCode::PageDown), + KeyCode::Numpad0 => modifiers.handle_num_pad('0', KeyCode::Insert), + KeyCode::NumpadPeriod => modifiers.handle_num_del('.', '\u{007f}'), KeyCode::NumpadEnter => DecodedKey::Unicode('\u{000A}'), // ========= Fallback ========= k => DecodedKey::RawKey(k), @@ -311,7 +311,7 @@ mod test { rshift: false, }; assert_eq!( - modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), DecodedKey::Unicode('a') ); } @@ -330,7 +330,7 @@ mod test { rshift: false, }; assert_eq!( - modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), DecodedKey::Unicode('A') ); } @@ -349,7 +349,7 @@ mod test { rshift: false, }; assert_eq!( - modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), DecodedKey::Unicode('A') ); } @@ -368,7 +368,7 @@ mod test { rshift: false, }; assert_eq!( - modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), DecodedKey::Unicode('a') ); } @@ -387,7 +387,7 @@ mod test { rshift: false, }; assert_eq!( - modifiers.handle_alpha('A', HandleControl::MapLettersToUnicode), + modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode), DecodedKey::Unicode('\u{0001}') ); } diff --git a/src/lib.rs b/src/lib.rs index 8842de8..4e9937a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -742,12 +742,16 @@ pub struct Modifiers { } impl Modifiers { - /// Handle the standard letters + /// Handle letter keys with standard ASCII 'A'..'Z' keycaps. /// - /// ONLY pass 'A'..='Z' - nothing else - pub(crate) fn handle_alpha(&self, letter: char, handle_control: HandleControl) -> DecodedKey { + /// ONLY pass 'A'..='Z' - nothing else. + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. + pub(crate) fn handle_ascii_2(&self, letter: char, handle_ctrl: HandleControl) -> DecodedKey { debug_assert!(letter.is_ascii_uppercase()); - if handle_control == HandleControl::MapLettersToUnicode && self.is_ctrl() { + if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { // Get a Control code, like Ctrl+C => U+0003 const ASCII_UPPERCASE_START_OFFSET: u8 = 64; DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char) @@ -761,21 +765,83 @@ impl Modifiers { } } - /// Handle the standard letters, with an Alt-Gr alternative + /// Handle letter keys with just two variants (lower and upper case). + /// + /// Designed for non-ASCII keys, this does not produce control codes. + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. + /// + /// We make you pass both upper and lower case variants to avoid having to + /// use the `char::to_lowercase` function. + pub(crate) fn handle_letter2(&self, letter_lower: char, letter_upper: char) -> DecodedKey { + if self.is_caps() { + DecodedKey::Unicode(letter_upper) + } else { + DecodedKey::Unicode(letter_lower) + } + } + + /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols. + /// + /// ONLY pass 'A'..='Z' - nothing else + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. Or, if AltGr is held, you get either the alternate + /// character. Useful if your alternate character is e.g. `€`. + /// + /// We make you pass both upper and lower case variants to avoid having to + /// use the `char::to_lowercase` function. + pub(crate) fn handle_ascii_3( + &self, + letter_upper: char, + alt: char, + handle_ctrl: HandleControl, + ) -> DecodedKey { + debug_assert!(letter_upper.is_ascii_uppercase()); + if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { + // Get a Control code, like Ctrl+C => U+0003 + const ASCII_UPPERCASE_START_OFFSET: u8 = 64; + DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + } else if self.ralt { + // Alternate character + DecodedKey::Unicode(alt) + } else if self.is_caps() { + // Capital letter + DecodedKey::Unicode(letter_upper) + } else { + // Lowercase letter + const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; + DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) + } + } + + /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols. /// /// ONLY pass 'A'..='Z' - nothing else - pub(crate) fn handle_alalt( + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. Or, if AltGr is held, you get either the upper or + /// lower case alternate character. Useful if your alternate character is + /// e.g. `é` (or `É` if Shift or Caps Lock is enabled). + /// + /// We make you pass both upper and lower case variants to avoid having to + /// use the `char::to_lowercase` function. + pub(crate) fn handle_ascii_4( &self, - letter: char, + letter_upper: char, alt_letter_lower: char, alt_letter_upper: char, - handle_control: HandleControl, + handle_ctrl: HandleControl, ) -> DecodedKey { - debug_assert!(letter.is_ascii_uppercase()); - if handle_control == HandleControl::MapLettersToUnicode && self.is_ctrl() { + debug_assert!(letter_upper.is_ascii_uppercase()); + if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { // Get a Control code, like Ctrl+C => U+0003 const ASCII_UPPERCASE_START_OFFSET: u8 = 64; - DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char) } else if self.ralt && self.is_caps() { // Capital letter DecodedKey::Unicode(alt_letter_upper) @@ -784,25 +850,16 @@ impl Modifiers { DecodedKey::Unicode(alt_letter_lower) } else if self.is_caps() { // Capital letter - DecodedKey::Unicode(letter) + DecodedKey::Unicode(letter_upper) } else { // Lowercase letter const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; - DecodedKey::Unicode((letter as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) - } - } - - /// Handle accented letters - pub(crate) fn handle_accen(&self, lower: char, upper: char) -> DecodedKey { - if self.is_caps() { - DecodedKey::Unicode(upper) - } else { - DecodedKey::Unicode(lower) + DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) } } /// Handle numpad keys which are either a character or a raw key - pub(crate) fn handle_numpad(&self, letter: char, key: KeyCode) -> DecodedKey { + pub(crate) fn handle_num_pad(&self, letter: char, key: KeyCode) -> DecodedKey { if self.numlock { DecodedKey::Unicode(letter) } else { @@ -810,8 +867,10 @@ impl Modifiers { } } - /// Handle numpad keys which are one of two characters - pub(crate) fn handle_numpad_pair(&self, letter: char, other: char) -> DecodedKey { + /// Handle numpad keys which produce a pair of characters + /// + /// This is usually just for Numpad Delete. + pub(crate) fn handle_num_del(&self, letter: char, other: char) -> DecodedKey { if self.numlock { DecodedKey::Unicode(letter) } else { @@ -820,7 +879,9 @@ impl Modifiers { } /// Handle standard two-glyph shifted keys - pub(crate) fn handle_shift(&self, plain: char, shifted: char) -> DecodedKey { + /// + /// Caps Lock is ignored here - only shift matters. + pub(crate) fn handle_symbol2(&self, plain: char, shifted: char) -> DecodedKey { if self.is_shifted() { DecodedKey::Unicode(shifted) } else { @@ -829,7 +890,10 @@ impl Modifiers { } /// Handle standard three-glyph shifted keys - pub(crate) fn handle_altsh(&self, plain: char, shifted: char, alt: char) -> DecodedKey { + /// + /// Caps Lock is ignored here - only shift matters. AltGr gets you the + /// alternate letter, regardless of Shift status. + pub(crate) fn handle_symbol3(&self, plain: char, shifted: char, alt: char) -> DecodedKey { if self.is_altgr() { DecodedKey::Unicode(alt) } else if self.is_shifted() { From 8a6539c184a46c64582d8bdb7ce85fe4f61138b0 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 5 Jun 2025 20:28:35 +0100 Subject: [PATCH 12/18] Update Jis109 layout --- examples/print_keyboard.rs | 111 ++++++++++++- src/layouts/jis109.rs | 317 +++++++++++++++++++------------------ 2 files changed, 266 insertions(+), 162 deletions(-) diff --git a/examples/print_keyboard.rs b/examples/print_keyboard.rs index 67949d9..0bda4ac 100644 --- a/examples/print_keyboard.rs +++ b/examples/print_keyboard.rs @@ -32,10 +32,10 @@ fn main() { println!("/// # FiSe105Key"); println!("///"); show_kb(&pc_keyboard::layouts::FiSe105Key); - // println!("/// ****************************************"); - // println!("/// # Jis109Key"); - // println!("///"); - // show_kb(&pc_keyboard::layouts::Jis109Key); + println!("/// ****************************************"); + println!("/// # Jis109Key"); + println!("///"); + show_kb(&pc_keyboard::layouts::Jis109Key); println!("/// ****************************************"); println!("/// # No105Key"); println!("///"); @@ -96,7 +96,6 @@ fn show_kb(layout: &dyn KeyboardLayout) { fn show_kb_modifiers(layout: &dyn KeyboardLayout, modifiers: &Modifiers) { let mut map = Map::new(modifiers); map.insert("esc", KeyCode::Escape, layout); - map.insert("oem8", KeyCode::Oem8, layout); map.insert("key1", KeyCode::Key1, layout); map.insert("key2", KeyCode::Key2, layout); map.insert("key3", KeyCode::Key3, layout); @@ -166,14 +165,18 @@ fn show_kb_modifiers(layout: &dyn KeyboardLayout, modifiers: &Modifiers) { map.insert("m", KeyCode::M, layout); match layout.get_physical() { pc_keyboard::PhysicalKeyboard::Iso => { + map.insert("oem8", KeyCode::Oem8, layout); map.insert("oem5", KeyCode::Oem5, layout); map.print_iso(); } pc_keyboard::PhysicalKeyboard::Ansi => { + map.insert("oem8", KeyCode::Oem8, layout); map.print_ansi(); } pc_keyboard::PhysicalKeyboard::Jis => { - todo!() + map.insert("oem12", KeyCode::Oem12, layout); + map.insert("oem13", KeyCode::Oem13, layout); + map.print_jis(); } } } @@ -401,6 +404,102 @@ impl Map { /// │ │ │ │ {sp} │ │ │ │ │ │ │ │ │ │{n0} │{np}│ │ /// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ /// ``` +///"# + ); + } + + fn print_jis(&self) { + let es = self.get("esc"); + let k1 = self.get("key1"); + let k2 = self.get("key2"); + let k3 = self.get("key3"); + let k4 = self.get("key4"); + let k5 = self.get("key5"); + let k6 = self.get("key6"); + let k7 = self.get("key7"); + let k8 = self.get("key8"); + let k9 = self.get("key9"); + let k0 = self.get("key0"); + let om = self.get("oem_minus"); + let ol = self.get("oem_plus"); + let bs = self.get("backspace"); + let nd = self.get("numpad_divide"); + let nm = self.get("numpad_multiply"); + let ns = self.get("numpad_subtract"); + let tb = self.get("tab"); + let o4 = self.get("oem4"); + let o6 = self.get("oem6"); + let o7 = self.get("oem7"); + let de = self.get("delete"); + let n7 = self.get("numpad7"); + let n8 = self.get("numpad8"); + let n9 = self.get("numpad9"); + let nl = self.get("numpadl"); + let o1 = self.get("oem1"); + let o3 = self.get("oem3"); + let en = self.get("enter"); + let n4 = self.get("numpad4"); + let n5 = self.get("numpad5"); + let n6 = self.get("numpad6"); + let oc = self.get("oem_comma"); + let op = self.get("oem_period"); + let o2 = self.get("oem2"); + let n1 = self.get("numpad1"); + let n2 = self.get("numpad2"); + let n3 = self.get("numpad3"); + let ne = self.get("numpade"); + let sp = self.get("space"); + let n0 = self.get("numpad0"); + let np = self.get("numpad_period"); + let od = self.get("oem12"); + let oe = self.get("oem13"); + + let kq = self.get("q"); + let kw = self.get("w"); + let ke = self.get("e"); + let kr = self.get("r"); + let kt = self.get("t"); + let ky = self.get("y"); + let ku = self.get("u"); + let ki = self.get("i"); + let ko = self.get("o"); + let kp = self.get("p"); + let ka = self.get("a"); + let ks = self.get("s"); + let kd = self.get("d"); + let kf = self.get("f"); + let kg = self.get("g"); + let kh = self.get("h"); + let kj = self.get("j"); + let kk = self.get("k"); + let kl = self.get("l"); + let kz = self.get("z"); + let kx = self.get("x"); + let kc = self.get("c"); + let kv = self.get("v"); + let kb = self.get("b"); + let kn = self.get("n"); + let km = self.get("m"); + + println!( + r#"/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │{es}│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │{k1}│{k2}│{k3}│{k4}│{k5}│{k6}│{k7}│{k8}│{k9}│{k0}│{om}│{ol}│{oe}│{bs}│ │ │ │ │ │ │{nd}│{nm}│{ns}│ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │{tb} │{kq}│{kw}│{ke}│{kr}│{kt}│{ky}│{ku}│{ki}│{ko}│{kp}│{o4}│{o6}│ {en} │ │{de}│ │ │ │{n7}│{n8}│{n9}│ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤{nl}│ +/// │ │{ka}│{ks}│{kd}│{kf}│{kg}│{kh}│{kj}│{kk}│{kl}│{o1}│{o3}│{o7}│ │ │{n4}│{n5}│{n6}│ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │{kz}│{kx}│{kc}│{kv}│{kb}│{kn}│{km}│{oc}│{op}│{o2}│{od} │ │ │ │ │{n1}│{n2}│{n3}│ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤{ne}│ +/// │ │ │ │ │ {sp} │ │ │ │ │ │ │ │ │ │ │{n0} │{np}│ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` ///"# ); } diff --git a/src/layouts/jis109.rs b/src/layouts/jis109.rs index 7533806..e4b1f43 100644 --- a/src/layouts/jis109.rs +++ b/src/layouts/jis109.rs @@ -1,6 +1,8 @@ //! JIS keyboard support -use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard}; +use crate::{ + DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS, +}; /// A standard Japan 106-key (or 109-key including Windows keys) keyboard. /// @@ -8,9 +10,137 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, Physi /// /// We used as a /// reference. +/// +/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We +/// show either a Unicode glyph, or a hex number if the glyph isn't a +/// printable character. Blank spaces are passed through as +/// [`DecodedKey::RawKey`]. +/// +/// Run the `print_keyboard` example to re-generate these images. +/// +/// ## Unmodified +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Caps Lock +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shifted +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │ ! │ " │ # │ $ │ % │ & │ ' │ ( │ ) │ ~ │ = │ ¯ │ | │0008│ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ` │ { │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ + │ * │ } │ │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Control +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ^ │ ¥ │0008│ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ @ │ [ │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ : │ ] │ │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ \ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` +/// +/// ## Shift AltGr +/// +/// ```text +/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐ +/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘ +/// +/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐ +/// │ │ ! │ " │ # │ $ │ % │ & │ ' │ ( │ ) │ ~ │ = │ ¯ │ | │0008│ │ │ │ │ │ │ / │ * │ - │ +/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤ +/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ` │ { │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │ +/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │ +/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ + │ * │ } │ │ │ 4 │ 5 │ 6 │ │ +/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┼───────┤ ┌────┐ ├────┼────┼────┼────┤ +/// │ │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ _ │ │ │ │ │ 1 │ 2 │ 3 │ │ +/// ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│ +/// │ │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ │ 0 │ . │ │ +/// └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘ +/// ``` pub struct Jis109Key; impl KeyboardLayout for Jis109Key { + #[rustfmt::skip] fn map_keycode( &self, keycode: KeyCode, @@ -18,161 +148,36 @@ impl KeyboardLayout for Jis109Key { handle_ctrl: HandleControl, ) -> DecodedKey { match keycode { - KeyCode::Oem8 => { - // hankaku/zenkaku/kanji - DecodedKey::RawKey(KeyCode::Oem8) - } - KeyCode::Escape => DecodedKey::Unicode('\u{001B}'), - KeyCode::Key1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('!') - } else { - DecodedKey::Unicode('1') - } - } - KeyCode::Key2 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('"') - } else { - DecodedKey::Unicode('2') - } - } - KeyCode::Key3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('#') - } else { - DecodedKey::Unicode('3') - } - } - KeyCode::Key4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('$') - } else { - DecodedKey::Unicode('4') - } - } - KeyCode::Key5 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('%') - } else { - DecodedKey::Unicode('5') - } - } - KeyCode::Key6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('&') - } else { - DecodedKey::Unicode('6') - } - } - KeyCode::Key7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('\'') - } else { - DecodedKey::Unicode('7') - } - } - KeyCode::Key8 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('(') - } else { - DecodedKey::Unicode('8') - } - } - KeyCode::Key9 => { - if modifiers.is_shifted() { - DecodedKey::Unicode(')') - } else { - DecodedKey::Unicode('9') - } - } - KeyCode::Key0 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('~') - } else { - DecodedKey::Unicode('0') - } - } - KeyCode::OemMinus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('=') - } else { - DecodedKey::Unicode('-') - } - } - KeyCode::OemPlus => { - if modifiers.is_shifted() { - DecodedKey::Unicode('¯') - } else { - DecodedKey::Unicode('^') - } - } - KeyCode::Oem4 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('`') - } else { - DecodedKey::Unicode('@') - } - } - KeyCode::Oem6 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('{') - } else { - DecodedKey::Unicode('[') - } - } - KeyCode::Oem7 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('}') - } else { - DecodedKey::Unicode(']') - } - } - KeyCode::Oem1 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('+') - } else { - DecodedKey::Unicode(';') - } - } - KeyCode::Oem3 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('*') - } else { - DecodedKey::Unicode(':') - } - } - KeyCode::Oem9 => { - // Muhenkan - DecodedKey::RawKey(keycode) - } - KeyCode::Oem10 => { - // Henkan/Zenkouho - DecodedKey::RawKey(keycode) - } - KeyCode::Oem11 => { - // Hiragana/Katakana - DecodedKey::RawKey(keycode) - } - KeyCode::Oem12 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('_') - } else { - DecodedKey::Unicode('\\') - } - } - KeyCode::Oem13 => { - if modifiers.is_shifted() { - DecodedKey::Unicode('|') - } else { - DecodedKey::Unicode('¥') - } - } - - e => { - let us = super::Us104Key; - us.map_keycode(e, modifiers, handle_ctrl) - } + // ========= Row 2 (the numbers) ========= + // hankaku/zenkaku/kanji + KeyCode::Oem8 => DecodedKey::RawKey(keycode), + KeyCode::Key2 => modifiers.handle_symbol2('2', '"'), + KeyCode::Key6 => modifiers.handle_symbol2('6', '&'), + KeyCode::Key7 => modifiers.handle_symbol2('7', QUO), + KeyCode::Key8 => modifiers.handle_symbol2('8', '('), + KeyCode::Key9 => modifiers.handle_symbol2('9', ')'), + KeyCode::Key0 => modifiers.handle_symbol2('0', '~'), + KeyCode::OemMinus => modifiers.handle_symbol2('-', '='), + KeyCode::OemPlus => modifiers.handle_symbol2('^', '¯'), + KeyCode::Oem13 => modifiers.handle_symbol2('¥', '|'), + // ========= Row 3 (QWERTY) ========= + KeyCode::Oem4 => modifiers.handle_symbol2('@', '`'), + KeyCode::Oem6 => modifiers.handle_symbol2('[', '{'), + // ========= Row 4 (ASDFG) ========= + KeyCode::Oem1 => modifiers.handle_symbol2(';', '+'), + KeyCode::Oem3 => modifiers.handle_symbol2(':', '*'), + KeyCode::Oem7 => modifiers.handle_symbol2(']', '}'), + // ========= Row 5 (ZXCVB) ========= + KeyCode::Oem12 => modifiers.handle_symbol2(SLS, '_'), + // ========= Modifiers ========= + // Muhenkan + KeyCode::Oem9 => DecodedKey::RawKey(keycode), + // Henkan/Zenkouho + KeyCode::Oem10 => DecodedKey::RawKey(keycode), + // Hiragana/Katakana + KeyCode::Oem11 => DecodedKey::RawKey(keycode), + // ========= Fallback ========= + e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl) } } From 74c87f1040a6d7b26f4e1b86108d75b7c6510e58 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 12 Jun 2025 20:02:07 +0100 Subject: [PATCH 13/18] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7659fbd..d5c6520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * Fix Ctrl combination handling for Colemak and De105Key layouts * Fix 102/105-key German layout: Add missing Alt-Gr combinations +* Added tool to print keyboard layouts as ASCII-art +* Cleaned up how layouts are implemented ## v0.8.0 (13 Sep 2024) From e035de7bc0eb816c182cca3aac10c38a4c1f302e Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 12 Jun 2025 20:02:23 +0100 Subject: [PATCH 14/18] Set rust-version to match our MSRV. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index fccb2fd..5845a0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,6 @@ categories = ["embedded", "no-std"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-embedded-community/pc-keyboard.git" edition = "2021" +rust-version = "1.61" [dependencies] From 21abaf8129914797e3fdda5ccb76f34b3c1da531 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 12 Jun 2025 20:02:43 +0100 Subject: [PATCH 15/18] People on Github might want to see docs for the version in Github. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e79a55e..e85dee9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A simple driver for handling PC keyboards, with both Scancode Set 1 (when running on a PC) and Scancode Set 2 support (when reading a PS/2 keyboard output directly). -See for documentation. +See for documentation, or read [`src/lib.rs`](./src/lib.rs). ## Minimum Supported Rust Version (MSRV) From e353a2778613f5eb0cb3f8a841550785bede5bef Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 12 Jun 2025 20:02:56 +0100 Subject: [PATCH 16/18] Remove weird leftovers in lib.rs docs --- src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4e9937a..8fa734e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,6 @@ //! Supports PS/2 Scan Code Set 1 and 2, on a variety of keyboard layouts. See //! [the OSDev Wiki](https://wiki.osdev.org/PS/2_Keyboard). //! -//! There is also [`Keyboard`] which combines the above three functions into a single object. -//! //! ## Supports: //! //! - Scancode Set 1 (from the i8042 PC keyboard controller) @@ -51,8 +49,6 @@ //! //! See the [`examples`](./examples) folder for more details. //! -//! ## [Documentation](https://docs.rs/crate/pc-keyboard) -//! //! ## Keycodes //! //! This crate uses symbolic keycodes to abstract over Scancode Set 1 and From e2ba180cd78536f4f2d8d56c92378c33cc17090c Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 12 Jun 2025 20:39:02 +0100 Subject: [PATCH 17/18] Move code block where it belongs --- src/lib.rs | 324 ++++++++++++++++++++++++++--------------------------- 1 file changed, 161 insertions(+), 163 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8fa734e..396eaeb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -737,169 +737,6 @@ pub struct Modifiers { pub rctrl2: bool, } -impl Modifiers { - /// Handle letter keys with standard ASCII 'A'..'Z' keycaps. - /// - /// ONLY pass 'A'..='Z' - nothing else. - /// - /// You will get a `DecodedKey::Unicode` value with the appropriate lower - /// or upper case letter, according to state of the the Caps Lock and - /// Shift modifiers. - pub(crate) fn handle_ascii_2(&self, letter: char, handle_ctrl: HandleControl) -> DecodedKey { - debug_assert!(letter.is_ascii_uppercase()); - if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { - // Get a Control code, like Ctrl+C => U+0003 - const ASCII_UPPERCASE_START_OFFSET: u8 = 64; - DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char) - } else if self.is_caps() { - // Capital letter - DecodedKey::Unicode(letter) - } else { - // Lowercase letter - const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; - DecodedKey::Unicode((letter as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) - } - } - - /// Handle letter keys with just two variants (lower and upper case). - /// - /// Designed for non-ASCII keys, this does not produce control codes. - /// - /// You will get a `DecodedKey::Unicode` value with the appropriate lower - /// or upper case letter, according to state of the the Caps Lock and - /// Shift modifiers. - /// - /// We make you pass both upper and lower case variants to avoid having to - /// use the `char::to_lowercase` function. - pub(crate) fn handle_letter2(&self, letter_lower: char, letter_upper: char) -> DecodedKey { - if self.is_caps() { - DecodedKey::Unicode(letter_upper) - } else { - DecodedKey::Unicode(letter_lower) - } - } - - /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols. - /// - /// ONLY pass 'A'..='Z' - nothing else - /// - /// You will get a `DecodedKey::Unicode` value with the appropriate lower - /// or upper case letter, according to state of the the Caps Lock and - /// Shift modifiers. Or, if AltGr is held, you get either the alternate - /// character. Useful if your alternate character is e.g. `€`. - /// - /// We make you pass both upper and lower case variants to avoid having to - /// use the `char::to_lowercase` function. - pub(crate) fn handle_ascii_3( - &self, - letter_upper: char, - alt: char, - handle_ctrl: HandleControl, - ) -> DecodedKey { - debug_assert!(letter_upper.is_ascii_uppercase()); - if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { - // Get a Control code, like Ctrl+C => U+0003 - const ASCII_UPPERCASE_START_OFFSET: u8 = 64; - DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char) - } else if self.ralt { - // Alternate character - DecodedKey::Unicode(alt) - } else if self.is_caps() { - // Capital letter - DecodedKey::Unicode(letter_upper) - } else { - // Lowercase letter - const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; - DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) - } - } - - /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols. - /// - /// ONLY pass 'A'..='Z' - nothing else - /// - /// You will get a `DecodedKey::Unicode` value with the appropriate lower - /// or upper case letter, according to state of the the Caps Lock and - /// Shift modifiers. Or, if AltGr is held, you get either the upper or - /// lower case alternate character. Useful if your alternate character is - /// e.g. `é` (or `É` if Shift or Caps Lock is enabled). - /// - /// We make you pass both upper and lower case variants to avoid having to - /// use the `char::to_lowercase` function. - pub(crate) fn handle_ascii_4( - &self, - letter_upper: char, - alt_letter_lower: char, - alt_letter_upper: char, - handle_ctrl: HandleControl, - ) -> DecodedKey { - debug_assert!(letter_upper.is_ascii_uppercase()); - if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { - // Get a Control code, like Ctrl+C => U+0003 - const ASCII_UPPERCASE_START_OFFSET: u8 = 64; - DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char) - } else if self.ralt && self.is_caps() { - // Capital letter - DecodedKey::Unicode(alt_letter_upper) - } else if self.ralt { - // Lowercase letter - DecodedKey::Unicode(alt_letter_lower) - } else if self.is_caps() { - // Capital letter - DecodedKey::Unicode(letter_upper) - } else { - // Lowercase letter - const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; - DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) - } - } - - /// Handle numpad keys which are either a character or a raw key - pub(crate) fn handle_num_pad(&self, letter: char, key: KeyCode) -> DecodedKey { - if self.numlock { - DecodedKey::Unicode(letter) - } else { - DecodedKey::RawKey(key) - } - } - - /// Handle numpad keys which produce a pair of characters - /// - /// This is usually just for Numpad Delete. - pub(crate) fn handle_num_del(&self, letter: char, other: char) -> DecodedKey { - if self.numlock { - DecodedKey::Unicode(letter) - } else { - DecodedKey::Unicode(other) - } - } - - /// Handle standard two-glyph shifted keys - /// - /// Caps Lock is ignored here - only shift matters. - pub(crate) fn handle_symbol2(&self, plain: char, shifted: char) -> DecodedKey { - if self.is_shifted() { - DecodedKey::Unicode(shifted) - } else { - DecodedKey::Unicode(plain) - } - } - - /// Handle standard three-glyph shifted keys - /// - /// Caps Lock is ignored here - only shift matters. AltGr gets you the - /// alternate letter, regardless of Shift status. - pub(crate) fn handle_symbol3(&self, plain: char, shifted: char, alt: char) -> DecodedKey { - if self.is_altgr() { - DecodedKey::Unicode(alt) - } else if self.is_shifted() { - DecodedKey::Unicode(shifted) - } else { - DecodedKey::Unicode(plain) - } - } -} - /// Contains either a Unicode character, or a raw key code. #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum DecodedKey { @@ -1325,6 +1162,167 @@ impl Modifiers { pub const fn is_caps(&self) -> bool { self.is_shifted() ^ self.capslock } + + /// Handle letter keys with standard ASCII 'A'..'Z' keycaps. + /// + /// ONLY pass 'A'..='Z' - nothing else. + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. + pub(crate) fn handle_ascii_2(&self, letter: char, handle_ctrl: HandleControl) -> DecodedKey { + debug_assert!(letter.is_ascii_uppercase()); + if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { + // Get a Control code, like Ctrl+C => U+0003 + const ASCII_UPPERCASE_START_OFFSET: u8 = 64; + DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + } else if self.is_caps() { + // Capital letter + DecodedKey::Unicode(letter) + } else { + // Lowercase letter + const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; + DecodedKey::Unicode((letter as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) + } + } + + /// Handle letter keys with just two variants (lower and upper case). + /// + /// Designed for non-ASCII keys, this does not produce control codes. + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. + /// + /// We make you pass both upper and lower case variants to avoid having to + /// use the `char::to_lowercase` function. + pub(crate) fn handle_letter2(&self, letter_lower: char, letter_upper: char) -> DecodedKey { + if self.is_caps() { + DecodedKey::Unicode(letter_upper) + } else { + DecodedKey::Unicode(letter_lower) + } + } + + /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols. + /// + /// ONLY pass 'A'..='Z' - nothing else + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. Or, if AltGr is held, you get either the alternate + /// character. Useful if your alternate character is e.g. `€`. + /// + /// We make you pass both upper and lower case variants to avoid having to + /// use the `char::to_lowercase` function. + pub(crate) fn handle_ascii_3( + &self, + letter_upper: char, + alt: char, + handle_ctrl: HandleControl, + ) -> DecodedKey { + debug_assert!(letter_upper.is_ascii_uppercase()); + if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { + // Get a Control code, like Ctrl+C => U+0003 + const ASCII_UPPERCASE_START_OFFSET: u8 = 64; + DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + } else if self.ralt { + // Alternate character + DecodedKey::Unicode(alt) + } else if self.is_caps() { + // Capital letter + DecodedKey::Unicode(letter_upper) + } else { + // Lowercase letter + const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; + DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) + } + } + + /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols. + /// + /// ONLY pass 'A'..='Z' - nothing else + /// + /// You will get a `DecodedKey::Unicode` value with the appropriate lower + /// or upper case letter, according to state of the the Caps Lock and + /// Shift modifiers. Or, if AltGr is held, you get either the upper or + /// lower case alternate character. Useful if your alternate character is + /// e.g. `é` (or `É` if Shift or Caps Lock is enabled). + /// + /// We make you pass both upper and lower case variants to avoid having to + /// use the `char::to_lowercase` function. + pub(crate) fn handle_ascii_4( + &self, + letter_upper: char, + alt_letter_lower: char, + alt_letter_upper: char, + handle_ctrl: HandleControl, + ) -> DecodedKey { + debug_assert!(letter_upper.is_ascii_uppercase()); + if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() { + // Get a Control code, like Ctrl+C => U+0003 + const ASCII_UPPERCASE_START_OFFSET: u8 = 64; + DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char) + } else if self.ralt && self.is_caps() { + // Capital letter + DecodedKey::Unicode(alt_letter_upper) + } else if self.ralt { + // Lowercase letter + DecodedKey::Unicode(alt_letter_lower) + } else if self.is_caps() { + // Capital letter + DecodedKey::Unicode(letter_upper) + } else { + // Lowercase letter + const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32; + DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char) + } + } + + /// Handle numpad keys which are either a character or a raw key + pub(crate) fn handle_num_pad(&self, letter: char, key: KeyCode) -> DecodedKey { + if self.numlock { + DecodedKey::Unicode(letter) + } else { + DecodedKey::RawKey(key) + } + } + + /// Handle numpad keys which produce a pair of characters + /// + /// This is usually just for Numpad Delete. + pub(crate) fn handle_num_del(&self, letter: char, other: char) -> DecodedKey { + if self.numlock { + DecodedKey::Unicode(letter) + } else { + DecodedKey::Unicode(other) + } + } + + /// Handle standard two-glyph shifted keys + /// + /// Caps Lock is ignored here - only shift matters. + pub(crate) fn handle_symbol2(&self, plain: char, shifted: char) -> DecodedKey { + if self.is_shifted() { + DecodedKey::Unicode(shifted) + } else { + DecodedKey::Unicode(plain) + } + } + + /// Handle standard three-glyph shifted keys + /// + /// Caps Lock is ignored here - only shift matters. AltGr gets you the + /// alternate letter, regardless of Shift status. + pub(crate) fn handle_symbol3(&self, plain: char, shifted: char, alt: char) -> DecodedKey { + if self.is_altgr() { + DecodedKey::Unicode(alt) + } else if self.is_shifted() { + DecodedKey::Unicode(shifted) + } else { + DecodedKey::Unicode(plain) + } + } } // **************************************************************************** From b7f14c237de80f7f1e84eab6f255eed2c72ed5b6 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 12 Jun 2025 20:45:34 +0100 Subject: [PATCH 18/18] Remove leftover header --- src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 396eaeb..3f61270 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1136,12 +1136,6 @@ impl KeyEvent { } } -// **************************************************************************** -// -// Keyboard Layouts -// -// **************************************************************************** - impl Modifiers { pub const fn is_shifted(&self) -> bool { self.lshift | self.rshift