aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-02-09 16:06:11 +0000
committerMichael Brown <mcb30@ipxe.org>2022-02-10 13:11:27 +0000
commitfa708015e545a5877b1c07e2acf40f25b333c2cd (patch)
tree86e889d7624d9b88a338fca41c04eb00b8695a14
parentf51a62bc3f7abb40e331c16df1f4d9314aefaf23 (diff)
downloadipxe-fa708015e545a5877b1c07e2acf40f25b333c2cd.zip
ipxe-fa708015e545a5877b1c07e2acf40f25b333c2cd.tar.gz
ipxe-fa708015e545a5877b1c07e2acf40f25b333c2cd.tar.bz2
[console] Avoid attempting to remap numeric keypad on BIOS console
To minimise code size, our keyboard mapping works on the basis of allowing the BIOS to convert the keyboard scancode into an ASCII character and then remapping the ASCII character. This causes problems with keyboard layouts such as "fr" that swap the shifted and unshifted digit keys, since the ASCII-based remapping will spuriously remap the numeric keypad (which produces the same ASCII values as the digit keys). Fix by checking that the keyboard scancode is within the range of keys that vary between keyboard mappings before attempting to remap the ASCII character. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/x86/interface/pcbios/bios_console.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/arch/x86/interface/pcbios/bios_console.c b/src/arch/x86/interface/pcbios/bios_console.c
index 0692e7a..443513e 100644
--- a/src/arch/x86/interface/pcbios/bios_console.c
+++ b/src/arch/x86/interface/pcbios/bios_console.c
@@ -60,6 +60,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ATTR_DEFAULT ATTR_FCOL_WHITE
+/** Maximum keycode subject to remapping
+ *
+ * This allows us to avoid remapping the numeric keypad, which is
+ * necessary for keyboard layouts such as "fr" that swap the shifted
+ * and unshifted digit keys.
+ */
+#define SCANCODE_RSHIFT 0x36
+
/* Set default console usage if applicable */
#if ! ( defined ( CONSOLE_PCBIOS ) && CONSOLE_EXPLICIT ( CONSOLE_PCBIOS ) )
#undef CONSOLE_PCBIOS
@@ -346,6 +354,7 @@ static const char * bios_ansi_seq ( unsigned int scancode ) {
*/
static int bios_getchar ( void ) {
uint16_t keypress;
+ unsigned int scancode;
unsigned int character;
const char *ansi_seq;
@@ -367,11 +376,17 @@ static int bios_getchar ( void ) {
: "=a" ( keypress )
: "a" ( 0x1000 ), "m" ( bios_inject_lock ) );
bios_inject_lock--;
+ scancode = ( keypress >> 8 );
character = ( keypress & 0xff );
- /* If it's a normal character, just map and return it */
- if ( character && ( character < 0x80 ) )
- return key_remap ( character );
+ /* If it's a normal character, map (if applicable) and return it */
+ if ( character && ( character < 0x80 ) ) {
+ if ( scancode < SCANCODE_RSHIFT ) {
+ return key_remap ( character );
+ } else {
+ return character;
+ }
+ }
/* Otherwise, check for a special key that we know about */
if ( ( ansi_seq = bios_ansi_seq ( keypress >> 8 ) ) ) {