aboutsummaryrefslogtreecommitdiff
path: root/src/core
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/core
parent871dd236d4aff66e871c25addcf522fe75a4ccd7 (diff)
downloadipxe-f2a59d5973da2041f93264609698b9b3f4ec101b.zip
ipxe-f2a59d5973da2041f93264609698b9b3f4ec101b.tar.gz
ipxe-f2a59d5973da2041f93264609698b9b3f4ec101b.tar.bz2
[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/core')
-rw-r--r--src/core/keymap.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/src/core/keymap.c b/src/core/keymap.c
index c095396..a5209bc 100644
--- a/src/core/keymap.c
+++ b/src/core/keymap.c
@@ -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;
+ }
+ }
+
+ /* Clear flags */
+ mapped &= ASCII_MASK;
- return character;
+ DBGC2 ( &keymap, "KEYMAP mapped %04x => %02x\n", character, mapped );
+ return mapped;
}