feat: add keyboard layout support
This commit is contained in:
1 parent
86e3ebfe33
commit
821543238d
36 files changed
+1132
-125
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user