Skip to main content

Crate pc_keyboard

Crate pc_keyboard 

Source
Expand description

Driver for a PS/2 PC keyboard.

Supports PS/2 Scan Code Set 1 and 2, on a variety of keyboard layouts. See the OSDev Wiki.

§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:
NameNo. KeysDescriptionLink
Us104Key101/104North American standard EnglishWikipedia
Uk105Key102/105United Kingdom standard EnglishWikipedia
Azerty102/105Typically used in French localesWikipedia
De105Key102/105German layoutWikipedia
FiSe105Key102/105Finnish/Swedish layoutWikipedia
No105Key102/105Norwegian layoutWikipedia
Jis109Key106/109JIS 109-key layout (Latin chars only)Wikipedia
Colemak101/104A keyboard layout designed to make typing more efficient and comfortableWikipedia
Dvorak104Key101/104The more ‘ergonomic’ alternative to QWERTYWikipedia
DVP104Key101/104Dvorak for ProgrammersWikipedia

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 PS2Keyboard which combines the above three functions into a single object.

See the 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. The scancodes can 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

This is the mapping of KeyCode to a 102/105-key ISO keyboard:

┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
│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: https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=ISO105)

§101/104 key ANSI

This is the mapping of KeyCode to a 101/104-key ANSI keyboard:

┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
│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: https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=ANSI104)

§106/109 key JIS

This is the mapping of KeyCode to a 106/109-key JIS keyboard:

┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
│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: https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=OADG109A)

§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. 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 KeyScancode Set 1Scancode Set 2USB HID
Escape0x010x760x29
F10x3B0x050x3A
F20x3C0x060x3B
F30x3D0x040x3C
F40x3E0x0C0x3D
F50x3F0x030x3E
F60x400x0B0x3F
F70x410x830x40
F80x420x0A0x41
F90x430x010x42
F100x440x090x43
F110x570x780x44
F120x580x070x45
PrintScreen0xE0370xE07C0x46
SysRq0x540x7F
ScrollLock0x460x7E0x47
PauseBreak0x48
-
Oem80x290x0E0x35
Key10x020x160x1E
Key20x030x1E0x1F
Key30x040x260x20
Key40x050x250x21
Key50x060x2E0x22
Key60x070x360x23
Key70x080x3D0x24
Key80x090x3E0x25
Key90x0A0x460x26
Key00x0B0x450x27
OemMinus0x0C0x4E0x2D
OemPlus0x0D0x550x2E
Backspace0x0E0x660x2A
Insert0xE0520xE0700x49
Home0xE0470xE06C0x4A
PageUp0xE0490xE07D0x4B
NumpadLock0x450x770x53
NumpadDivide0xE0350xE04A0x54
NumpadMultiply0x370x7C0x55
NumpadSubtract0x4A0x7B0x56
-
Tab0x0F0x0D0x2B
Q0x100x150x14
W0x110x1D0x1A
E0x120x240x08
R0x130x2D0x15
T0x140x2C0x17
Y0x150x350x1C
U0x160x3C0x18
I0x170x430x0C
O0x180x440x12
P0x190x4D0x13
Oem40x1A0x540x2F
Oem60x1B0x5B0x30
Oem50x560x610x64
Oem70x2B0x5D0x31
Delete0xE0530xE0710x4C
End0xE04F0xE0690x4D
PageDown0xE0510xE07A0x4E
Numpad70x470x6C0x5F
Numpad80x480x750x60
Numpad90x490x7D0x61
NumpadAdd0x4E0x790x57
-
CapsLock0x3A0x580x39
A0x1E0x1C0x04
S0x1F0x1B0x16
D0x200x230x07
F0x210x2B0x09
G0x220x340x0A
H0x230x330x0B
J0x240x3B0x0D
K0x250x420x0E
L0x260x4B0x0F
Oem10x270x4C0x33
Oem30x280x520x34
Return0x1C0x5A0x28
Numpad40x4B0x6B0x5C
Numpad50x4C0x730x5D
Numpad60x4D0x740x5E
-
LShift0x2A0x120xE1
Z0x2C0x1A0x1D
X0x2D0x220x1B
C0x2E0x210x06
V0x2F0x2A0x19
B0x300x320x05
N0x310x310x11
M0x320x3A0x10
OemComma0x330x410x36
OemPeriod0x340x490x37
Oem20x350x4A0x38
RShift0x360x590xE5
ArrowUp0xE0480xE0750x52
Numpad10x4F0x690x59
Numpad20x500x720x5A
Numpad30x510x7A0x5B
NumpadEnter0xE01C0xE0750x58
-
LControl0x1D0x140xE0
LWin0xE05B0xE01F0xE3
LAlt0x380x110xE2
Spacebar0x390x290x2C
RAltGr0xE0380xE0110xE6
RWin0xE05C0xE0270xE7
Apps0xE05C0xE02F0x65
RControl0xE01D0xE0140xE4
ArrowLeft0xE04B0xE06B0x50
ArrowDown0xE0500xE0720x51
ArrowRight0xE04D0xE0740x52
Numpad00x520x700x62
NumpadPeriod0x530x710x63
-
Oem90x7B0x67??
Oem100x790x64??
Oem110x700x13??
Oem120x730x51??
Oem130x7D0x6A??
-??
PrevTrack0xE0100xE015??
NextTrack0xE0190xE04D??
Mute0xE0200xE023??
Calculator0xE0210xE02B??
Play0xE0220xE034??
Stop0xE0240xE03B??
VolumeDown0xE02E0xE021??
VolumeUp0xE0300xE032??
WWWHome0xE0320xE03A??
TooManyKeys0x00??
PowerOnTestOk0xAA??
RControl20xE11D0xE114??
RAlt20xE02A0xE012??

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.

Modules§

layouts
Implements the various keyboard layouts.

Structs§

EventDecoder
Converts KeyEvents into Unicode, according to the current Keyboard Layout
KeyEvent
A event describing something happen to a key on your keyboard.
Modifiers
The set of modifier keys you have on a keyboard.
PS2Keyboard
Encapsulates decode/sampling logic, and handles state transitions and key events for PS/2 Keyboards
Ps2Decoder
Handles decoding of IBM PS/2 Keyboard (and IBM PC/AT Keyboard) bit-streams.
ScancodeSet1
Contains the implementation of Scancode Set 1.
ScancodeSet2
Contains the implementation of Scancode Set 2.
UsbBootKeyboardReport
A USB HID report as received from a keyboard in Boot Mode
UsbDecodedKeyIter
An Iterator that produces [‘DecodedKey’] values, using an EventDecoder
UsbKeyEventIter
An Iterator that produces [‘KeyEvent’] values
UsbKeyboard
Encapsulates HID frame handling, and handles state transitions and key events for USB HID Keyboards

Enums§

DecodedKey
Contains either a Unicode character, or a raw key code.
Error
Indicates different error conditions.
HandleControl
Options for how we can handle what happens when the Ctrl key is held down and a letter is pressed.
KeyCode
Keycodes that can be generated by a keyboard.
KeyState
The new state for a key, as part of a key event.
PhysicalKeyboard
Describes a physical keyboard
UsbModifiers

Traits§

KeyboardLayout
Describes a Keyboard Layout.
ScancodeSet
A mechanism to convert bytes from a Keyboard into KeyCode values.