aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-02-14 13:45:59 +0000
committerMichael Brown <mcb30@ipxe.org>2022-02-15 12:50:26 +0000
commite1cedbc0d4fdb0e16818f6b722f4873a50780761 (patch)
tree498de03ad0d5157c73479274569ea992cb47101c
parentf2a59d5973da2041f93264609698b9b3f4ec101b (diff)
downloadipxe-e1cedbc0d4fdb0e16818f6b722f4873a50780761.zip
ipxe-e1cedbc0d4fdb0e16818f6b722f4873a50780761.tar.gz
ipxe-e1cedbc0d4fdb0e16818f6b722f4873a50780761.tar.bz2
[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>
-rw-r--r--src/arch/x86/include/bios.h4
-rw-r--r--src/arch/x86/interface/pcbios/bios_console.c12
-rw-r--r--src/core/keymap.c5
-rw-r--r--src/drivers/usb/usbkbd.c2
-rw-r--r--src/hci/keymap/keymap_al.c8
-rw-r--r--src/hci/keymap/keymap_az.c7
-rw-r--r--src/hci/keymap/keymap_by.c6
-rw-r--r--src/hci/keymap/keymap_cf.c9
-rw-r--r--src/hci/keymap/keymap_cz.c26
-rw-r--r--src/hci/keymap/keymap_de.c11
-rw-r--r--src/hci/keymap/keymap_dk.c9
-rw-r--r--src/hci/keymap/keymap_es.c11
-rw-r--r--src/hci/keymap/keymap_et.c10
-rw-r--r--src/hci/keymap/keymap_fi.c9
-rw-r--r--src/hci/keymap/keymap_fr.c12
-rw-r--r--src/hci/keymap/keymap_gr.c6
-rw-r--r--src/hci/keymap/keymap_hu.c17
-rw-r--r--src/hci/keymap/keymap_il.c6
-rw-r--r--src/hci/keymap/keymap_it.c12
-rw-r--r--src/hci/keymap/keymap_lt.c6
-rw-r--r--src/hci/keymap/keymap_mk.c6
-rw-r--r--src/hci/keymap/keymap_mt.c7
-rw-r--r--src/hci/keymap/keymap_nl.c8
-rw-r--r--src/hci/keymap/keymap_no-latin1.c10
-rw-r--r--src/hci/keymap/keymap_no.c8
-rw-r--r--src/hci/keymap/keymap_pl.c6
-rw-r--r--src/hci/keymap/keymap_pt.c10
-rw-r--r--src/hci/keymap/keymap_ro.c6
-rw-r--r--src/hci/keymap/keymap_ru.c6
-rw-r--r--src/hci/keymap/keymap_sg.c10
-rw-r--r--src/hci/keymap/keymap_sr-latin.c6
-rw-r--r--src/hci/keymap/keymap_ua.c6
-rw-r--r--src/hci/keymap/keymap_uk.c6
-rw-r--r--src/hci/keymap/keymap_us.c6
-rw-r--r--src/include/ipxe/keymap.h5
-rw-r--r--src/interface/efi/efi_console.c3
-rwxr-xr-xsrc/util/genkeymap.py40
37 files changed, 332 insertions, 5 deletions
diff --git a/src/arch/x86/include/bios.h b/src/arch/x86/include/bios.h
index 3ba8264..6391a49 100644
--- a/src/arch/x86/include/bios.h
+++ b/src/arch/x86/include/bios.h
@@ -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 */
diff --git a/src/arch/x86/interface/pcbios/bios_console.c b/src/arch/x86/interface/pcbios/bios_console.c
index 2664ac8..0220c85 100644
--- a/src/arch/x86/interface/pcbios/bios_console.c
+++ b/src/arch/x86/interface/pcbios/bios_console.c
@@ -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 );
diff --git a/src/core/keymap.c b/src/core/keymap.c
index a5209bc..3fa85f7 100644
--- a/src/core/keymap.c
+++ b/src/core/keymap.c
@@ -65,8 +65,11 @@ unsigned int key_remap ( unsigned int character ) {
if ( ( character & KEYMAP_CAPSLOCK_UNDO ) && isalpha ( mapped ) )
mapped ^= CASE_TOGGLE;
+ /* Select remapping table */
+ key = ( ( character & KEYMAP_ALTGR ) ? keymap->altgr : keymap->basic );
+
/* Remap via table */
- for ( key = keymap->basic ; key->from ; key++ ) {
+ for ( ; key->from ; key++ ) {
if ( mapped == key->from ) {
mapped = key->to;
break;
diff --git a/src/drivers/usb/usbkbd.c b/src/drivers/usb/usbkbd.c
index 516667b..b284e58 100644
--- a/src/drivers/usb/usbkbd.c
+++ b/src/drivers/usb/usbkbd.c
@@ -132,6 +132,8 @@ static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
/* Apply modifiers */
if ( modifiers & USBKBD_CTRL )
key |= KEYMAP_CTRL;
+ if ( modifiers & USBKBD_ALT_RIGHT )
+ key |= KEYMAP_ALTGR;
if ( leds & USBKBD_LED_CAPS_LOCK )
key |= KEYMAP_CAPSLOCK;
diff --git a/src/hci/keymap/keymap_al.c b/src/hci/keymap/keymap_al.c
index a3df385..b68b988 100644
--- a/src/hci/keymap/keymap_al.c
+++ b/src/hci/keymap/keymap_al.c
@@ -35,8 +35,16 @@ static struct keymap_key al_basic[] = {
{ 0, 0 }
};
+/** "al" AltGr remapping */
+static struct keymap_key al_altgr[] = {
+ { 0x31, 0x7e }, /* '1' => '~' */
+ { 0x37, 0x60 }, /* '7' => '`' */
+ { 0, 0 }
+};
+
/** "al" keyboard map */
struct keymap al_keymap __keymap = {
.name = "al",
.basic = al_basic,
+ .altgr = al_altgr,
};
diff --git a/src/hci/keymap/keymap_az.c b/src/hci/keymap/keymap_az.c
index 7b382ca..03087e0 100644
--- a/src/hci/keymap/keymap_az.c
+++ b/src/hci/keymap/keymap_az.c
@@ -26,8 +26,15 @@ static struct keymap_key az_basic[] = {
{ 0, 0 }
};
+/** "az" AltGr remapping */
+static struct keymap_key az_altgr[] = {
+ { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
+ { 0, 0 }
+};
+
/** "az" keyboard map */
struct keymap az_keymap __keymap = {
.name = "az",
.basic = az_basic,
+ .altgr = az_altgr,
};
diff --git a/src/hci/keymap/keymap_by.c b/src/hci/keymap/keymap_by.c
index 4127609..9af6c96 100644
--- a/src/hci/keymap/keymap_by.c
+++ b/src/hci/keymap/keymap_by.c
@@ -17,8 +17,14 @@ static struct keymap_key by_basic[] = {
{ 0, 0 }
};
+/** "by" AltGr remapping */
+static struct keymap_key by_altgr[] = {
+ { 0, 0 }
+};
+
/** "by" keyboard map */
struct keymap by_keymap __keymap = {
.name = "by",
.basic = by_basic,
+ .altgr = by_altgr,
};
diff --git a/src/hci/keymap/keymap_cf.c b/src/hci/keymap/keymap_cf.c
index 0bbe896..09242ee 100644
--- a/src/hci/keymap/keymap_cf.c
+++ b/src/hci/keymap/keymap_cf.c
@@ -24,8 +24,17 @@ static struct keymap_key cf_basic[] = {
{ 0, 0 }
};
+/** "cf" AltGr remapping */
+static struct keymap_key cf_altgr[] = {
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x3b, 0x7e }, /* ';' => '~' */
+ { 0x60, 0x5c }, /* '`' => '\\' */
+ { 0, 0 }
+};
+
/** "cf" keyboard map */
struct keymap cf_keymap __keymap = {
.name = "cf",
.basic = cf_basic,
+ .altgr = cf_altgr,
};
diff --git a/src/hci/keymap/keymap_cz.c b/src/hci/keymap/keymap_cz.c
index 8655d5b..cce686d 100644
--- a/src/hci/keymap/keymap_cz.c
+++ b/src/hci/keymap/keymap_cz.c
@@ -46,8 +46,34 @@ static struct keymap_key cz_basic[] = {
{ 0, 0 }
};
+/** "cz" AltGr remapping */
+static struct keymap_key cz_altgr[] = {
+ { 0x2c, 0x3c }, /* ',' => '<' */
+ { 0x2e, 0x3e }, /* '.' => '>' */
+ { 0x2f, 0x2a }, /* '/' => '*' */
+ { 0x30, 0x7d }, /* '0' => '}' */
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x33, 0x23 }, /* '3' => '#' */
+ { 0x34, 0x24 }, /* '4' => '$' */
+ { 0x36, 0x5e }, /* '6' => '^' */
+ { 0x37, 0x26 }, /* '7' => '&' */
+ { 0x38, 0x2a }, /* '8' => '*' */
+ { 0x39, 0x7b }, /* '9' => '{' */
+ { 0x3b, 0x24 }, /* ';' => '$' */
+ { 0x62, 0x7b }, /* 'b' => '{' */
+ { 0x63, 0x26 }, /* 'c' => '&' */
+ { 0x67, 0x5d }, /* 'g' => ']' */
+ { 0x68, 0x60 }, /* 'h' => '`' */
+ { 0x6d, 0x5e }, /* 'm' => '^' */
+ { 0x6e, 0x7d }, /* 'n' => '}' */
+ { 0x76, 0x40 }, /* 'v' => '@' */
+ { 0x78, 0x23 }, /* 'x' => '#' */
+ { 0, 0 }
+};
+
/** "cz" keyboard map */
struct keymap cz_keymap __keymap = {
.name = "cz",
.basic = cz_basic,
+ .altgr = cz_altgr,
};
diff --git a/src/hci/keymap/keymap_de.c b/src/hci/keymap/keymap_de.c
index 4d23c2e..4a889a2 100644
--- a/src/hci/keymap/keymap_de.c
+++ b/src/hci/keymap/keymap_de.c
@@ -41,8 +41,19 @@ static struct keymap_key de_basic[] = {
{ 0, 0 }
};
+/** "de" AltGr remapping */
+static struct keymap_key de_altgr[] = {
+ { 0x2d, 0x5c }, /* '-' => '\\' */
+ { 0x30, 0x7d }, /* '0' => '}' */
+ { 0x39, 0x5d }, /* '9' => ']' */
+ { 0x71, 0x40 }, /* 'q' => '@' */
+ { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
+ { 0, 0 }
+};
+
/** "de" keyboard map */
struct keymap de_keymap __keymap = {
.name = "de",
.basic = de_basic,
+ .altgr = de_altgr,
};
diff --git a/src/hci/keymap/keymap_dk.c b/src/hci/keymap/keymap_dk.c
index 100246b..4d40743 100644
--- a/src/hci/keymap/keymap_dk.c
+++ b/src/hci/keymap/keymap_dk.c
@@ -33,8 +33,17 @@ static struct keymap_key dk_basic[] = {
{ 0, 0 }
};
+/** "dk" AltGr remapping */
+static struct keymap_key dk_altgr[] = {
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x3d, 0x7c }, /* '=' => '|' */
+ { 0x71, 0x40 }, /* 'q' => '@' */
+ { 0, 0 }
+};
+
/** "dk" keyboard map */
struct keymap dk_keymap __keymap = {
.name = "dk",
.basic = dk_basic,
+ .altgr = dk_altgr,
};
diff --git a/src/hci/keymap/keymap_es.c b/src/hci/keymap/keymap_es.c
index 2f4b86c..397e2cb 100644
--- a/src/hci/keymap/keymap_es.c
+++ b/src/hci/keymap/keymap_es.c
@@ -33,8 +33,19 @@ static struct keymap_key es_basic[] = {
{ 0, 0 }
};
+/** "es" AltGr remapping */
+static struct keymap_key es_altgr[] = {
+ { 0x30, 0x7d }, /* '0' => '}' */
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x39, 0x5d }, /* '9' => ']' */
+ { 0x5c, 0x7d }, /* '\\' => '}' */
+ { 0x71, 0x40 }, /* 'q' => '@' */
+ { 0, 0 }
+};
+
/** "es" keyboard map */
struct keymap es_keymap __keymap = {
.name = "es",
.basic = es_basic,
+ .altgr = es_altgr,
};
diff --git a/src/hci/keymap/keymap_et.c b/src/hci/keymap/keymap_et.c
index a8bf46e..4120dbe 100644
--- a/src/hci/keymap/keymap_et.c
+++ b/src/hci/keymap/keymap_et.c
@@ -31,8 +31,18 @@ static struct keymap_key et_basic[] = {
{ 0, 0 }
};
+/** "et" AltGr remapping */
+static struct keymap_key et_altgr[] = {
+ { 0x27, 0x5e }, /* '\'' => '^' */
+ { 0x2d, 0x5c }, /* '-' => '\\' */
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
+ { 0, 0 }
+};
+
/** "et" keyboard map */
struct keymap et_keymap __keymap = {
.name = "et",
.basic = et_basic,
+ .altgr = et_altgr,
};
diff --git a/src/hci/keymap/keymap_fi.c b/src/hci/keymap/keymap_fi.c
index eb75eb4..978121a 100644
--- a/src/hci/keymap/keymap_fi.c
+++ b/src/hci/keymap/keymap_fi.c
@@ -31,8 +31,17 @@ static struct keymap_key fi_basic[] = {
{ 0, 0 }
};
+/** "fi" AltGr remapping */
+static struct keymap_key fi_altgr[] = {
+ { 0x2d, 0x5c }, /* '-' => '\\' */
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
+ { 0, 0 }
+};
+
/** "fi" keyboard map */
struct keymap fi_keymap __keymap = {
.name = "fi",
.basic = fi_basic,
+ .altgr = fi_altgr,
};
diff --git a/src/hci/keymap/keymap_fr.c b/src/hci/keymap/keymap_fr.c
index 523254e..c0a959f 100644
--- a/src/hci/keymap/keymap_fr.c
+++ b/src/hci/keymap/keymap_fr.c
@@ -62,8 +62,20 @@ static struct keymap_key fr_basic[] = {
{ 0, 0 }
};
+/** "fr" AltGr remapping */
+static struct keymap_key fr_altgr[] = {
+ { 0x2d, 0x5d }, /* '-' => ']' */
+ { 0x30, 0x40 }, /* '0' => '@' */
+ { 0x33, 0x23 }, /* '3' => '#' */
+ { 0x38, 0x5c }, /* '8' => '\\' */
+ { 0x39, 0x5e }, /* '9' => '^' */
+ { 0x61, 0x40 }, /* 'a' => '@' */
+ { 0, 0 }
+};
+
/** "fr" keyboard map */
struct keymap fr_keymap __keymap = {
.name = "fr",
.basic = fr_basic,
+ .altgr = fr_altgr,
};
diff --git a/src/hci/keymap/keymap_gr.c b/src/hci/keymap/keymap_gr.c
index 16a2a70..4826c26 100644
--- a/src/hci/keymap/keymap_gr.c
+++ b/src/hci/keymap/keymap_gr.c
@@ -17,8 +17,14 @@ static struct keymap_key gr_basic[] = {
{ 0, 0 }
};
+/** "gr" AltGr remapping */
+static struct keymap_key gr_altgr[] = {
+ { 0, 0 }
+};
+
/** "gr" keyboard map */
struct keymap gr_keymap __keymap = {
.name = "gr",
.basic = gr_basic,
+ .altgr = gr_altgr,
};
diff --git a/src/hci/keymap/keymap_hu.c b/src/hci/keymap/keymap_hu.c
index 5e40716..64e27dd 100644
--- a/src/hci/keymap/keymap_hu.c
+++ b/src/hci/keymap/keymap_hu.c
@@ -35,8 +35,25 @@ static struct keymap_key hu_basic[] = {
{ 0, 0 }
};
+/** "hu" AltGr remapping */
+static struct keymap_key hu_altgr[] = {
+ { 0x2e, 0x3e }, /* '.' => '>' */
+ { 0x2f, 0x2a }, /* '/' => '*' */
+ { 0x33, 0x5e }, /* '3' => '^' */
+ { 0x37, 0x60 }, /* '7' => '`' */
+ { 0x3b, 0x24 }, /* ';' => '$' */
+ { 0x63, 0x26 }, /* 'c' => '&' */
+ { 0x6d, 0x3c }, /* 'm' => '<' */
+ { 0x76, 0x40 }, /* 'v' => '@' */
+ { 0x78, 0x23 }, /* 'x' => '#' */
+ { 0x7a, 0x3e }, /* 'z' => '>' */
+ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
+ { 0, 0 }
+};
+
/** "hu" keyboard map */
struct keymap hu_keymap __keymap = {
.name = "hu",
.basic = hu_basic,
+ .altgr = hu_altgr,
};
diff --git a/src/hci/keymap/keymap_il.c b/src/hci/keymap/keymap_il.c
index de5e639..e3061fa 100644
--- a/src/hci/keymap/keymap_il.c
+++ b/src/hci/keymap/keymap_il.c
@@ -29,8 +29,14 @@ static struct keymap_key il_basic[] = {
{ 0, 0 }
};
+/** "il" AltGr remapping */
+static struct keymap_key il_altgr[] = {
+ { 0, 0 }
+};
+
/** "il" keyboard map */
struct keymap il_keymap __keymap = {
.name = "il",
.basic = il_basic,
+ .altgr = il_altgr,
};
diff --git a/src/hci/keymap/keymap_it.c b/src/hci/keymap/keymap_it.c
index a492102..f67bbad 100644
--- a/src/hci/keymap/keymap_it.c
+++ b/src/hci/keymap/keymap_it.c
@@ -35,8 +35,20 @@ static struct keymap_key it_basic[] = {
{ 0, 0 }
};
+/** "it" AltGr remapping */
+static struct keymap_key it_altgr[] = {
+ { 0x2d, 0x60 }, /* '-' => '`' */
+ { 0x30, 0x7d }, /* '0' => '}' */
+ { 0x39, 0x5d }, /* '9' => ']' */
+ { 0x3b, 0x40 }, /* ';' => '@' */
+ { 0x3d, 0x7e }, /* '=' => '~' */
+ { 0x71, 0x40 }, /* 'q' => '@' */
+ { 0, 0 }
+};
+
/** "it" keyboard map */
struct keymap it_keymap __keymap = {
.name = "it",
.basic = it_basic,
+ .altgr = it_altgr,
};
diff --git a/src/hci/keymap/keymap_lt.c b/src/hci/keymap/keymap_lt.c
index 333241d..5d6ee5a 100644
--- a/src/hci/keymap/keymap_lt.c
+++ b/src/hci/keymap/keymap_lt.c
@@ -15,8 +15,14 @@ static struct keymap_key lt_basic[] = {
{ 0, 0 }
};
+/** "lt" AltGr remapping */
+static struct keymap_key lt_altgr[] = {
+ { 0, 0 }
+};
+
/** "lt" keyboard map */
struct keymap lt_keymap __keymap = {
.name = "lt",
.basic = lt_basic,
+ .altgr = lt_altgr,
};
diff --git a/src/hci/keymap/keymap_mk.c b/src/hci/keymap/keymap_mk.c
index 1656fb9..4b90ef7 100644
--- a/src/hci/keymap/keymap_mk.c
+++ b/src/hci/keymap/keymap_mk.c
@@ -17,8 +17,14 @@ static struct keymap_key mk_basic[] = {
{ 0, 0 }
};
+/** "mk" AltGr remapping */
+static struct keymap_key mk_altgr[] = {
+ { 0, 0 }
+};
+
/** "mk" keyboard map */
struct keymap mk_keymap __keymap = {
.name = "mk",
.basic = mk_basic,
+ .altgr = mk_altgr,
};
diff --git a/src/hci/keymap/keymap_mt.c b/src/hci/keymap/keymap_mt.c
index ebff850..f5baf69 100644
--- a/src/hci/keymap/keymap_mt.c
+++ b/src/hci/keymap/keymap_mt.c
@@ -20,8 +20,15 @@ static struct keymap_key mt_basic[] = {
{ 0, 0 }
};
+/** "mt" AltGr remapping */
+static struct keymap_key mt_altgr[] = {
+ { 0x2d, 0x5c }, /* '-' => '\\' */
+ { 0, 0 }
+};
+
/** "mt" keyboard map */
struct keymap mt_keymap __keymap = {
.name = "mt",
.basic = mt_basic,
+ .altgr = mt_altgr,
};
diff --git a/src/hci/keymap/keymap_nl.c b/src/hci/keymap/keymap_nl.c
index 2172e04..bbee4cb 100644
--- a/src/hci/keymap/keymap_nl.c
+++ b/src/hci/keymap/keymap_nl.c
@@ -38,8 +38,16 @@ static struct keymap_key nl_basic[] = {
{ 0, 0 }
};
+/** "nl" AltGr remapping */
+static struct keymap_key nl_altgr[] = {
+ { 0x2d, 0x5c }, /* '-' => '\\' */
+ { 0x39, 0x7d }, /* '9' => '}' */
+ { 0, 0 }
+};
+
/** "nl" keyboard map */
struct keymap nl_keymap __keymap = {
.name = "nl",
.basic = nl_basic,
+ .altgr = nl_altgr,
};
diff --git a/src/hci/keymap/keymap_no-latin1.c b/src/hci/keymap/keymap_no-latin1.c
index 65f30be..63fe855 100644
--- a/src/hci/keymap/keymap_no-latin1.c
+++ b/src/hci/keymap/keymap_no-latin1.c
@@ -37,8 +37,18 @@ static struct keymap_key no_latin1_basic[] = {
{ 0, 0 }
};
+/** "no-latin1" AltGr remapping */
+static struct keymap_key no_latin1_altgr[] = {
+ { 0x30, 0x7d }, /* '0' => '}' */
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x39, 0x5d }, /* '9' => ']' */
+ { 0x5b, 0x7d }, /* '[' => '}' */
+ { 0, 0 }
+};
+
/** "no-latin1" keyboard map */
struct keymap no_latin1_keymap __keymap = {
.name = "no-latin1",
.basic = no_latin1_basic,
+ .altgr = no_latin1_altgr,
};
diff --git a/src/hci/keymap/keymap_no.c b/src/hci/keymap/keymap_no.c
index d3d06bc..95a9542 100644
--- a/src/hci/keymap/keymap_no.c
+++ b/src/hci/keymap/keymap_no.c
@@ -35,8 +35,16 @@ static struct keymap_key no_basic[] = {
{ 0, 0 }
};
+/** "no" AltGr remapping */
+static struct keymap_key no_altgr[] = {
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x71, 0x40 }, /* 'q' => '@' */
+ { 0, 0 }
+};
+
/** "no" keyboard map */
struct keymap no_keymap __keymap = {
.name = "no",
.basic = no_basic,
+ .altgr = no_altgr,
};
diff --git a/src/hci/keymap/keymap_pl.c b/src/hci/keymap/keymap_pl.c
index a23c01f..a76181f 100644
--- a/src/hci/keymap/keymap_pl.c
+++ b/src/hci/keymap/keymap_pl.c
@@ -17,8 +17,14 @@ static struct keymap_key pl_basic[] = {
{ 0, 0 }
};
+/** "pl" AltGr remapping */
+static struct keymap_key pl_altgr[] = {
+ { 0, 0 }
+};
+
/** "pl" keyboard map */
struct keymap pl_keymap __keymap = {
.name = "pl",
.basic = pl_basic,
+ .altgr = pl_altgr,
};
diff --git a/src/hci/keymap/keymap_pt.c b/src/hci/keymap/keymap_pt.c
index c065fd7..99ba52e 100644
--- a/src/hci/keymap/keymap_pt.c
+++ b/src/hci/keymap/keymap_pt.c
@@ -34,8 +34,18 @@ static struct keymap_key pt_basic[] = {
{ 0, 0 }
};
+/** "pt" AltGr remapping */
+static struct keymap_key pt_altgr[] = {
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x37, 0x7b }, /* '7' => '{' */
+ { 0x38, 0x5b }, /* '8' => '[' */
+ { 0x71, 0x40 }, /* 'q' => '@' */
+ { 0, 0 }
+};
+
/** "pt" keyboard map */
struct keymap pt_keymap __keymap = {
.name = "pt",
.basic = pt_basic,
+ .altgr = pt_altgr,
};
diff --git a/src/hci/keymap/keymap_ro.c b/src/hci/keymap/keymap_ro.c
index 334cf60..6204500 100644
--- a/src/hci/keymap/keymap_ro.c
+++ b/src/hci/keymap/keymap_ro.c
@@ -15,8 +15,14 @@ static struct keymap_key ro_basic[] = {
{ 0, 0 }
};
+/** "ro" AltGr remapping */
+static struct keymap_key ro_altgr[] = {
+ { 0, 0 }
+};
+
/** "ro" keyboard map */
struct keymap ro_keymap __keymap = {
.name = "ro",
.basic = ro_basic,
+ .altgr = ro_altgr,
};
diff --git a/src/hci/keymap/keymap_ru.c b/src/hci/keymap/keymap_ru.c
index a08b115..2aafcf9 100644
--- a/src/hci/keymap/keymap_ru.c
+++ b/src/hci/keymap/keymap_ru.c
@@ -18,8 +18,14 @@ static struct keymap_key ru_basic[] = {
{ 0, 0 }
};
+/** "ru" AltGr remapping */
+static struct keymap_key ru_altgr[] = {
+ { 0, 0 }
+};
+
/** "ru" keyboard map */
struct keymap ru_keymap __keymap = {
.name = "ru",
.basic = ru_basic,
+ .altgr = ru_altgr,
};
diff --git a/src/hci/keymap/keymap_sg.c b/src/hci/keymap/keymap_sg.c
index 152c5d6..9a6db9c 100644
--- a/src/hci/keymap/keymap_sg.c
+++ b/src/hci/keymap/keymap_sg.c
@@ -43,8 +43,18 @@ static struct keymap_key sg_basic[] = {
{ 0, 0 }
};
+/** "sg" AltGr remapping */
+static struct keymap_key sg_altgr[] = {
+ { 0x32, 0x40 }, /* '2' => '@' */
+ { 0x33, 0x23 }, /* '3' => '#' */
+ { 0x37, 0x7c }, /* '7' => '|' */
+ { 0x5c, 0x7d }, /* '\\' => '}' */
+ { 0, 0 }
+};
+
/** "sg" keyboard map */
struct keymap sg_keymap __keymap = {
.name = "sg",
.basic = sg_basic,
+ .altgr = sg_altgr,
};
diff --git a/src/hci/keymap/keymap_sr-latin.c b/src/hci/keymap/keymap_sr-latin.c
index ec5efdc..7e55714 100644
--- a/src/hci/keymap/keymap_sr-latin.c
+++ b/src/hci/keymap/keymap_sr-latin.c
@@ -17,8 +17,14 @@ static struct keymap_key sr_latin_basic[] = {
{ 0, 0 }
};
+/** "sr-latin" AltGr remapping */
+static struct keymap_key sr_latin_altgr[] = {
+ { 0, 0 }
+};
+
/** "sr-latin" keyboard map */
struct keymap sr_latin_keymap __keymap = {
.name = "sr-latin",
.basic = sr_latin_basic,
+ .altgr = sr_latin_altgr,
};
diff --git a/src/hci/keymap/keymap_ua.c b/src/hci/keymap/keymap_ua.c
index b4199cd..44e82cb 100644
--- a/src/hci/keymap/keymap_ua.c
+++ b/src/hci/keymap/keymap_ua.c
@@ -17,8 +17,14 @@ static struct keymap_key ua_basic[] = {
{ 0, 0 }
};
+/** "ua" AltGr remapping */
+static struct keymap_key ua_altgr[] = {
+ { 0, 0 }
+};
+
/** "ua" keyboard map */
struct keymap ua_keymap __keymap = {
.name = "ua",
.basic = ua_basic,
+ .altgr = ua_altgr,
};
diff --git a/src/hci/keymap/keymap_uk.c b/src/hci/keymap/keymap_uk.c
index 156b42d..28cf7aa 100644
--- a/src/hci/keymap/keymap_uk.c
+++ b/src/hci/keymap/keymap_uk.c
@@ -19,8 +19,14 @@ static struct keymap_key uk_basic[] = {
{ 0, 0 }
};
+/** "uk" AltGr remapping */
+static struct keymap_key uk_altgr[] = {
+ { 0, 0 }
+};
+
/** "uk" keyboard map */
struct keymap uk_keymap __keymap = {
.name = "uk",
.basic = uk_basic,
+ .altgr = uk_altgr,
};
diff --git a/src/hci/keymap/keymap_us.c b/src/hci/keymap/keymap_us.c
index 5d78f80..6432474 100644
--- a/src/hci/keymap/keymap_us.c
+++ b/src/hci/keymap/keymap_us.c
@@ -15,8 +15,14 @@ static struct keymap_key us_basic[] = {
{ 0, 0 }
};
+/** "us" AltGr remapping */
+static struct keymap_key us_altgr[] = {
+ { 0, 0 }
+};
+
/** "us" keyboard map */
struct keymap us_keymap __keymap = {
.name = "us",
.basic = us_basic,
+ .altgr = us_altgr,
};
diff --git a/src/include/ipxe/keymap.h b/src/include/ipxe/keymap.h
index 3da2519..72b6961 100644
--- a/src/include/ipxe/keymap.h
+++ b/src/include/ipxe/keymap.h
@@ -32,6 +32,8 @@ struct keymap {
const char *name;
/** Basic remapping table (zero-terminated) */
struct keymap_key *basic;
+ /** AltGr remapping table (zero-terminated) */
+ struct keymap_key *altgr;
};
/** Keyboard mapping table */
@@ -64,6 +66,9 @@ struct keymap {
/** Undo and redo CapsLock key flags */
#define KEYMAP_CAPSLOCK_REDO ( KEYMAP_CAPSLOCK | KEYMAP_CAPSLOCK_UNDO )
+/** AltGr key flag */
+#define KEYMAP_ALTGR 0x0800
+
extern unsigned int key_remap ( unsigned int character );
#endif /* _IPXE_KEYMAP_H */
diff --git a/src/interface/efi/efi_console.c b/src/interface/efi/efi_console.c
index 9adce4a..fc1500a 100644
--- a/src/interface/efi/efi_console.c
+++ b/src/interface/efi/efi_console.c
@@ -334,6 +334,9 @@ static int efi_getchar ( void ) {
EFI_RIGHT_CONTROL_PRESSED ) ) {
character |= KEYMAP_CTRL;
}
+ if ( shift & EFI_RIGHT_ALT_PRESSED ) {
+ character |= KEYMAP_ALTGR;
+ }
}
/* Apply toggle state */
diff --git a/src/util/genkeymap.py b/src/util/genkeymap.py
index d38552e..ff5ff0a 100755
--- a/src/util/genkeymap.py
+++ b/src/util/genkeymap.py
@@ -171,6 +171,11 @@ class KeyLayout(UserDict[KeyModifiers, Sequence[Key]]):
"""Basic shifted keyboard layout"""
return self[KeyModifiers.SHIFT]
+ @property
+ def altgr(self):
+ """AltGr keyboard layout"""
+ return self.get(KeyModifiers.ALTGR, self.unshifted)
+
@classmethod
def load(cls, name: str) -> KeyLayout:
"""Load keymap using 'loadkeys -b'"""
@@ -278,6 +283,7 @@ class KeymapKeys(UserDict[str, str]):
self.ascii_name(source), self.ascii_name(target)
)
for source, target in self.items()
+ if ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target)
) + '\t{ 0, 0 }\n}'
@@ -301,13 +307,12 @@ class Keymap:
raw = {source: self.target[key.modifiers][key.keycode].ascii
for source, key in self.source.inverse.items()}
# Eliminate any null mappings, mappings that attempt to remap
- # the backspace key, or mappings that would become identity
- # mappings after clearing the high bit
+ # the backspace key, or identity mappings
table = {source: target for source, target in raw.items()
if target
and ord(source) != 0x7f
and ord(target) != 0x7f
- and ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target)}
+ and source != target}
# Recursively delete any mappings that would produce
# unreachable alphanumerics (e.g. the "il" keymap, which maps
# away the whole lower-case alphabet)
@@ -327,6 +332,28 @@ class Keymap:
(unshifted, shifted))
return KeymapKeys(dict(sorted(table.items())))
+ @property
+ def altgr(self) -> KeymapKeys:
+ """AltGr remapping table"""
+ # Construct raw mapping from source ASCII to target ASCII
+ raw = {source: self.target.altgr[key.keycode].ascii
+ for source, key in self.source.inverse.items()
+ if key.modifiers == KeyModifiers.NONE}
+ # Identify printable keys that are unreachable via the basic map
+ basic = self.basic
+ unmapped = set(x for x in basic.keys()
+ if x.isascii() and x.isprintable())
+ remapped = set(basic.values())
+ unreachable = unmapped - remapped
+ # Eliminate any null mappings, mappings for unprintable
+ # characters, or mappings for characters that are reachable
+ # via the basic map
+ table = {source: target for source, target in raw.items()
+ if source.isprintable()
+ and target
+ and target in unreachable}
+ return KeymapKeys(dict(sorted(table.items())))
+
def cname(self, suffix: str) -> str:
"""C variable name"""
return re.sub(r'\W', '_', (self.name + '_' + suffix))
@@ -336,6 +363,7 @@ class Keymap:
"""Generated source code"""
keymap_name = self.cname("keymap")
basic_name = self.cname("basic")
+ altgr_name = self.cname("altgr")
code = textwrap.dedent(f"""
/** @file
*
@@ -352,12 +380,16 @@ class Keymap:
/** "{self.name}" basic remapping */
static struct keymap_key {basic_name}[] = %s;
+ /** "{self.name}" AltGr remapping */
+ static struct keymap_key {altgr_name}[] = %s;
+
/** "{self.name}" keyboard map */
struct keymap {keymap_name} __keymap = {{
\t.name = "{self.name}",
\t.basic = {basic_name},
+ \t.altgr = {altgr_name},
}};
- """).strip() % self.basic.code
+ """).strip() % (self.basic.code, self.altgr.code)
return code