feat: add keyboard layout support

This commit is contained in:
daniel committed 2026-08-13 17:57:44 +02:00
1 parent 86e3ebfe33
commit 821543238d
36 files changed
+1132 -125

No files matched your search

+24 -12
View File
@@ -200,20 +200,28 @@ namespace Drivers::USB::HidKeyboard {
return (hidUsage >= 0x39 && hidUsage <= 0x53);
}
// Keys that arrive E0-prefixed on a PS/2 keyboard. They share a scancode
// with a main-block key (keypad "/" with "/", keypad Enter with Enter), so
// they must be flagged or a keyboard layout would rewrite them.
static bool IsExtendedKey(uint8_t hidUsage) {
return hidUsage == 0x54 || hidUsage == 0x58; // KP /, KP Enter
}
// Build and inject a KeyEvent into the PS/2 keyboard buffer
static void InjectKey(uint8_t scancode, bool pressed, uint8_t modifiers,
bool nonChar = false) {
bool nonChar = false, bool extended = false) {
bool shift = (modifiers & (MOD_LEFT_SHIFT | MOD_RIGHT_SHIFT)) != 0;
bool ctrl = (modifiers & (MOD_LEFT_CTRL | MOD_RIGHT_CTRL)) != 0;
bool alt = (modifiers & (MOD_LEFT_ALT | MOD_RIGHT_ALT)) != 0;
bool caps = Drivers::PS2::Keyboard::GetCapsLock();
char ascii = 0;
if (!nonChar && scancode < 128 && pressed) {
if (shift) {
ascii = g_ScancodeToAsciiShifted[scancode];
} else {
ascii = g_ScancodeToAscii[scancode];
}
// Caps Lock inverts shift for letters only, matching the PS/2 path.
char base = g_ScancodeToAscii[scancode];
bool upper = shift;
if (caps && base >= 'a' && base <= 'z') upper = !shift;
ascii = upper ? g_ScancodeToAsciiShifted[scancode] : base;
}
Drivers::PS2::Keyboard::KeyEvent event = {
@@ -223,7 +231,9 @@ namespace Drivers::USB::HidKeyboard {
.Shift = shift,
.Ctrl = ctrl,
.Alt = alt,
.CapsLock = false
.CapsLock = caps, // re-stamped by InjectKeyEvent, which owns the lock
.AltGr = (modifiers & MOD_RIGHT_ALT) != 0,
.Extended = extended
};
Drivers::PS2::Keyboard::InjectKeyEvent(event);
@@ -238,7 +248,9 @@ namespace Drivers::USB::HidKeyboard {
.Shift = (modifiers & (MOD_LEFT_SHIFT | MOD_RIGHT_SHIFT)) != 0,
.Ctrl = (modifiers & (MOD_LEFT_CTRL | MOD_RIGHT_CTRL)) != 0,
.Alt = (modifiers & (MOD_LEFT_ALT | MOD_RIGHT_ALT)) != 0,
.CapsLock = false
.CapsLock = Drivers::PS2::Keyboard::GetCapsLock(),
.AltGr = (modifiers & MOD_RIGHT_ALT) != 0,
.Extended = false
};
Drivers::PS2::Keyboard::InjectKeyEvent(event);
@@ -271,7 +283,7 @@ namespace Drivers::USB::HidKeyboard {
uint8_t scancode = g_HidToScancode[key];
if (scancode != 0) {
InjectKey(scancode, false, modifiers, IsNonCharKey(key));
InjectKey(scancode, false, modifiers, IsNonCharKey(key), IsExtendedKey(key));
}
g_PrevKeys[i] = 0;
}
@@ -354,7 +366,7 @@ namespace Drivers::USB::HidKeyboard {
if (!KeyInArray(key, g_PrevKeys)) {
uint8_t scancode = g_HidToScancode[key];
if (scancode != 0) {
InjectKey(scancode, true, modifiers, IsNonCharKey(key));
InjectKey(scancode, true, modifiers, IsNonCharKey(key), IsExtendedKey(key));
g_RepeatKey = key;
g_RepeatStartMs = now;
g_LastRepeatMs = 0;
@@ -373,7 +385,7 @@ namespace Drivers::USB::HidKeyboard {
if (!KeyInArray(key, keys)) {
uint8_t scancode = g_HidToScancode[key];
if (scancode != 0) {
InjectKey(scancode, false, modifiers, IsNonCharKey(key));
InjectKey(scancode, false, modifiers, IsNonCharKey(key), IsExtendedKey(key));
}
if (key == g_RepeatKey) {
g_RepeatKey = 0;
@@ -405,7 +417,7 @@ namespace Drivers::USB::HidKeyboard {
(now - g_LastRepeatMs) >= TYPEMATIC_PERIOD_MS) {
uint8_t scancode = g_HidToScancode[g_RepeatKey];
if (scancode != 0) {
InjectKey(scancode, true, g_PrevModifiers, IsNonCharKey(g_RepeatKey));
InjectKey(scancode, true, g_PrevModifiers, IsNonCharKey(g_RepeatKey), IsExtendedKey(g_RepeatKey));
}
g_LastRepeatMs = now;
}