[console] Support AltGr to access ASCII characters via remapping

Several keyboard layouts define ASCII characters as accessible only
via the AltGr modifier.  Add support for this modifier to ensure that
all ASCII characters are accessible.

Experiments suggest that the BIOS console is likely to fail to
generate ASCII characters when the AltGr key is pressed.  Work around
this limitation by accepting LShift+RShift (which will definitely
produce an ASCII character) as a synonym for AltGr.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2022-02-14 13:45:59 +00:00
parent f2a59d5973
commit e1cedbc0d4
37 changed files with 332 additions and 5 deletions

View File

@@ -7,6 +7,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define BDA_EBDA 0x000e
#define BDA_EQUIPMENT_WORD 0x0010
#define BDA_KB0 0x0017
#define BDA_KB0_RSHIFT 0x01
#define BDA_KB0_LSHIFT 0x02
#define BDA_KB0_CTRL 0x04
#define BDA_KB0_CAPSLOCK 0x040
#define BDA_FBMS 0x0013
@@ -16,5 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define BDA_REBOOT_WARM 0x1234
#define BDA_NUM_DRIVES 0x0075
#define BDA_CHAR_HEIGHT 0x0085
#define BDA_KB2 0x0096
#define BDA_KB2_RALT 0x08
#endif /* BIOS_H */

View File

@@ -362,6 +362,7 @@ static const char * bios_ansi_seq ( unsigned int scancode ) {
static int bios_getchar ( void ) {
uint16_t keypress;
uint8_t kb0;
uint8_t kb2;
unsigned int scancode;
unsigned int character;
const char *ansi_seq;
@@ -387,6 +388,7 @@ static int bios_getchar ( void ) {
scancode = ( keypress >> 8 );
character = ( keypress & 0xff );
get_real ( kb0, BDA_SEG, BDA_KB0 );
get_real ( kb2, BDA_SEG, BDA_KB2 );
/* If it's a normal character, map (if applicable) and return it */
if ( character && ( character < 0x80 ) ) {
@@ -405,6 +407,16 @@ static int bios_getchar ( void ) {
character |= KEYMAP_CTRL;
if ( kb0 & BDA_KB0_CAPSLOCK )
character |= KEYMAP_CAPSLOCK_REDO;
if ( kb2 & BDA_KB2_RALT )
character |= KEYMAP_ALTGR;
/* Treat LShift+RShift as AltGr since many BIOSes will
* not return ASCII characters when AltGr is pressed.
*/
if ( ( kb0 & ( BDA_KB0_LSHIFT | BDA_KB0_RSHIFT ) ) ==
( BDA_KB0_LSHIFT | BDA_KB0_RSHIFT ) ) {
character |= KEYMAP_ALTGR;
}
/* Map and return */
return key_remap ( character );