]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[console] Support AltGr to access ASCII characters via remapping
authorMichael Brown <mcb30@ipxe.org>
Mon, 14 Feb 2022 13:45:59 +0000 (13:45 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 15 Feb 2022 12:50:26 +0000 (12:50 +0000)
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>
37 files changed:
src/arch/x86/include/bios.h
src/arch/x86/interface/pcbios/bios_console.c
src/core/keymap.c
src/drivers/usb/usbkbd.c
src/hci/keymap/keymap_al.c
src/hci/keymap/keymap_az.c
src/hci/keymap/keymap_by.c
src/hci/keymap/keymap_cf.c
src/hci/keymap/keymap_cz.c
src/hci/keymap/keymap_de.c
src/hci/keymap/keymap_dk.c
src/hci/keymap/keymap_es.c
src/hci/keymap/keymap_et.c
src/hci/keymap/keymap_fi.c
src/hci/keymap/keymap_fr.c
src/hci/keymap/keymap_gr.c
src/hci/keymap/keymap_hu.c
src/hci/keymap/keymap_il.c
src/hci/keymap/keymap_it.c
src/hci/keymap/keymap_lt.c
src/hci/keymap/keymap_mk.c
src/hci/keymap/keymap_mt.c
src/hci/keymap/keymap_nl.c
src/hci/keymap/keymap_no-latin1.c
src/hci/keymap/keymap_no.c
src/hci/keymap/keymap_pl.c
src/hci/keymap/keymap_pt.c
src/hci/keymap/keymap_ro.c
src/hci/keymap/keymap_ru.c
src/hci/keymap/keymap_sg.c
src/hci/keymap/keymap_sr-latin.c
src/hci/keymap/keymap_ua.c
src/hci/keymap/keymap_uk.c
src/hci/keymap/keymap_us.c
src/include/ipxe/keymap.h
src/interface/efi/efi_console.c
src/util/genkeymap.py

index 3ba8264ecc7f417c5f692d6a36a69ffc14049930..6391a4958277c7f475024aee15ebfd2a788cfcd3 100644 (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 */
index 2664ac8a516e549413fa701cab5d2550fbc69ad3..0220c8564f28964862b36b3af733fd1f879cc0a5 100644 (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 );
index a5209bc20a399c8253e662f72906b514112ba4b5..3fa85f74e3c315d011d128b17252bbc33f1974ee 100644 (file)
@@ -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;
index 516667b25e855671e5f33134c399b78510d608c5..b284e584f3b9246a49f84a4d47a7ae4e6a015e37 100644 (file)
@@ -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;
 
index a3df385a94dcd6eab32f9b02e3d490510f41db08..b68b988781e87711310f29ea7cfd7dbbb4cc0616 100644 (file)
@@ -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,
 };
index 7b382ca8b9e9e5734c26c176d88c67ba50c62ca9..03087e01efe8cebd661904932a46eda85d39213e 100644 (file)
@@ -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,
 };
index 4127609e3bc0a60cb9a621972baf2bab449593e3..9af6c966dd6ea46492ccfef15c5811826ac738a8 100644 (file)
@@ -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,
 };
index 0bbe89659d2c6d2533d9aa9b35c4ec4d63b7bf39..09242ee6f4f72ad6df9041de12ffda86a664f10c 100644 (file)
@@ -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,
 };
index 8655d5b68e45fc2100e9c2d64da5ba3ed610e9ac..cce686d9ab9b29f57f9a1bd12cd175e230157a72 100644 (file)
@@ -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,
 };
index 4d23c2e60c56cddbd14843a048903e87f20adca3..4a889a2425b85f0a5852a27070b58bfce3b7bb75 100644 (file)
@@ -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,
 };
index 100246bf538c3595fcffb0c4c3a7e46258da6170..4d40743b17cc098cac4a713aadd5924c14cb5305 100644 (file)
@@ -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,
 };
index 2f4b86c4787a88b5d92c6fb847041e0c5aaee340..397e2cbaa1fd584019adbd98b922ee516d35d6c7 100644 (file)
@@ -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,
 };
index a8bf46ebcdc4ad6b8886867a03ee1a5d04af62ff..4120dbed92c95481fdbcfdb4080eb0893abeb40c 100644 (file)
@@ -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,
 };
index eb75eb4dcd87c52c931af571b2714fd6f61a15f6..978121a888252debeff82f74390f03abcb728243 100644 (file)
@@ -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,
 };
index 523254ee56360caec7341c7d2ff88e70784ebb76..c0a959f0d319581a5ed0a0383275b837a11ef042 100644 (file)
@@ -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,
 };
index 16a2a703264e5f551f23bed1de1890365aac08ef..4826c26c2ba8858183da1f399933e2dd1ff0b590 100644 (file)
@@ -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,
 };
index 5e407161f24aa12e1326cc3f023999ec781306e5..64e27dda631188fbef0e7b9a0336d82e58c1be6c 100644 (file)
@@ -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,
 };
index de5e639ca3ff2e96b6af2d962219a3fec5e6e725..e3061fa542a5c9d34fc14e6cb2a1330862cf1613 100644 (file)
@@ -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,
 };
index a4921020a1970f002ab5772966284c71a2ff5ecf..f67bbadcbdcb668c7598381feb19eddc44fc4a43 100644 (file)
@@ -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,
 };
index 333241d21244e161651397dd9fddc44162b8ad1f..5d6ee5a8cc748529a3f78017f9ba661e05e349a0 100644 (file)
@@ -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,
 };
index 1656fb99c12fd01fd9b3acf29e8d84366d956506..4b90ef7997056bc4f9516843837a4e2a98e18ac2 100644 (file)
@@ -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,
 };
index ebff8506f639af3aa1eb45e6c416bdf04404f81f..f5baf690714a628bd73e6b184935f1502b327052 100644 (file)
@@ -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,
 };
index 2172e045f32484a67714ac4ad0e453d0904cc5f6..bbee4cbdf0889ed5a06125b783f9091c38b6783e 100644 (file)
@@ -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,
 };
index 65f30beae5e95fdd7cdb1b94dfdedb7b8a9ee260..63fe8554823370cd39f2a551241f9c1969352432 100644 (file)
@@ -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,
 };
index d3d06bce31341dd340c61cc7747f0ced70807584..95a95428b95c6c3894f99071c223ba98fc7c3974 100644 (file)
@@ -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,
 };
index a23c01f2cc06c6455526666e5da8a6f7ec59d63d..a76181fbc085169201d11f08a3e0b5f096d1f26d 100644 (file)
@@ -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,
 };
index c065fd76f43b3a48c09a870d87b013e5c9cff2eb..99ba52e4b497506e5bbdc14952dbbe2a7eb760a3 100644 (file)
@@ -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,
 };
index 334cf6080d5390a791df5b136e4776ba5c6d94ff..6204500018ccabe37cc6d3701f15b5ddb7f0f67e 100644 (file)
@@ -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,
 };
index a08b115ed10a70744279798fe02c623e59234fb0..2aafcf9bd0e00f653568b390cc1b59b6a7ca13ff 100644 (file)
@@ -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,
 };
index 152c5d6319643afca3909cadb2accea06ed54a29..9a6db9cb4165bed36ac9c842f222954351fb8c16 100644 (file)
@@ -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,
 };
index ec5efdc89ec5b6518d33295b41b8e3487c0f4263..7e55714a2656229302511ffcb3c5104dea2859b1 100644 (file)
@@ -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,
 };
index b4199cdad67f7201abbdac059b2dc0d48e4a1096..44e82cb2d919c0043e072d7b5fb433ff3e39ca26 100644 (file)
@@ -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,
 };
index 156b42dff1caace9f6557f8d22ad2a3e58d371cf..28cf7aac4676eacb931af1f621b8b4160f04130b 100644 (file)
@@ -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,
 };
index 5d78f80a2022c90ac0d6f60c30b4390ed1704049..6432474e21241238c1e123e2e277e7e87c4a1188 100644 (file)
@@ -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,
 };
index 3da25190bc822dd016f060678fa29947ace8ad2d..72b6961efee319cbce3ca8c117f6dcabba7efbff 100644 (file)
@@ -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 */
index 9adce4a9b4ac02a933e4d5ea1ded21056f01aff6..fc1500afb3319c3e00fa94275310ec3f58635a9b 100644 (file)
@@ -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 */
index d38552eb41fbaf4864d56a61c402a31b17e9471c..ff5ff0a87ad4d0fdb93fe2ab66292f8cf3ca5ddd 100755 (executable)
@@ -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