From cbbff2b1194857d15d61f97ea828b0991d44ab7a Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sat, 11 Feb 2023 00:06:06 +0000
Subject: [PATCH 1/9] Drew some ASCII art keyboards.

---
 README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/README.md b/README.md
index 18e5757..13abbaa 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,53 @@ 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.
+
+This is the mapping of `KeyCode` to a 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|
++-----+-----+-----+------------------------------+-----+-----+------+------+  +----+----+----+  +---------+----+----+
+```
+
+This is the mapping of `KeyCode` to a 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| Oem5   |  |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 `Oem7` key is missing on the 104-key ANSI layout.
+
 ## Minimum Supported Rust Version (MSRV)
 
 This crate is guaranteed to compile on stable Rust 1.61 and up. It might compile with older versions but that may change in any new patch release.

From c7d59333e664b44b9f0e4fc2bdd5c757d7c26311 Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sat, 11 Feb 2023 00:08:02 +0000
Subject: [PATCH 2/9] Corrected description of ANSI.

It's easier to see once you've got a diagram. The problem I was having was that other sides use *different* symbolic mappings for each scancode for ANSI and ISO. In our system, one scancode gives one symbolic key, regardless of whether you have ISO or ANSI.
---
 src/layouts/colemak.rs              | 2 +-
 src/layouts/dvorak104.rs            | 2 +-
 src/layouts/dvorak_programmer104.rs | 2 +-
 src/layouts/us104.rs                | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/layouts/colemak.rs b/src/layouts/colemak.rs
index d584251..ca4db0b 100644
--- a/src/layouts/colemak.rs
+++ b/src/layouts/colemak.rs
@@ -4,7 +4,7 @@ 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 Oem7 above (ANSI layout).
+/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
 pub struct Colemak;
 
 impl KeyboardLayout for Colemak {
diff --git a/src/layouts/dvorak104.rs b/src/layouts/dvorak104.rs
index 5339e1b..58e9c0f 100644
--- a/src/layouts/dvorak104.rs
+++ b/src/layouts/dvorak104.rs
@@ -4,7 +4,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
 
 /// A Dvorak 101-key (or 104-key including Windows keys) keyboard.
 ///
-/// Has a 1-row high Enter key, with Oem7 above (ANSI layout).
+/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
 pub struct Dvorak104Key;
 
 impl KeyboardLayout for Dvorak104Key {
diff --git a/src/layouts/dvorak_programmer104.rs b/src/layouts/dvorak_programmer104.rs
index d165ac9..7c3bf4c 100644
--- a/src/layouts/dvorak_programmer104.rs
+++ b/src/layouts/dvorak_programmer104.rs
@@ -4,7 +4,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
 
 /// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard.
 ///
-/// Has a 1-row high Enter key, with Oem7 above (ANSI layout).
+/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
 pub struct DVP104Key;
 
 impl KeyboardLayout for DVP104Key {
diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs
index b25b7a1..17fe9cf 100644
--- a/src/layouts/us104.rs
+++ b/src/layouts/us104.rs
@@ -4,7 +4,7 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
 
 /// A standard United States 101-key (or 104-key including Windows keys) keyboard.
 ///
-/// Has a 1-row high Enter key, with Oem7 above (ANSI layout).
+/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
 pub struct Us104Key;
 
 impl KeyboardLayout for Us104Key {

From e0324883a84470c8bd2dd2559fe874e1886db5fc Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sat, 11 Feb 2023 00:08:30 +0000
Subject: [PATCH 3/9] Add more tests to US and UK.

Just to be sure I've got this right, I go from scancodes to Unicode, based on various online tables.
---
 src/layouts/uk105.rs | 65 +++++++++++++++++++++++++++++++++++++++-
 src/layouts/us104.rs | 70 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/src/layouts/uk105.rs b/src/layouts/uk105.rs
index 21c6a30..67305b1 100644
--- a/src/layouts/uk105.rs
+++ b/src/layouts/uk105.rs
@@ -79,7 +79,70 @@ impl KeyboardLayout for Uk105Key {
 #[cfg(test)]
 mod test {
     use super::*;
-    use crate::{HandleControl, Keyboard, ScancodeSet2};
+    use crate::{EventDecoder, HandleControl, Keyboard, ScancodeSet, ScancodeSet1, ScancodeSet2};
+
+    #[test]
+    fn layout() {
+        // Codes taken from https://kbdlayout.info/kbduk/overview+scancodes?arrangement=ISO105
+        let mut s = ScancodeSet1::new();
+        let mut dec = EventDecoder::new(Uk105Key, HandleControl::Ignore);
+        let data = [
+            (0x29, '`'),
+            (0x02, '1'),
+            (0x03, '2'),
+            (0x04, '3'),
+            (0x05, '4'),
+            (0x06, '5'),
+            (0x07, '6'),
+            (0x08, '7'),
+            (0x09, '8'),
+            (0x0a, '9'),
+            (0x0b, '0'),
+            (0x0c, '-'),
+            (0x0d, '='),
+            (0x0f, '\t'),
+            (0x10, 'q'),
+            (0x11, 'w'),
+            (0x12, 'e'),
+            (0x13, 'r'),
+            (0x14, 't'),
+            (0x15, 'y'),
+            (0x16, 'u'),
+            (0x17, 'i'),
+            (0x18, 'o'),
+            (0x19, 'p'),
+            (0x1a, '['),
+            (0x1b, ']'),
+            (0x1e, 'a'),
+            (0x1f, 's'),
+            (0x20, 'd'),
+            (0x21, 'f'),
+            (0x22, 'g'),
+            (0x23, 'h'),
+            (0x24, 'j'),
+            (0x25, 'k'),
+            (0x26, 'l'),
+            (0x27, ';'),
+            (0x28, '\''),
+            (0x2B, '#'),
+            (0x1c, '\n'),
+            (0x56, '\\'),
+            (0x2c, 'z'),
+            (0x2d, 'x'),
+            (0x2e, 'c'),
+            (0x2f, 'v'),
+            (0x30, 'b'),
+            (0x31, 'n'),
+            (0x32, 'm'),
+            (0x33, ','),
+            (0x34, '.'),
+            (0x35, '/'),
+        ];
+        for (code, unicode) in data {
+            let ev = s.advance_state(code).unwrap().unwrap();
+            assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev));
+        }
+    }
 
     #[test]
     fn test_hash() {
diff --git a/src/layouts/us104.rs b/src/layouts/us104.rs
index 17fe9cf..9f2a04b 100644
--- a/src/layouts/us104.rs
+++ b/src/layouts/us104.rs
@@ -214,7 +214,7 @@ impl KeyboardLayout for Us104Key {
                     DecodedKey::Unicode(']')
                 }
             }
-            KeyCode::Oem7 => {
+            KeyCode::Oem5 => {
                 if modifiers.is_shifted() {
                     DecodedKey::Unicode('|')
                 } else {
@@ -484,3 +484,71 @@ impl KeyboardLayout for Us104Key {
         }
     }
 }
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use crate::{EventDecoder, ScancodeSet, ScancodeSet1};
+
+    #[test]
+    fn layout() {
+        // Codes taken from https://kbdlayout.info/kbdus/overview+scancodes?arrangement=ANSI104
+        let mut s = ScancodeSet1::new();
+        let mut dec = EventDecoder::new(Us104Key, HandleControl::Ignore);
+        let data = [
+            (0x29, '`'),
+            (0x02, '1'),
+            (0x03, '2'),
+            (0x04, '3'),
+            (0x05, '4'),
+            (0x06, '5'),
+            (0x07, '6'),
+            (0x08, '7'),
+            (0x09, '8'),
+            (0x0a, '9'),
+            (0x0b, '0'),
+            (0x0c, '-'),
+            (0x0d, '='),
+            (0x0f, '\t'),
+            (0x10, 'q'),
+            (0x11, 'w'),
+            (0x12, 'e'),
+            (0x13, 'r'),
+            (0x14, 't'),
+            (0x15, 'y'),
+            (0x16, 'u'),
+            (0x17, 'i'),
+            (0x18, 'o'),
+            (0x19, 'p'),
+            (0x1a, '['),
+            (0x1b, ']'),
+            (0x56, '\\'),
+            (0x1e, 'a'),
+            (0x1f, 's'),
+            (0x20, 'd'),
+            (0x21, 'f'),
+            (0x22, 'g'),
+            (0x23, 'h'),
+            (0x24, 'j'),
+            (0x25, 'k'),
+            (0x26, 'l'),
+            (0x27, ';'),
+            (0x28, '\''),
+            (0x1c, '\n'),
+            (0x2c, 'z'),
+            (0x2d, 'x'),
+            (0x2e, 'c'),
+            (0x2f, 'v'),
+            (0x30, 'b'),
+            (0x31, 'n'),
+            (0x32, 'm'),
+            (0x33, ','),
+            (0x34, '.'),
+            (0x35, '/'),
+        ];
+        for (code, unicode) in data {
+            let ev = s.advance_state(code).unwrap().unwrap();
+            assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev));
+        }
+    }
+}

From 270162d71e78483f45f08e184dc86e48654a7c59 Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sat, 11 Feb 2023 00:18:56 +0000
Subject: [PATCH 4/9] Ensure modifiers are passed through.

Closes #29.
---
 src/layouts/azerty.rs |  2 +-
 src/lib.rs            | 53 ++++++++++++++++++++++++++++++-------------
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/src/layouts/azerty.rs b/src/layouts/azerty.rs
index ce9047b..336f0eb 100644
--- a/src/layouts/azerty.rs
+++ b/src/layouts/azerty.rs
@@ -553,7 +553,7 @@ mod test {
         );
         assert_eq!(
             k.process_keyevent(KeyEvent::new(KeyCode::NumpadLock, KeyState::Down)),
-            None
+            Some(DecodedKey::RawKey(KeyCode::NumpadLock))
         );
         assert_eq!(
             k.process_keyevent(KeyEvent::new(KeyCode::NumpadLock, KeyState::Up)),
diff --git a/src/lib.rs b/src/lib.rs
index f1fa8ad..77de047 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -673,14 +673,14 @@ where
                 state: KeyState::Down,
             } => {
                 self.modifiers.lshift = true;
-                None
+                Some(DecodedKey::RawKey(KeyCode::LShift))
             }
             KeyEvent {
                 code: KeyCode::RShift,
                 state: KeyState::Down,
             } => {
                 self.modifiers.rshift = true;
-                None
+                Some(DecodedKey::RawKey(KeyCode::RShift))
             }
             KeyEvent {
                 code: KeyCode::LShift,
@@ -701,7 +701,7 @@ where
                 state: KeyState::Down,
             } => {
                 self.modifiers.capslock = !self.modifiers.capslock;
-                None
+                Some(DecodedKey::RawKey(KeyCode::CapsLock))
             }
             KeyEvent {
                 code: KeyCode::NumpadLock,
@@ -714,7 +714,7 @@ where
                 } else {
                     // It's a numlock toggle
                     self.modifiers.numlock = !self.modifiers.numlock;
-                    None
+                    Some(DecodedKey::RawKey(KeyCode::NumpadLock))
                 }
             }
             KeyEvent {
@@ -722,7 +722,7 @@ where
                 state: KeyState::Down,
             } => {
                 self.modifiers.lctrl = true;
-                None
+                Some(DecodedKey::RawKey(KeyCode::LControl))
             }
             KeyEvent {
                 code: KeyCode::LControl,
@@ -736,7 +736,7 @@ where
                 state: KeyState::Down,
             } => {
                 self.modifiers.rctrl = true;
-                None
+                Some(DecodedKey::RawKey(KeyCode::RControl))
             }
             KeyEvent {
                 code: KeyCode::RControl,
@@ -750,7 +750,7 @@ where
                 state: KeyState::Down,
             } => {
                 self.modifiers.alt_gr = true;
-                None
+                Some(DecodedKey::RawKey(KeyCode::RAltGr))
             }
             KeyEvent {
                 code: KeyCode::RAltGr,
@@ -764,7 +764,7 @@ where
                 state: KeyState::Down,
             } => {
                 self.modifiers.rctrl2 = true;
-                None
+                Some(DecodedKey::RawKey(KeyCode::RControl2))
             }
             KeyEvent {
                 code: KeyCode::RControl2,
@@ -1019,7 +1019,10 @@ mod test {
         );
         let test_sequence = [
             // A with left shift held
-            (KeyEvent::new(KeyCode::LShift, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::LShift, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::LShift)),
+            ),
             (
                 KeyEvent::new(KeyCode::A, KeyState::Down),
                 Some(DecodedKey::Unicode('A')),
@@ -1033,7 +1036,10 @@ mod test {
             ),
             (KeyEvent::new(KeyCode::A, KeyState::Up), None),
             // A with right shift held
-            (KeyEvent::new(KeyCode::RShift, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::RShift, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::RShift)),
+            ),
             (
                 KeyEvent::new(KeyCode::A, KeyState::Down),
                 Some(DecodedKey::Unicode('A')),
@@ -1041,7 +1047,10 @@ mod test {
             (KeyEvent::new(KeyCode::A, KeyState::Up), None),
             (KeyEvent::new(KeyCode::RShift, KeyState::Up), None),
             // Caps lock ON
-            (KeyEvent::new(KeyCode::CapsLock, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::CapsLock, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::CapsLock)),
+            ),
             (KeyEvent::new(KeyCode::CapsLock, KeyState::Up), None),
             // Letters are now caps
             (
@@ -1050,7 +1059,10 @@ mod test {
             ),
             (KeyEvent::new(KeyCode::X, KeyState::Up), None),
             // Unless you press shift
-            (KeyEvent::new(KeyCode::RShift, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::RShift, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::RShift)),
+            ),
             (
                 KeyEvent::new(KeyCode::A, KeyState::Down),
                 Some(DecodedKey::Unicode('a')),
@@ -1083,7 +1095,10 @@ mod test {
             ),
             (KeyEvent::new(KeyCode::A, KeyState::Up), None),
             // Left Control
-            (KeyEvent::new(KeyCode::LControl, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::LControl, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::LControl)),
+            ),
             (
                 KeyEvent::new(KeyCode::A, KeyState::Down),
                 Some(DecodedKey::Unicode('\u{0001}')),
@@ -1097,7 +1112,10 @@ mod test {
             ),
             (KeyEvent::new(KeyCode::A, KeyState::Up), None),
             // Right Control
-            (KeyEvent::new(KeyCode::RControl, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::RControl, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::RControl)),
+            ),
             (
                 KeyEvent::new(KeyCode::A, KeyState::Down),
                 Some(DecodedKey::Unicode('\u{0001}')),
@@ -1124,7 +1142,10 @@ mod test {
             ),
             (KeyEvent::new(KeyCode::Numpad0, KeyState::Up), None),
             // Numlock OFF
-            (KeyEvent::new(KeyCode::NumpadLock, KeyState::Down), None),
+            (
+                KeyEvent::new(KeyCode::NumpadLock, KeyState::Down),
+                Some(DecodedKey::RawKey(KeyCode::NumpadLock)),
+            ),
             (KeyEvent::new(KeyCode::NumpadLock, KeyState::Up), None),
             // Now KP_0 produces INSERT
             (
@@ -1358,7 +1379,7 @@ mod test {
                     code: KeyCode::RControl2,
                     state: KeyState::Down,
                 },
-                None,
+                Some(DecodedKey::RawKey(KeyCode::RControl2)),
             ),
             // Numlock
             (

From 2de2c561a18e142336b0316ce3b5a81b6be88921 Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sat, 11 Feb 2023 17:08:14 +0000
Subject: [PATCH 5/9] Better keyboard pictures, and a scancode table.

---
 README.md             | 253 ++++++++++++++++++++++++++++++++++++------
 src/layouts/jis109.rs |   5 +
 src/lib.rs            |  31 ++++--
 src/scancodes/set1.rs |   5 +
 4 files changed, 249 insertions(+), 45 deletions(-)

diff --git a/README.md b/README.md
index 13abbaa..416aa88 100644
--- a/README.md
+++ b/README.md
@@ -51,49 +51,234 @@ See the [`examples`](./examples) folder for more details.
 ## Keycodes
 
 This crate uses symbolic keycodes to abstract over Scancode Set 1 and Scancode
-Set 2. They represented by the `KeyCode` enum.
+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.
 
-This is the mapping of `KeyCode` to a 105-key ISO keyboard:
+### 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`.
+
+### 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| 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|
-+-----+-----+-----+------------------------------+-----+-----+------+------+  +----+----+----+  +---------+----+----+
+┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
+│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│  Oem5  │  │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│
+└─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
 ```
 
-This is the mapping of `KeyCode` to a 104-key ANSI keyboard: 
+Note that the `Oem7` key is missing on the 104-key ANSI keyboard.
+
+The 101-key is also missing `LWin`, `RWin`, and `Menu`.
+
+### 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+|Backspace|  |Inse|Home|PgUp|  |NumL|Num/|Num*|Num-|
-+----++---++---++---++---++---++---++---++---++---++---++---++---++--------+  +----+----+----+  +----+----+----+----+
-|Tab  | Q  | W  | E  | R  | T  | Y  | U  | I  | O  | P  |Oem4|Oem6| Oem5   |  |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|
-+-----+-----+-----+------------------------------+-----+-----+------+------+  +----+----+----+  +---------+----+----+
+┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
+│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 `Oem7` key is missing on the 104-key ANSI layout.
+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 also missing `LWin`, `RWin`, and `Menu`.
+
+### 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           |
+| -              | --             | --             |
+| 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`.
 
 ## Minimum Supported Rust Version (MSRV)
 
diff --git a/src/layouts/jis109.rs b/src/layouts/jis109.rs
index 5f1ab59..45c1a31 100644
--- a/src/layouts/jis109.rs
+++ b/src/layouts/jis109.rs
@@ -5,6 +5,11 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
 /// A standard Japan 106-key (or 109-key including Windows keys) keyboard.
 ///
 /// Has a small space bar, to fit in extra keys.
+///
+/// Note this doesn't currently work with Scancode Set 2, because I don't know
+/// what the Set 2 values are for the extra JIS-109 specific keys. Also, you're
+/// going to need to implement the Input Method Editor yourself - we only do
+/// basic Latin decoding here.
 pub struct Jis109Key;
 
 impl KeyboardLayout for Jis109Key {
diff --git a/src/lib.rs b/src/lib.rs
index 77de047..29633f2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -287,7 +287,7 @@ pub enum KeyCode {
     Numpad2,
     /// Numpad 3/Page Down Key
     Numpad3,
-
+    /// Numpad Enter
     NumpadEnter,
 
     // ========= Row 6 (modifers and space bar) =========
@@ -321,24 +321,23 @@ pub enum KeyCode {
     NumpadPeriod,
 
     // ========= Extra Keys =========
-
-    // Multi-media keys - Previous Track
+    /// Multi-media keys - Previous Track
     PrevTrack,
-    // Multi-media keys - Next Track
+    /// Multi-media keys - Next Track
     NextTrack,
-    // Multi-media keys - Volume Mute Toggle
+    /// Multi-media keys - Volume Mute Toggle
     Mute,
-    // Multi-media keys - Open Calculator
+    /// Multi-media keys - Open Calculator
     Calculator,
-    // Multi-media keys - Play
+    /// Multi-media keys - Play
     Play,
-    // Multi-media keys - Stop
+    /// Multi-media keys - Stop
     Stop,
-    // Multi-media keys - Increase Volume
+    /// Multi-media keys - Increase Volume
     VolumeDown,
-    // Multi-media keys - Decrease Volume
+    /// Multi-media keys - Decrease Volume
     VolumeUp,
-    // Multi-media keys - Open Browser
+    /// Multi-media keys - Open Browser
     WWWHome,
     /// Sent when the keyboard boots
     PowerOnTestOk,
@@ -348,6 +347,16 @@ pub enum KeyCode {
     RControl2,
     /// Used as a 'hidden' Right Alt Key (Print Screen = RAlt2 + PrntScr)
     RAlt2,
+    /// Extra JIS key (0x7B)
+    Oem9,
+    /// Extra JIS key (0x79)
+    Oem10,
+    /// Extra JIS key (0x70)
+    Oem11,
+    /// Extra JIS symbol key (0x73)
+    Oem12,
+    /// Extra JIS symbol key (0x7D)
+    Oem13,
 }
 
 /// The new state for a key, as part of a key event.
diff --git a/src/scancodes/set1.rs b/src/scancodes/set1.rs
index f0b5f05..4775eb2 100644
--- a/src/scancodes/set1.rs
+++ b/src/scancodes/set1.rs
@@ -205,6 +205,11 @@ impl ScancodeSet1 {
             // 0x6B My Computer
             // 0x6C Email
             // 0x6D Media Select
+            0x70 => Ok(KeyCode::Oem11),
+            0x73 => Ok(KeyCode::Oem12),
+            0x79 => Ok(KeyCode::Oem10),
+            0x7B => Ok(KeyCode::Oem9),
+            0x7D => Ok(KeyCode::Oem13),
             _ => Err(Error::UnknownKeyCode),
         }
     }

From a0af24ca35795baac015fa7153581b7c39ec6bda Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sat, 11 Feb 2023 17:08:24 +0000
Subject: [PATCH 6/9] Add media keys to Scancode Set 2.

---
 src/scancodes/set2.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/scancodes/set2.rs b/src/scancodes/set2.rs
index 5929b4a..4fec123 100644
--- a/src/scancodes/set2.rs
+++ b/src/scancodes/set2.rs
@@ -124,10 +124,19 @@ impl ScancodeSet2 {
             0x11 => Ok(KeyCode::RAltGr),
             0x12 => Ok(KeyCode::RAlt2),
             0x14 => Ok(KeyCode::RControl),
+            0x15 => Ok(KeyCode::PrevTrack),
             0x1F => Ok(KeyCode::LWin),
+            0x21 => Ok(KeyCode::VolumeDown),
+            0x23 => Ok(KeyCode::Mute),
             0x27 => Ok(KeyCode::RWin),
+            0x2B => Ok(KeyCode::Calculator),
             0x2F => Ok(KeyCode::Apps),
+            0x32 => Ok(KeyCode::VolumeUp),
+            0x34 => Ok(KeyCode::Play),
+            0x3A => Ok(KeyCode::WWWHome),
+            0x3B => Ok(KeyCode::Stop),
             0x4A => Ok(KeyCode::NumpadDivide),
+            0x4D => Ok(KeyCode::NextTrack),
             0x5A => Ok(KeyCode::NumpadEnter),
             0x69 => Ok(KeyCode::End),
             0x6B => Ok(KeyCode::ArrowLeft),

From 957ad41ce468aeed9578379b9d78d23fab130999 Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sun, 12 Feb 2023 13:59:47 +0000
Subject: [PATCH 7/9] Add Scancode Set 2 for extra JIS-109 keys

---
 README.md             |  6 ++++++
 src/lib.rs            | 22 ++++++++++++----------
 src/scancodes/set2.rs |  9 +++++++--
 3 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index 416aa88..acee9f8 100644
--- a/README.md
+++ b/README.md
@@ -260,6 +260,12 @@ IBM PC or PC/XT.
 | 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         |
diff --git a/src/lib.rs b/src/lib.rs
index 29633f2..40e99c8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -320,6 +320,18 @@ pub enum KeyCode {
     /// The Numppad Period/Delete Key
     NumpadPeriod,
 
+    // ========= JIS 109-key extra keys =========
+    /// Extra JIS key (0x7B)
+    Oem9,
+    /// Extra JIS key (0x79)
+    Oem10,
+    /// Extra JIS key (0x70)
+    Oem11,
+    /// Extra JIS symbol key (0x73)
+    Oem12,
+    /// Extra JIS symbol key (0x7D)
+    Oem13,
+
     // ========= Extra Keys =========
     /// Multi-media keys - Previous Track
     PrevTrack,
@@ -347,16 +359,6 @@ pub enum KeyCode {
     RControl2,
     /// Used as a 'hidden' Right Alt Key (Print Screen = RAlt2 + PrntScr)
     RAlt2,
-    /// Extra JIS key (0x7B)
-    Oem9,
-    /// Extra JIS key (0x79)
-    Oem10,
-    /// Extra JIS key (0x70)
-    Oem11,
-    /// Extra JIS symbol key (0x73)
-    Oem12,
-    /// Extra JIS symbol key (0x7D)
-    Oem13,
 }
 
 /// The new state for a key, as part of a key event.
diff --git a/src/scancodes/set2.rs b/src/scancodes/set2.rs
index 4fec123..4dcc9d6 100644
--- a/src/scancodes/set2.rs
+++ b/src/scancodes/set2.rs
@@ -40,6 +40,7 @@ impl ScancodeSet2 {
             0x0E => Ok(KeyCode::Oem8),
             0x11 => Ok(KeyCode::LAlt),
             0x12 => Ok(KeyCode::LShift),
+            0x13 => Ok(KeyCode::Oem11),
             0x14 => Ok(KeyCode::LControl),
             0x15 => Ok(KeyCode::Q),
             0x16 => Ok(KeyCode::Key1),
@@ -83,6 +84,7 @@ impl ScancodeSet2 {
             0x4C => Ok(KeyCode::Oem1),
             0x4D => Ok(KeyCode::P),
             0x4E => Ok(KeyCode::OemMinus),
+            0x51 => Ok(KeyCode::Oem12),
             0x52 => Ok(KeyCode::Oem3),
             0x54 => Ok(KeyCode::Oem4),
             0x55 => Ok(KeyCode::OemPlus),
@@ -92,8 +94,11 @@ impl ScancodeSet2 {
             0x5B => Ok(KeyCode::Oem6),
             0x5D => Ok(KeyCode::Oem7),
             0x61 => Ok(KeyCode::Oem5),
+            0x64 => Ok(KeyCode::Oem10),
             0x66 => Ok(KeyCode::Backspace),
+            0x67 => Ok(KeyCode::Oem9),
             0x69 => Ok(KeyCode::Numpad1),
+            0x6A => Ok(KeyCode::Oem13),
             0x6B => Ok(KeyCode::Numpad4),
             0x6C => Ok(KeyCode::Numpad7),
             0x70 => Ok(KeyCode::Numpad0),
@@ -278,7 +283,7 @@ mod test {
         }
         codes.sort();
         println!("{:?}", codes);
-        assert_eq!(codes.len(), 89);
-        assert_eq!(errs.len(), 167);
+        assert_eq!(codes.len(), 94);
+        assert_eq!(errs.len(), 162);
     }
 }

From 65f3e7638db36573f607528ff25e874a24619803 Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sun, 12 Feb 2023 17:16:57 +0000
Subject: [PATCH 8/9] Remove inaccurate comment.

We have Scancode Set 2 support for JIS now.
---
 src/layouts/jis109.rs | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/layouts/jis109.rs b/src/layouts/jis109.rs
index 45c1a31..5f1ab59 100644
--- a/src/layouts/jis109.rs
+++ b/src/layouts/jis109.rs
@@ -5,11 +5,6 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
 /// A standard Japan 106-key (or 109-key including Windows keys) keyboard.
 ///
 /// Has a small space bar, to fit in extra keys.
-///
-/// Note this doesn't currently work with Scancode Set 2, because I don't know
-/// what the Set 2 values are for the extra JIS-109 specific keys. Also, you're
-/// going to need to implement the Input Method Editor yourself - we only do
-/// basic Latin decoding here.
 pub struct Jis109Key;
 
 impl KeyboardLayout for Jis109Key {

From e0afc9818d6925d683fcbec1b3990f9a4a4baa15 Mon Sep 17 00:00:00 2001
From: Jonathan 'theJPster' Pallant <github@thejpster.org.uk>
Date: Sun, 12 Feb 2023 17:23:13 +0000
Subject: [PATCH 9/9] Adjust JIS OemX keys.

---
 src/layouts/jis109.rs | 59 +++++++++++++++++++++++++++++++------------
 1 file changed, 43 insertions(+), 16 deletions(-)

diff --git a/src/layouts/jis109.rs b/src/layouts/jis109.rs
index 5f1ab59..8bcf617 100644
--- a/src/layouts/jis109.rs
+++ b/src/layouts/jis109.rs
@@ -5,6 +5,9 @@ use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
 /// A standard Japan 106-key (or 109-key including Windows keys) keyboard.
 ///
 /// Has a small space bar, to fit in extra keys.
+///
+/// We used <https://www.win.tue.nl/~aeb/linux/kbd/scancodes-8.html> as a
+/// reference.
 pub struct Jis109Key;
 
 impl KeyboardLayout for Jis109Key {
@@ -16,11 +19,8 @@ impl KeyboardLayout for Jis109Key {
     ) -> DecodedKey {
         match keycode {
             KeyCode::Oem8 => {
-                if modifiers.is_shifted() {
-                    DecodedKey::Unicode('`')
-                } else {
-                    DecodedKey::Unicode('@')
-                }
+                // hankaku/zenkaku/kanji
+                DecodedKey::RawKey(KeyCode::Oem8)
             }
             KeyCode::Escape => DecodedKey::Unicode(0x1B.into()),
             KeyCode::Key1 => {
@@ -88,7 +88,7 @@ impl KeyboardLayout for Jis109Key {
             }
             KeyCode::Key0 => {
                 if modifiers.is_shifted() {
-                    DecodedKey::Unicode(' ')
+                    DecodedKey::Unicode('~')
                 } else {
                     DecodedKey::Unicode('0')
                 }
@@ -102,46 +102,73 @@ impl KeyboardLayout for Jis109Key {
             }
             KeyCode::OemPlus => {
                 if modifiers.is_shifted() {
-                    DecodedKey::Unicode('+')
+                    DecodedKey::Unicode('¯')
                 } else {
-                    DecodedKey::Unicode(';')
+                    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::Oem6 => {
+            KeyCode::Oem7 => {
                 if modifiers.is_shifted() {
                     DecodedKey::Unicode('}')
                 } else {
                     DecodedKey::Unicode(']')
                 }
             }
-            KeyCode::Oem7 => {
+            KeyCode::Oem1 => {
                 if modifiers.is_shifted() {
-                    DecodedKey::Unicode('|')
+                    DecodedKey::Unicode('+')
                 } else {
-                    DecodedKey::Unicode('\\')
+                    DecodedKey::Unicode(';')
                 }
             }
-            KeyCode::Oem1 => {
+            KeyCode::Oem3 => {
                 if modifiers.is_shifted() {
                     DecodedKey::Unicode('*')
                 } else {
                     DecodedKey::Unicode(':')
                 }
             }
-            KeyCode::Oem3 => {
+            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('~')
+                    DecodedKey::Unicode('_')
                 } else {
-                    DecodedKey::Unicode('^')
+                    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)