OvmfPkg/VirtioInputDxe: fold Ctrl correctly

Folding Ctrl into a printable character to produce a C0 control code is
not specified by SIMPLE_TEXT_INPUT(_EX). We apply it for narrow
compatibility with other keyboard drivers and TerminalDxe; as such,
only apply it ReadKeyStroke (which is the only interface that does not
convey modifier state explicitly).

Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Tested-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
This commit is contained in:
Ivan Shapovalov 2026-07-30 23:04:53 +03:00 committed by mergify[bot]
parent 1c76821458
commit 93be2ced1c

View file

@ -312,11 +312,6 @@ VirtioKeyboardConvertKeyCode (
KeyData->KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED); KeyData->KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
} }
if (Dev->KeyActive[KEY_LEFTCTRL] || Dev->KeyActive[KEY_RIGHTCTRL]) {
// Convert Ctrl+[a-z] and Ctrl+[A-Z] into [1-26] ASCII table entries
Key->UnicodeChar &= 0x1F;
}
break; break;
} }
} }
@ -474,6 +469,22 @@ VirtioKeyboardReadKeyStroke (
continue; continue;
} }
// Since ReadKeyStroke does not allow to convey modifier state, we have to
// fold Ctrl into the printable character to produce a C0 control code
// (i.e. apply the caret notation).
// NB1: this is not actually in the SIMPLE_TEXT_INPUT(_EX) spec; we do it
// for compatibility with other keyboard drivers and TerminalDxe.
// NB2: We only apply a subset of caret notation limited to alphabetic
// characters, as these are idempotent wrt. Shift and CapsLock
// (which are already applied at this point).
if (KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) {
if (((KeyData.Key.UnicodeChar >= 'A') && (KeyData.Key.UnicodeChar <= 'Z')) ||
((KeyData.Key.UnicodeChar >= 'a') && (KeyData.Key.UnicodeChar <= 'z')))
{
KeyData.Key.UnicodeChar &= 0x1F;
}
}
*Key = KeyData.Key; *Key = KeyData.Key;
break; break;
} }