aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/x86
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-02-14 16:31:08 +0000
committerMichael Brown <mcb30@ipxe.org>2022-02-15 11:58:50 +0000
commitf2a59d5973da2041f93264609698b9b3f4ec101b (patch)
treed74210c67817a2bc8ddbf92514c18608566317ed /src/arch/x86
parent871dd236d4aff66e871c25addcf522fe75a4ccd7 (diff)
downloadipxe-f2a59d5973da2041f93264609698b9b3f4ec101b.tar.gz
[console] Centralise handling of key modifiers
Handle Ctrl and CapsLock key modifiers within key_remap(), to provide consistent behaviour across different console types. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/include/bios.h3
-rw-r--r--src/arch/x86/interface/pcbios/bios_console.c23
2 files changed, 21 insertions, 5 deletions
diff --git a/src/arch/x86/include/bios.h b/src/arch/x86/include/bios.h
index 14e7acbc7..3ba8264ec 100644
--- a/src/arch/x86/include/bios.h
+++ b/src/arch/x86/include/bios.h
@@ -6,6 +6,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define BDA_SEG 0x0040
#define BDA_EBDA 0x000e
#define BDA_EQUIPMENT_WORD 0x0010
+#define BDA_KB0 0x0017
+#define BDA_KB0_CTRL 0x04
+#define BDA_KB0_CAPSLOCK 0x040
#define BDA_FBMS 0x0013
#define BDA_TICKS 0x006c
#define BDA_MIDNIGHT 0x0070
diff --git a/src/arch/x86/interface/pcbios/bios_console.c b/src/arch/x86/interface/pcbios/bios_console.c
index 438a01d07..2664ac8a5 100644
--- a/src/arch/x86/interface/pcbios/bios_console.c
+++ b/src/arch/x86/interface/pcbios/bios_console.c
@@ -361,6 +361,7 @@ static const char * bios_ansi_seq ( unsigned int scancode ) {
*/
static int bios_getchar ( void ) {
uint16_t keypress;
+ uint8_t kb0;
unsigned int scancode;
unsigned int character;
const char *ansi_seq;
@@ -385,16 +386,28 @@ static int bios_getchar ( void ) {
bios_inject_lock--;
scancode = ( keypress >> 8 );
character = ( keypress & 0xff );
+ get_real ( kb0, BDA_SEG, BDA_KB0 );
/* 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 if ( scancode == SCANCODE_NON_US ) {
- return key_remap ( character | KEYMAP_PSEUDO );
- } else {
+
+ /* Handle special scancodes */
+ if ( scancode == SCANCODE_NON_US ) {
+ /* Treat as "\|" with high bit set */
+ character |= KEYMAP_PSEUDO;
+ } else if ( scancode >= SCANCODE_RSHIFT ) {
+ /* Non-remappable scancode (e.g. numeric keypad) */
return character;
}
+
+ /* Apply modifiers */
+ if ( kb0 & BDA_KB0_CTRL )
+ character |= KEYMAP_CTRL;
+ if ( kb0 & BDA_KB0_CAPSLOCK )
+ character |= KEYMAP_CAPSLOCK_REDO;
+
+ /* Map and return */
+ return key_remap ( character );
}
/* Otherwise, check for a special key that we know about */