[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>
This commit is contained in:
Michael Brown
2022-02-14 16:31:08 +00:00
parent 871dd236d4
commit f2a59d5973
6 changed files with 116 additions and 37 deletions

View File

@@ -23,6 +23,8 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ctype.h>
#include <ipxe/keys.h>
#include <ipxe/keymap.h>
/** @file
@@ -31,6 +33,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
/** ASCII character mask */
#define ASCII_MASK 0x7f
/** Control character mask */
#define CTRL_MASK 0x1f
/** Upper case character mask */
#define UPPER_MASK 0x5f
/** Case toggle bit */
#define CASE_TOGGLE ( ASCII_MASK & ~UPPER_MASK )
/** Default keyboard mapping */
static TABLE_START ( keymap_start, KEYMAP );
@@ -41,21 +55,36 @@ static struct keymap *keymap = keymap_start;
* Remap a key
*
* @v character Character read from console
* @ret character Mapped character
* @ret mapped Mapped character
*/
unsigned int key_remap ( unsigned int character ) {
unsigned int mapped = ( character & KEYMAP_MASK );
struct keymap_key *key;
/* Invert case before remapping if applicable */
if ( ( character & KEYMAP_CAPSLOCK_UNDO ) && isalpha ( mapped ) )
mapped ^= CASE_TOGGLE;
/* Remap via table */
for ( key = keymap->basic ; key->from ; key++ ) {
if ( key->from == character ) {
character = key->to;
if ( mapped == key->from ) {
mapped = key->to;
break;
}
}
/* Clear pseudo key flag */
character &= ~KEYMAP_PSEUDO;
/* Handle Ctrl-<key> and CapsLock */
if ( isalpha ( mapped ) ) {
if ( character & KEYMAP_CTRL ) {
mapped &= CTRL_MASK;
} else if ( character & KEYMAP_CAPSLOCK ) {
mapped ^= CASE_TOGGLE;
}
}
return character;
/* Clear flags */
mapped &= ASCII_MASK;
DBGC2 ( &keymap, "KEYMAP mapped %04x => %02x\n", character, mapped );
return mapped;
}