aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-02-06 19:33:20 +0000
committerMichael Brown <mcb30@ipxe.org>2022-02-10 13:59:32 +0000
commit3f05a82fec6223a49df300a9cbf80c6245c3f99e (patch)
tree992afdde95a7f1686908376ac49b4cfedb19fd52
parent0979b3a11ddd642b047c7e9240cefc0144c595c7 (diff)
downloadipxe-3f05a82fec6223a49df300a9cbf80c6245c3f99e.zip
ipxe-3f05a82fec6223a49df300a9cbf80c6245c3f99e.tar.gz
ipxe-3f05a82fec6223a49df300a9cbf80c6245c3f99e.tar.bz2
[console] Update genkeymap to work with current databases
Rewrite genkeymap.pl in Python with added sanity checks, and update the list of keyboard mappings to remove those no longer supported by the underlying "loadkeys" tool. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/Makefile2
-rw-r--r--src/hci/keymap/keymap_al.c1
-rw-r--r--src/hci/keymap/keymap_az.c2
-rw-r--r--src/hci/keymap/keymap_cz.c33
-rw-r--r--src/hci/keymap/keymap_de.c13
-rw-r--r--src/hci/keymap/keymap_dk.c4
-rw-r--r--src/hci/keymap/keymap_es.c2
-rw-r--r--src/hci/keymap/keymap_et.c1
-rw-r--r--src/hci/keymap/keymap_fi.c9
-rw-r--r--src/hci/keymap/keymap_fr.c16
-rw-r--r--src/hci/keymap/keymap_hu.c1
-rw-r--r--src/hci/keymap/keymap_il.c12
-rw-r--r--src/hci/keymap/keymap_it.c1
-rw-r--r--src/hci/keymap/keymap_mt.c2
-rw-r--r--src/hci/keymap/keymap_nl.c4
-rw-r--r--src/hci/keymap/keymap_no-latin1.c1
-rw-r--r--src/hci/keymap/keymap_no.c88
-rw-r--r--src/hci/keymap/keymap_pt.c31
-rw-r--r--src/hci/keymap/keymap_ru.c1
-rw-r--r--src/hci/keymap/keymap_sr-latin.c (renamed from src/hci/keymap/keymap_bg.c)6
-rw-r--r--src/hci/keymap/keymap_sr.c35
-rw-r--r--src/hci/keymap/keymap_th.c15
-rw-r--r--src/hci/keymap/keymap_wo.c55
-rwxr-xr-xsrc/util/genkeymap.pl238
-rwxr-xr-xsrc/util/genkeymap.py346
25 files changed, 434 insertions, 485 deletions
diff --git a/src/Makefile b/src/Makefile
index 4c4abf1..83642e7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -50,7 +50,7 @@ ELF2EFI64 := ./util/elf2efi64
EFIROM := ./util/efirom
EFIFATBIN := ./util/efifatbin
EINFO := ./util/einfo
-GENKEYMAP := ./util/genkeymap.pl
+GENKEYMAP := ./util/genkeymap.py
DOXYGEN := doxygen
LCAB := lcab
QEMUIMG := qemu-img
diff --git a/src/hci/keymap/keymap_al.c b/src/hci/keymap/keymap_al.c
index caf295e..e441836 100644
--- a/src/hci/keymap/keymap_al.c
+++ b/src/hci/keymap/keymap_al.c
@@ -14,6 +14,7 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
struct key_mapping al_mapping[] __keymap = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x1c, 0x1d }, /* 0x1c => 0x1d */
{ 0x22, 0x7b }, /* '"' => '{' */
{ 0x27, 0x5b }, /* '\'' => '[' */
{ 0x3c, 0x3b }, /* '<' => ';' */
diff --git a/src/hci/keymap/keymap_az.c b/src/hci/keymap/keymap_az.c
index 27ce91e..525ab23 100644
--- a/src/hci/keymap/keymap_az.c
+++ b/src/hci/keymap/keymap_az.c
@@ -12,7 +12,7 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "az" keyboard mapping */
struct key_mapping az_mapping[] __keymap = {
- { 0x23, 0x27 }, /* '#' => '\'' */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x24, 0x3b }, /* '$' => ';' */
{ 0x26, 0x3f }, /* '&' => '?' */
{ 0x2f, 0x2e }, /* '/' => '.' */
diff --git a/src/hci/keymap/keymap_cz.c b/src/hci/keymap/keymap_cz.c
index 9280f84..2b4a215 100644
--- a/src/hci/keymap/keymap_cz.c
+++ b/src/hci/keymap/keymap_cz.c
@@ -12,16 +12,35 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "cz" keyboard mapping */
struct key_mapping cz_mapping[] __keymap = {
- { 0x21, 0x2b }, /* '!' => '+' */
+ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
+ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x1f, 0x1c }, /* 0x1f => 0x1c */
+ { 0x21, 0x31 }, /* '!' => '1' */
+ { 0x22, 0x21 }, /* '"' => '!' */
+ { 0x23, 0x33 }, /* '#' => '3' */
+ { 0x24, 0x34 }, /* '$' => '4' */
+ { 0x25, 0x35 }, /* '%' => '5' */
+ { 0x26, 0x37 }, /* '&' => '7' */
+ { 0x28, 0x39 }, /* '(' => '9' */
+ { 0x29, 0x30 }, /* ')' => '0' */
+ { 0x2a, 0x38 }, /* '*' => '8' */
{ 0x2d, 0x3d }, /* '-' => '=' */
{ 0x2f, 0x2d }, /* '/' => '-' */
{ 0x31, 0x2b }, /* '1' => '+' */
- { 0x3c, 0x2c }, /* '<' => ',' */
- { 0x3e, 0x2e }, /* '>' => '.' */
- { 0x3f, 0x2d }, /* '?' => '-' */
+ { 0x3a, 0x22 }, /* ':' => '"' */
+ { 0x3c, 0x3f }, /* '<' => '?' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x32 }, /* '@' => '2' */
+ { 0x59, 0x5a }, /* 'Y' => 'Z' */
+ { 0x5a, 0x59 }, /* 'Z' => 'Y' */
{ 0x5d, 0x29 }, /* ']' => ')' */
- { 0x5f, 0x3d }, /* '_' => '=' */
+ { 0x5e, 0x36 }, /* '^' => '6' */
+ { 0x5f, 0x25 }, /* '_' => '%' */
{ 0x60, 0x3b }, /* '`' => ';' */
- { 0x7d, 0x29 }, /* '}' => ')' */
- { 0x7e, 0x3b }, /* '~' => ';' */
+ { 0x79, 0x7a }, /* 'y' => 'z' */
+ { 0x7a, 0x79 }, /* 'z' => 'y' */
+ { 0x7b, 0x2f }, /* '{' => '/' */
+ { 0x7c, 0x27 }, /* '|' => '\'' */
+ { 0x7d, 0x28 }, /* '}' => '(' */
};
diff --git a/src/hci/keymap/keymap_de.c b/src/hci/keymap/keymap_de.c
index ffcf912..2559e15 100644
--- a/src/hci/keymap/keymap_de.c
+++ b/src/hci/keymap/keymap_de.c
@@ -14,33 +14,26 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
struct key_mapping de_mapping[] __keymap = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
- { 0x22, 0x7d }, /* '"' => '}' */
+ { 0x1c, 0x23 }, /* 0x1c => '#' */
+ { 0x1d, 0x1e }, /* 0x1d => 0x1e */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
- { 0x27, 0x5d }, /* '\'' => ']' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
{ 0x2a, 0x28 }, /* '*' => '(' */
- { 0x2b, 0x60 }, /* '+' => '`' */
- { 0x2d, 0x5c }, /* '-' => '\\' */
{ 0x2f, 0x2d }, /* '/' => '-' */
- { 0x3a, 0x7b }, /* ':' => '{' */
- { 0x3b, 0x5b }, /* ';' => '[' */
{ 0x3c, 0x3b }, /* '<' => ';' */
- { 0x3d, 0x27 }, /* '=' => '\'' */
{ 0x3e, 0x3a }, /* '>' => ':' */
{ 0x3f, 0x5f }, /* '?' => '_' */
{ 0x40, 0x22 }, /* '@' => '"' */
{ 0x59, 0x5a }, /* 'Y' => 'Z' */
{ 0x5a, 0x59 }, /* 'Z' => 'Y' */
- { 0x5b, 0x40 }, /* '[' => '@' */
{ 0x5c, 0x23 }, /* '\\' => '#' */
{ 0x5d, 0x2b }, /* ']' => '+' */
{ 0x5e, 0x26 }, /* '^' => '&' */
{ 0x5f, 0x3f }, /* '_' => '?' */
- { 0x60, 0x5e }, /* '`' => '^' */
{ 0x79, 0x7a }, /* 'y' => 'z' */
{ 0x7a, 0x79 }, /* 'z' => 'y' */
- { 0x7b, 0x5c }, /* '{' => '\\' */
{ 0x7c, 0x27 }, /* '|' => '\'' */
{ 0x7d, 0x2a }, /* '}' => '*' */
};
diff --git a/src/hci/keymap/keymap_dk.c b/src/hci/keymap/keymap_dk.c
index e409018..05110dc 100644
--- a/src/hci/keymap/keymap_dk.c
+++ b/src/hci/keymap/keymap_dk.c
@@ -12,11 +12,12 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "dk" keyboard mapping */
struct key_mapping dk_mapping[] __keymap = {
+ { 0x1c, 0x27 }, /* 0x1c => '\'' */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
{ 0x2a, 0x28 }, /* '*' => '(' */
- { 0x2b, 0x60 }, /* '+' => '`' */
{ 0x2d, 0x2b }, /* '-' => '+' */
{ 0x2f, 0x2d }, /* '/' => '-' */
{ 0x3c, 0x3b }, /* '<' => ';' */
@@ -27,5 +28,4 @@ struct key_mapping dk_mapping[] __keymap = {
{ 0x5e, 0x26 }, /* '^' => '&' */
{ 0x5f, 0x3f }, /* '_' => '?' */
{ 0x7c, 0x2a }, /* '|' => '*' */
- { 0x7d, 0x5e }, /* '}' => '^' */
};
diff --git a/src/hci/keymap/keymap_es.c b/src/hci/keymap/keymap_es.c
index c1fe013..51dedff 100644
--- a/src/hci/keymap/keymap_es.c
+++ b/src/hci/keymap/keymap_es.c
@@ -12,6 +12,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "es" keyboard mapping */
struct key_mapping es_mapping[] __keymap = {
+ { 0x1c, 0x1d }, /* 0x1c => 0x1d */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
diff --git a/src/hci/keymap/keymap_et.c b/src/hci/keymap/keymap_et.c
index ad88cec..dd0f879 100644
--- a/src/hci/keymap/keymap_et.c
+++ b/src/hci/keymap/keymap_et.c
@@ -26,5 +26,4 @@ struct key_mapping et_mapping[] __keymap = {
{ 0x5e, 0x26 }, /* '^' => '&' */
{ 0x5f, 0x3f }, /* '_' => '?' */
{ 0x7c, 0x2a }, /* '|' => '*' */
- { 0x7f, 0x1b }, /* 0x7f => 0x1b */
};
diff --git a/src/hci/keymap/keymap_fi.c b/src/hci/keymap/keymap_fi.c
index c8f6c3a..c489bf0 100644
--- a/src/hci/keymap/keymap_fi.c
+++ b/src/hci/keymap/keymap_fi.c
@@ -12,27 +12,18 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "fi" keyboard mapping */
struct key_mapping fi_mapping[] __keymap = {
- { 0x22, 0x5b }, /* '"' => '[' */
{ 0x26, 0x2f }, /* '&' => '/' */
- { 0x27, 0x7b }, /* '\'' => '{' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
{ 0x2a, 0x28 }, /* '*' => '(' */
- { 0x2b, 0x60 }, /* '+' => '`' */
{ 0x2d, 0x2b }, /* '-' => '+' */
{ 0x2f, 0x2d }, /* '/' => '-' */
- { 0x3a, 0x5c }, /* ':' => '\\' */
- { 0x3b, 0x7c }, /* ';' => '|' */
{ 0x3c, 0x3b }, /* '<' => ';' */
- { 0x3d, 0x27 }, /* '=' => '\'' */
{ 0x3e, 0x3a }, /* '>' => ':' */
{ 0x3f, 0x5f }, /* '?' => '_' */
{ 0x40, 0x22 }, /* '@' => '"' */
- { 0x5b, 0x7d }, /* '[' => '}' */
{ 0x5c, 0x27 }, /* '\\' => '\'' */
{ 0x5e, 0x26 }, /* '^' => '&' */
{ 0x5f, 0x3f }, /* '_' => '?' */
- { 0x7b, 0x5d }, /* '{' => ']' */
{ 0x7c, 0x2a }, /* '|' => '*' */
- { 0x7d, 0x5e }, /* '}' => '^' */
};
diff --git a/src/hci/keymap/keymap_fr.c b/src/hci/keymap/keymap_fr.c
index fd615a4..8f3b499 100644
--- a/src/hci/keymap/keymap_fr.c
+++ b/src/hci/keymap/keymap_fr.c
@@ -16,13 +16,16 @@ struct key_mapping fr_mapping[] __keymap = {
{ 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */
{ 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */
{ 0x1a, 0x17 }, /* Ctrl-Z => Ctrl-W */
+ { 0x1c, 0x2a }, /* 0x1c => '*' */
+ { 0x1d, 0x24 }, /* 0x1d => '$' */
+ { 0x1e, 0x1c }, /* 0x1e => 0x1c */
+ { 0x1f, 0x1d }, /* 0x1f => 0x1d */
{ 0x21, 0x31 }, /* '!' => '1' */
{ 0x22, 0x25 }, /* '"' => '%' */
{ 0x23, 0x33 }, /* '#' => '3' */
{ 0x24, 0x34 }, /* '$' => '4' */
{ 0x25, 0x35 }, /* '%' => '5' */
{ 0x26, 0x37 }, /* '&' => '7' */
- { 0x27, 0x7c }, /* '\'' => '|' */
{ 0x28, 0x39 }, /* '(' => '9' */
{ 0x29, 0x30 }, /* ')' => '0' */
{ 0x2a, 0x38 }, /* '*' => '8' */
@@ -30,39 +33,28 @@ struct key_mapping fr_mapping[] __keymap = {
{ 0x2d, 0x29 }, /* '-' => ')' */
{ 0x2e, 0x3a }, /* '.' => ':' */
{ 0x2f, 0x21 }, /* '/' => '!' */
- { 0x30, 0x40 }, /* '0' => '@' */
{ 0x31, 0x26 }, /* '1' => '&' */
- { 0x32, 0x7b }, /* '2' => '{' */
{ 0x33, 0x22 }, /* '3' => '"' */
{ 0x34, 0x27 }, /* '4' => '\'' */
{ 0x35, 0x28 }, /* '5' => '(' */
{ 0x36, 0x2d }, /* '6' => '-' */
- { 0x37, 0x7d }, /* '7' => '}' */
{ 0x38, 0x5f }, /* '8' => '_' */
- { 0x39, 0x2f }, /* '9' => '/' */
{ 0x3a, 0x4d }, /* ':' => 'M' */
{ 0x3b, 0x6d }, /* ';' => 'm' */
{ 0x3c, 0x2e }, /* '<' => '.' */
{ 0x3e, 0x2f }, /* '>' => '/' */
- { 0x3f, 0x5c }, /* '?' => '\\' */
{ 0x40, 0x32 }, /* '@' => '2' */
{ 0x41, 0x51 }, /* 'A' => 'Q' */
{ 0x4d, 0x3f }, /* 'M' => '?' */
{ 0x51, 0x41 }, /* 'Q' => 'A' */
{ 0x57, 0x5a }, /* 'W' => 'Z' */
{ 0x5a, 0x57 }, /* 'Z' => 'W' */
- { 0x5b, 0x5e }, /* '[' => '^' */
{ 0x5c, 0x2a }, /* '\\' => '*' */
{ 0x5d, 0x24 }, /* ']' => '$' */
{ 0x5e, 0x36 }, /* '^' => '6' */
- { 0x5f, 0x5d }, /* '_' => ']' */
- { 0x60, 0x2a }, /* '`' => '*' */
{ 0x61, 0x71 }, /* 'a' => 'q' */
{ 0x6d, 0x2c }, /* 'm' => ',' */
{ 0x71, 0x61 }, /* 'q' => 'a' */
{ 0x77, 0x7a }, /* 'w' => 'z' */
{ 0x7a, 0x77 }, /* 'z' => 'w' */
- { 0x7b, 0x3c }, /* '{' => '<' */
- { 0x7c, 0x23 }, /* '|' => '#' */
- { 0x7d, 0x3e }, /* '}' => '>' */
};
diff --git a/src/hci/keymap/keymap_hu.c b/src/hci/keymap/keymap_hu.c
index 68eff2f..a2eadbc 100644
--- a/src/hci/keymap/keymap_hu.c
+++ b/src/hci/keymap/keymap_hu.c
@@ -14,6 +14,7 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
struct key_mapping hu_mapping[] __keymap = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x21, 0x27 }, /* '!' => '\'' */
{ 0x23, 0x2b }, /* '#' => '+' */
{ 0x24, 0x21 }, /* '$' => '!' */
diff --git a/src/hci/keymap/keymap_il.c b/src/hci/keymap/keymap_il.c
index 478330c..f631f7a 100644
--- a/src/hci/keymap/keymap_il.c
+++ b/src/hci/keymap/keymap_il.c
@@ -12,4 +12,16 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "il" keyboard mapping */
struct key_mapping il_mapping[] __keymap = {
+ { 0x1d, 0x1b }, /* 0x1d => 0x1b */
+ { 0x27, 0x2c }, /* '\'' => ',' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x28 }, /* ')' => '(' */
+ { 0x2f, 0x2e }, /* '/' => '.' */
+ { 0x3c, 0x3e }, /* '<' => '>' */
+ { 0x3e, 0x3c }, /* '>' => '<' */
+ { 0x5b, 0x5d }, /* '[' => ']' */
+ { 0x5d, 0x5b }, /* ']' => '[' */
+ { 0x60, 0x3b }, /* '`' => ';' */
+ { 0x7b, 0x7d }, /* '{' => '}' */
+ { 0x7d, 0x7b }, /* '}' => '{' */
};
diff --git a/src/hci/keymap/keymap_it.c b/src/hci/keymap/keymap_it.c
index 5bb0547..d96102c 100644
--- a/src/hci/keymap/keymap_it.c
+++ b/src/hci/keymap/keymap_it.c
@@ -12,6 +12,7 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "it" keyboard mapping */
struct key_mapping it_mapping[] __keymap = {
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
diff --git a/src/hci/keymap/keymap_mt.c b/src/hci/keymap/keymap_mt.c
index 094a6fc..dfca2ff 100644
--- a/src/hci/keymap/keymap_mt.c
+++ b/src/hci/keymap/keymap_mt.c
@@ -12,8 +12,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "mt" keyboard mapping */
struct key_mapping mt_mapping[] __keymap = {
+ { 0x1c, 0x1e }, /* 0x1c => 0x1e */
{ 0x22, 0x40 }, /* '"' => '@' */
- { 0x23, 0x04 }, /* '#' => Ctrl-D */
{ 0x40, 0x22 }, /* '@' => '"' */
{ 0x5c, 0x23 }, /* '\\' => '#' */
{ 0x7c, 0x7e }, /* '|' => '~' */
diff --git a/src/hci/keymap/keymap_nl.c b/src/hci/keymap/keymap_nl.c
index ba05170..2a0fbbc 100644
--- a/src/hci/keymap/keymap_nl.c
+++ b/src/hci/keymap/keymap_nl.c
@@ -12,11 +12,13 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "nl" keyboard mapping */
struct key_mapping nl_mapping[] __keymap = {
+ { 0x1c, 0x3c }, /* 0x1c => '<' */
+ { 0x1d, 0x1c }, /* 0x1d => 0x1c */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x5f }, /* '&' => '_' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x27 }, /* ')' => '\'' */
{ 0x2a, 0x28 }, /* '*' => '(' */
- { 0x2b, 0x7e }, /* '+' => '~' */
{ 0x2d, 0x2f }, /* '-' => '/' */
{ 0x2f, 0x2d }, /* '/' => '-' */
{ 0x3b, 0x2b }, /* ';' => '+' */
diff --git a/src/hci/keymap/keymap_no-latin1.c b/src/hci/keymap/keymap_no-latin1.c
index 8c3e81b..655e4ce 100644
--- a/src/hci/keymap/keymap_no-latin1.c
+++ b/src/hci/keymap/keymap_no-latin1.c
@@ -12,6 +12,7 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "no-latin1" keyboard mapping */
struct key_mapping no_latin1_mapping[] __keymap = {
+ { 0x1d, 0x1e }, /* 0x1d => 0x1e */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
diff --git a/src/hci/keymap/keymap_no.c b/src/hci/keymap/keymap_no.c
index 45cf9e8..7a2df7c 100644
--- a/src/hci/keymap/keymap_no.c
+++ b/src/hci/keymap/keymap_no.c
@@ -12,94 +12,22 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "no" keyboard mapping */
struct key_mapping no_mapping[] __keymap = {
- { 0x02, 0x18 }, /* Ctrl-B => Ctrl-X */
- { 0x03, 0x0a }, /* Ctrl-C => Ctrl-J */
- { 0x04, 0x05 }, /* Ctrl-D => Ctrl-E */
- { 0x06, 0x15 }, /* Ctrl-F => Ctrl-U */
- { 0x07, 0x09 }, /* Ctrl-G => Ctrl-I */
- { 0x08, 0x04 }, /* Ctrl-H => Ctrl-D */
- { 0x0a, 0x08 }, /* Ctrl-J => Ctrl-H */
- { 0x0b, 0x14 }, /* Ctrl-K => Ctrl-T */
- { 0x0c, 0x0e }, /* Ctrl-L => Ctrl-N */
- { 0x0e, 0x02 }, /* Ctrl-N => Ctrl-B */
- { 0x0f, 0x12 }, /* Ctrl-O => Ctrl-R */
- { 0x10, 0x0c }, /* Ctrl-P => Ctrl-L */
- { 0x12, 0x10 }, /* Ctrl-R => Ctrl-P */
- { 0x13, 0x0f }, /* Ctrl-S => Ctrl-O */
- { 0x14, 0x19 }, /* Ctrl-T => Ctrl-Y */
- { 0x15, 0x07 }, /* Ctrl-U => Ctrl-G */
- { 0x16, 0x0b }, /* Ctrl-V => Ctrl-K */
- { 0x18, 0x11 }, /* Ctrl-X => Ctrl-Q */
- { 0x19, 0x06 }, /* Ctrl-Y => Ctrl-F */
- { 0x22, 0x5f }, /* '"' => '_' */
+ { 0x1c, 0x27 }, /* 0x1c => '\'' */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
- { 0x27, 0x2d }, /* '\'' => '-' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
{ 0x2a, 0x28 }, /* '*' => '(' */
- { 0x2b, 0x60 }, /* '+' => '`' */
- { 0x2c, 0x77 }, /* ',' => 'w' */
{ 0x2d, 0x2b }, /* '-' => '+' */
- { 0x2e, 0x76 }, /* '.' => 'v' */
- { 0x2f, 0x7a }, /* '/' => 'z' */
- { 0x3a, 0x53 }, /* ':' => 'S' */
- { 0x3b, 0x73 }, /* ';' => 's' */
- { 0x3c, 0x57 }, /* '<' => 'W' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
{ 0x3d, 0x5c }, /* '=' => '\\' */
- { 0x3e, 0x56 }, /* '>' => 'V' */
- { 0x3f, 0x5a }, /* '?' => 'Z' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
{ 0x40, 0x22 }, /* '@' => '"' */
- { 0x42, 0x58 }, /* 'B' => 'X' */
- { 0x43, 0x4a }, /* 'C' => 'J' */
- { 0x44, 0x45 }, /* 'D' => 'E' */
- { 0x45, 0x3a }, /* 'E' => ':' */
- { 0x46, 0x55 }, /* 'F' => 'U' */
- { 0x47, 0x49 }, /* 'G' => 'I' */
- { 0x48, 0x44 }, /* 'H' => 'D' */
- { 0x49, 0x43 }, /* 'I' => 'C' */
- { 0x4a, 0x48 }, /* 'J' => 'H' */
- { 0x4b, 0x54 }, /* 'K' => 'T' */
- { 0x4c, 0x4e }, /* 'L' => 'N' */
- { 0x4e, 0x42 }, /* 'N' => 'B' */
- { 0x4f, 0x52 }, /* 'O' => 'R' */
- { 0x50, 0x4c }, /* 'P' => 'L' */
- { 0x52, 0x50 }, /* 'R' => 'P' */
- { 0x53, 0x4f }, /* 'S' => 'O' */
- { 0x54, 0x59 }, /* 'T' => 'Y' */
- { 0x55, 0x47 }, /* 'U' => 'G' */
- { 0x56, 0x4b }, /* 'V' => 'K' */
- { 0x57, 0x3b }, /* 'W' => ';' */
- { 0x58, 0x51 }, /* 'X' => 'Q' */
- { 0x59, 0x46 }, /* 'Y' => 'F' */
- { 0x5b, 0x27 }, /* '[' => '\'' */
- { 0x5c, 0x3c }, /* '\\' => '<' */
- { 0x5d, 0x7e }, /* ']' => '~' */
+ { 0x5c, 0x27 }, /* '\\' => '\'' */
{ 0x5e, 0x26 }, /* '^' => '&' */
{ 0x5f, 0x3f }, /* '_' => '?' */
{ 0x60, 0x7c }, /* '`' => '|' */
- { 0x62, 0x78 }, /* 'b' => 'x' */
- { 0x63, 0x6a }, /* 'c' => 'j' */
- { 0x64, 0x65 }, /* 'd' => 'e' */
- { 0x65, 0x2e }, /* 'e' => '.' */
- { 0x66, 0x75 }, /* 'f' => 'u' */
- { 0x67, 0x69 }, /* 'g' => 'i' */
- { 0x68, 0x64 }, /* 'h' => 'd' */
- { 0x69, 0x63 }, /* 'i' => 'c' */
- { 0x6a, 0x68 }, /* 'j' => 'h' */
- { 0x6b, 0x74 }, /* 'k' => 't' */
- { 0x6c, 0x6e }, /* 'l' => 'n' */
- { 0x6e, 0x62 }, /* 'n' => 'b' */
- { 0x6f, 0x72 }, /* 'o' => 'r' */
- { 0x70, 0x6c }, /* 'p' => 'l' */
- { 0x72, 0x70 }, /* 'r' => 'p' */
- { 0x73, 0x6f }, /* 's' => 'o' */
- { 0x74, 0x79 }, /* 't' => 'y' */
- { 0x75, 0x67 }, /* 'u' => 'g' */
- { 0x76, 0x6b }, /* 'v' => 'k' */
- { 0x77, 0x2c }, /* 'w' => ',' */
- { 0x78, 0x71 }, /* 'x' => 'q' */
- { 0x79, 0x66 }, /* 'y' => 'f' */
- { 0x7b, 0x2a }, /* '{' => '*' */
- { 0x7c, 0x3e }, /* '|' => '>' */
- { 0x7d, 0x5e }, /* '}' => '^' */
+ { 0x7c, 0x2a }, /* '|' => '*' */
};
diff --git a/src/hci/keymap/keymap_pt.c b/src/hci/keymap/keymap_pt.c
index a8e44b6..b993902 100644
--- a/src/hci/keymap/keymap_pt.c
+++ b/src/hci/keymap/keymap_pt.c
@@ -12,18 +12,21 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "pt" keyboard mapping */
struct key_mapping pt_mapping[] __keymap = {
- { 0x1c, 0x1d }, /* 0x1c => 0x1d */
- { 0x1d, 0x1b }, /* 0x1d => 0x1b */
- { 0x22, 0x5e }, /* '"' => '^' */
- { 0x27, 0x7e }, /* '\'' => '~' */
- { 0x2f, 0x3b }, /* '/' => ';' */
- { 0x3f, 0x3a }, /* '?' => ':' */
- { 0x5b, 0x27 }, /* '[' => '\'' */
- { 0x5c, 0x5d }, /* '\\' => ']' */
- { 0x5d, 0x5b }, /* ']' => '[' */
- { 0x60, 0x27 }, /* '`' => '\'' */
- { 0x7b, 0x60 }, /* '{' => '`' */
- { 0x7c, 0x7d }, /* '|' => '}' */
- { 0x7d, 0x7b }, /* '}' => '{' */
- { 0x7e, 0x22 }, /* '~' => '"' */
+ { 0x1e, 0x36 }, /* 0x1e => '6' */
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2d, 0x27 }, /* '-' => '\'' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5b, 0x2b }, /* '[' => '+' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x60, 0x5c }, /* '`' => '\\' */
+ { 0x7b, 0x2a }, /* '{' => '*' */
+ { 0x7e, 0x7c }, /* '~' => '|' */
};
diff --git a/src/hci/keymap/keymap_ru.c b/src/hci/keymap/keymap_ru.c
index 422b6c6..c120ffd 100644
--- a/src/hci/keymap/keymap_ru.c
+++ b/src/hci/keymap/keymap_ru.c
@@ -12,4 +12,5 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
/** "ru" keyboard mapping */
struct key_mapping ru_mapping[] __keymap = {
+ { 0x0d, 0x0a }, /* Ctrl-M => Ctrl-J */
};
diff --git a/src/hci/keymap/keymap_bg.c b/src/hci/keymap/keymap_sr-latin.c
index 62b6bae..9d76e8a 100644
--- a/src/hci/keymap/keymap_bg.c
+++ b/src/hci/keymap/keymap_sr-latin.c
@@ -1,6 +1,6 @@
/** @file
*
- * "bg" keyboard mapping
+ * "sr-latin" keyboard mapping
*
* This file is automatically generated; do not edit
*
@@ -10,6 +10,6 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h>
-/** "bg" keyboard mapping */
-struct key_mapping bg_mapping[] __keymap = {
+/** "sr-latin" keyboard mapping */
+struct key_mapping sr_latin_mapping[] __keymap = {
};
diff --git a/src/hci/keymap/keymap_sr.c b/src/hci/keymap/keymap_sr.c
deleted file mode 100644
index 0552f4d..0000000
--- a/src/hci/keymap/keymap_sr.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/** @file
- *
- * "sr" keyboard mapping
- *
- * This file is automatically generated; do not edit
- *
- */
-
-FILE_LICENCE ( PUBLIC_DOMAIN );
-
-#include <ipxe/keymap.h>
-
-/** "sr" keyboard mapping */
-struct key_mapping sr_mapping[] __keymap = {
- { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
- { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
- { 0x26, 0x2f }, /* '&' => '/' */
- { 0x28, 0x29 }, /* '(' => ')' */
- { 0x29, 0x3d }, /* ')' => '=' */
- { 0x2a, 0x28 }, /* '*' => '(' */
- { 0x2b, 0x2a }, /* '+' => '*' */
- { 0x2d, 0x27 }, /* '-' => '\'' */
- { 0x2f, 0x2d }, /* '/' => '-' */
- { 0x3c, 0x3b }, /* '<' => ';' */
- { 0x3d, 0x2b }, /* '=' => '+' */
- { 0x3e, 0x3a }, /* '>' => ':' */
- { 0x3f, 0x5f }, /* '?' => '_' */
- { 0x40, 0x22 }, /* '@' => '"' */
- { 0x59, 0x5a }, /* 'Y' => 'Z' */
- { 0x5a, 0x59 }, /* 'Z' => 'Y' */
- { 0x5e, 0x26 }, /* '^' => '&' */
- { 0x5f, 0x3f }, /* '_' => '?' */
- { 0x79, 0x7a }, /* 'y' => 'z' */
- { 0x7a, 0x79 }, /* 'z' => 'y' */
-};
diff --git a/src/hci/keymap/keymap_th.c b/src/hci/keymap/keymap_th.c
deleted file mode 100644
index e8b44d1..0000000
--- a/src/hci/keymap/keymap_th.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/** @file
- *
- * "th" keyboard mapping
- *
- * This file is automatically generated; do not edit
- *
- */
-
-FILE_LICENCE ( PUBLIC_DOMAIN );
-
-#include <ipxe/keymap.h>
-
-/** "th" keyboard mapping */
-struct key_mapping th_mapping[] __keymap = {
-};
diff --git a/src/hci/keymap/keymap_wo.c b/src/hci/keymap/keymap_wo.c
deleted file mode 100644
index b453576..0000000
--- a/src/hci/keymap/keymap_wo.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/** @file
- *
- * "wo" keyboard mapping
- *
- * This file is automatically generated; do not edit
- *
- */
-
-FILE_LICENCE ( PUBLIC_DOMAIN );
-
-#include <ipxe/keymap.h>
-
-/** "wo" keyboard mapping */
-struct key_mapping wo_mapping[] __keymap = {
- { 0x01, 0x11 }, /* Ctrl-A => Ctrl-Q */
- { 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */
- { 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */
- { 0x1a, 0x17 }, /* Ctrl-Z => Ctrl-W */
- { 0x21, 0x31 }, /* '!' => '1' */
- { 0x23, 0x33 }, /* '#' => '3' */
- { 0x24, 0x34 }, /* '$' => '4' */
- { 0x25, 0x35 }, /* '%' => '5' */
- { 0x26, 0x37 }, /* '&' => '7' */
- { 0x28, 0x39 }, /* '(' => '9' */
- { 0x29, 0x30 }, /* ')' => '0' */
- { 0x2a, 0x38 }, /* '*' => '8' */
- { 0x2c, 0x3b }, /* ',' => ';' */
- { 0x2d, 0x29 }, /* '-' => ')' */
- { 0x2e, 0x3a }, /* '.' => ':' */
- { 0x2f, 0x21 }, /* '/' => '!' */
- { 0x31, 0x26 }, /* '1' => '&' */
- { 0x33, 0x22 }, /* '3' => '"' */
- { 0x34, 0x27 }, /* '4' => '\'' */
- { 0x35, 0x28 }, /* '5' => '(' */
- { 0x36, 0x2d }, /* '6' => '-' */
- { 0x38, 0x5f }, /* '8' => '_' */
- { 0x3a, 0x4d }, /* ':' => 'M' */
- { 0x3b, 0x6d }, /* ';' => 'm' */
- { 0x3c, 0x2e }, /* '<' => '.' */
- { 0x3e, 0x2f }, /* '>' => '/' */
- { 0x40, 0x32 }, /* '@' => '2' */
- { 0x41, 0x51 }, /* 'A' => 'Q' */
- { 0x4d, 0x3f }, /* 'M' => '?' */
- { 0x51, 0x41 }, /* 'Q' => 'A' */
- { 0x57, 0x5a }, /* 'W' => 'Z' */
- { 0x5a, 0x57 }, /* 'Z' => 'W' */
- { 0x5d, 0x24 }, /* ']' => '$' */
- { 0x5e, 0x36 }, /* '^' => '6' */
- { 0x61, 0x71 }, /* 'a' => 'q' */
- { 0x6d, 0x2c }, /* 'm' => ',' */
- { 0x71, 0x61 }, /* 'q' => 'a' */
- { 0x77, 0x7a }, /* 'w' => 'z' */
- { 0x7a, 0x77 }, /* 'z' => 'w' */
- { 0x7e, 0x25 }, /* '~' => '%' */
-};
diff --git a/src/util/genkeymap.pl b/src/util/genkeymap.pl
deleted file mode 100755
index 7a5024b..0000000
--- a/src/util/genkeymap.pl
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-=head1 NAME
-
-genkeymap.pl
-
-=head1 SYNOPSIS
-
-genkeymap.pl [options] <keymap name>
-
-Options:
-
- -f,--from=<name> Set BIOS keymap name (default "us")
- -h,--help Display brief help message
- -v,--verbose Increase verbosity
- -q,--quiet Decrease verbosity
-
-=cut
-
-# With reference to:
-#
-# http://gunnarwrobel.de/wiki/Linux-and-the-keyboard.html
-
-use Getopt::Long;
-use Pod::Usage;
-use strict;
-use warnings;
-
-use constant BIOS_KEYMAP => "us";
-use constant BKEYMAP_MAGIC => "bkeymap";
-use constant MAX_NR_KEYMAPS => 256;
-use constant NR_KEYS => 128;
-use constant KG_SHIFT => 0;
-use constant KG_ALTGR => 1;
-use constant KG_CTRL => 2;
-use constant KG_ALT => 3;
-use constant KG_SHIFTL => 4;
-use constant KG_KANASHIFT => 4;
-use constant KG_SHIFTR => 5;
-use constant KG_CTRLL => 6;
-use constant KG_CTRLR => 7;
-use constant KG_CAPSSHIFT => 8;
-use constant KT_LATIN => 0;
-use constant KT_FN => 1;
-use constant KT_SPEC => 2;
-use constant KT_PAD => 3;
-use constant KT_DEAD => 4;
-use constant KT_CONS => 5;
-use constant KT_CUR => 6;
-use constant KT_SHIFT => 7;
-use constant KT_META => 8;
-use constant KT_ASCII => 9;
-use constant KT_LOCK => 10;
-use constant KT_LETTER => 11;
-use constant KT_SLOCK => 12;
-use constant KT_SPKUP => 14;
-
-my $verbosity = 1;
-my $from_name = BIOS_KEYMAP;
-
-# Read named keymaps using "loadkeys -b"
-#
-sub read_keymaps {
- my $name = shift;
- my $keymaps = [];
-
- # Generate binary keymap
- open my $pipe, "-|", "loadkeys", "-b", $name
- or die "Could not load keymap \"".$name."\": $!\n";
-
- # Check magic
- read $pipe, my $magic, length BKEYMAP_MAGIC
- or die "Could not read from \"".$name."\": $!\n";
- die "Bad magic value from \"".$name."\"\n"
- unless $magic eq BKEYMAP_MAGIC;
-
- # Read list of included keymaps
- read $pipe, my $included, MAX_NR_KEYMAPS
- or die "Could not read from \"".$name."\": $!\n";
- my @included = unpack ( "C*", $included );
- die "Missing or truncated keymap list from \"".$name."\"\n"
- unless @included == MAX_NR_KEYMAPS;
-
- # Read each keymap in turn
- for ( my $keymap = 0 ; $keymap < MAX_NR_KEYMAPS ; $keymap++ ) {
- if ( $included[$keymap] ) {
- read $pipe, my $keysyms, ( NR_KEYS * 2 )
- or die "Could not read from \"".$name."\": $!\n";
- my @keysyms = unpack ( "S*", $keysyms );
- die "Missing or truncated keymap ".$keymap." from \"".$name."\"\n"
- unless @keysyms == NR_KEYS;
- push @$keymaps, \@keysyms;
- } else {
- push @$keymaps, undef;
- }
- }
-
- close $pipe;
- return $keymaps;
-}
-
-# Translate keysym value to ASCII
-#
-sub keysym_to_ascii {
- my $keysym = shift;
-
- # Non-existent keysyms have no ASCII equivalent
- return unless $keysym;
-
- # Sanity check
- if ( $keysym & 0xf000 ) {
- warn "Unexpected keysym ".sprintf ( "0x%04x", $keysym )."\n";
- return;
- }
-
- # Extract type and value
- my $type = ( $keysym >> 8 );
- my $value = ( $keysym & 0xff );
-
- # Non-simple types have no ASCII equivalent
- return unless ( ( $type == KT_LATIN ) || ( $type == KT_ASCII ) ||
- ( $type == KT_LETTER ) );
-
- # High-bit-set characters cannot be generated on a US keyboard
- return if $value & 0x80;
-
- return $value;
-}
-
-# Translate ASCII to descriptive name
-#
-sub ascii_to_name {
- my $ascii = shift;
-
- if ( $ascii == 0x5c ) {
- return "'\\\\'";
- } elsif ( $ascii == 0x27 ) {
- return "'\\\''";
- } elsif ( ( $ascii >= 0x20 ) && ( $ascii <= 0x7e ) ) {
- return sprintf ( "'%c'", $ascii );
- } elsif ( $ascii <= 0x1a ) {
- return sprintf ( "Ctrl-%c", ( 0x40 + $ascii ) );
- } else {
- return sprintf ( "0x%02x", $ascii );
- }
-}
-
-# Produce translation table between two keymaps
-#
-sub translate_keymaps {
- my $from = shift;
- my $to = shift;
- my $map = {};
-
- foreach my $keymap ( 0, 1 << KG_SHIFT, 1 << KG_CTRL ) {
- for ( my $keycode = 0 ; $keycode < NR_KEYS ; $keycode++ ) {
- my $from_ascii = keysym_to_ascii ( $from->[$keymap]->[$keycode] )
- or next;
- my $to_ascii = keysym_to_ascii ( $to->[$keymap]->[$keycode] )
- or next;
- my $new_map = ( ! exists $map->{$from_ascii} );
- my $update_map =
- ( $new_map || ( $keycode < $map->{$from_ascii}->{keycode} ) );
- if ( ( $verbosity > 1 ) &&
- ( ( $from_ascii != $to_ascii ) ||
- ( $update_map && ! $new_map ) ) ) {
- printf STDERR "In keymap %d: %s => %s%s\n", $keymap,
- ascii_to_name ( $from_ascii ), ascii_to_name ( $to_ascii ),
- ( $update_map ? ( $new_map ? "" : " (override)" )
- : " (ignored)" );
- }
- if ( $update_map ) {
- $map->{$from_ascii} = {
- to_ascii => $to_ascii,
- keycode => $keycode,
- };
- }
- }
- }
- return { map { $_ => $map->{$_}->{to_ascii} } keys %$map };
-}
-
-# Parse command-line options
-Getopt::Long::Configure ( 'bundling', 'auto_abbrev' );
-GetOptions (
- 'verbose|v+' => sub { $verbosity++; },
- 'quiet|q+' => sub { $verbosity--; },
- 'from|f=s' => sub { shift; $from_name = shift; },
- 'help|h' => sub { pod2usage ( 1 ); },
-) or die "Could not parse command-line options\n";
-pod2usage ( 1 ) unless @ARGV == 1;
-my $to_name = shift;
-
-# Read and translate keymaps
-my $from = read_keymaps ( $from_name );
-my $to = read_keymaps ( $to_name );
-my $map = translate_keymaps ( $from, $to );
-
-# Generate output
-( my $to_name_c = $to_name ) =~ s/\W/_/g;
-printf "/** \@file\n";
-printf " *\n";
-printf " * \"".$to_name."\" keyboard mapping\n";
-printf " *\n";
-printf " * This file is automatically generated; do not edit\n";
-printf " *\n";
-printf " */\n";
-printf "\n";
-printf "FILE_LICENCE ( PUBLIC_DOMAIN );\n";
-printf "\n";
-printf "#include <ipxe/keymap.h>\n";
-printf "\n";
-printf "/** \"".$to_name."\" keyboard mapping */\n";
-printf "struct key_mapping ".$to_name_c."_mapping[] __keymap = {\n";
-foreach my $from_sym ( sort { $a <=> $b } keys %$map ) {
- my $to_sym = $map->{$from_sym};
- next if $from_sym == $to_sym;
- printf "\t{ 0x%02x, 0x%02x },\t/* %s => %s */\n", $from_sym, $to_sym,
- ascii_to_name ( $from_sym ), ascii_to_name ( $to_sym );
-}
-printf "};\n";
diff --git a/src/util/genkeymap.py b/src/util/genkeymap.py
new file mode 100755
index 0000000..1bb494f
--- /dev/null
+++ b/src/util/genkeymap.py
@@ -0,0 +1,346 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+"""Generate iPXE keymaps"""
+
+from __future__ import annotations
+
+import argparse
+from collections import UserDict
+from collections.abc import Sequence, Mapping, MutableMapping
+from dataclasses import dataclass
+from enum import Flag, IntEnum
+import re
+import subprocess
+from struct import Struct
+import textwrap
+from typing import ClassVar, Optional
+
+
+class KeyType(IntEnum):
+ """Key types"""
+
+ LATIN = 0
+ FN = 1
+ SPEC = 2
+ PAD = 3
+ DEAD = 4
+ CONS = 5
+ CUR = 6
+ SHIFT = 7
+ META = 8
+ ASCII = 9
+ LOCK = 10
+ LETTER = 11
+ SLOCK = 12
+ DEAD2 = 13
+ BRL = 14
+ UNKNOWN = 0xf0
+
+
+class KeyModifiers(Flag):
+ """Key modifiers"""
+
+ NONE = 0
+ SHIFT = 1
+ ALTGR = 2
+ CTRL = 4
+ ALT = 8
+ SHIFTL = 16
+ SHIFTR = 32
+ CTRLL = 64
+ CTRLR = 128
+
+ @property
+ def complexity(self) -> int:
+ """Get complexity value of applied modifiers"""
+ if self == self.NONE:
+ return 0
+ if self == self.SHIFT:
+ return 1
+ if self == self.CTRL:
+ return 2
+ return 3 + bin(self.value).count('1')
+
+
+@dataclass
+class Key:
+ """A single key definition"""
+
+ keycode: int
+ """Opaque keycode"""
+
+ keysym: int
+ """Key symbol"""
+
+ modifiers: KeyModifiers
+ """Applied modifiers"""
+
+ ASCII_TYPES: ClassVar[set[KeyType]] = {KeyType.LATIN, KeyType.ASCII,
+ KeyType.LETTER}
+ """Key types with direct ASCII values"""
+
+ @property
+ def keytype(self) -> Optional[KeyType]:
+ """Key type"""
+ try:
+ return KeyType(self.keysym >> 8)
+ except ValueError:
+ return None
+
+ @property
+ def value(self) -> int:
+ """Key value"""
+ return self.keysym & 0xff
+
+ @property
+ def ascii(self) -> Optional[str]:
+ """ASCII character"""
+ if self.keytype in self.ASCII_TYPES:
+ value = self.value
+ char = chr(value)
+ if value and char.isascii():
+ return char
+ return None
+
+
+class KeyMapping(UserDict[KeyModifiers, Sequence[Key]]):
+ """A keyboard mapping"""
+
+ BKEYMAP_MAGIC: ClassVar[bytes] = b'bkeymap'
+ """Magic signature for output produced by 'loadkeys -b'"""
+
+ MAX_NR_KEYMAPS: ClassVar[int] = 256
+ """Maximum number of keymaps produced by 'loadkeys -b'"""
+
+ NR_KEYS: ClassVar[int] = 128
+ """Number of keys in each keymap produced by 'loadkeys -b'"""
+
+ KEY_BACKSPACE: ClassVar[int] = 14
+ """Key code for backspace
+
+ Keyboard maps seem to somewhat arbitrarily pick an interpretation
+ for the backspace key and its various modifiers, according to the
+ personal preference of the keyboard map transcriber.
+ """
+
+ KEY_NON_US: ClassVar[int] = 86
+ """Key code 86
+
+ Key code 86 is somewhat bizarre. It doesn't physically exist on
+ most US keyboards. The database used by "loadkeys" defines it as
+ "<>", while most other databases either define it as a duplicate
+ "\\|" or omit it entirely.
+ """
+
+ FIXUPS: ClassVar[Mapping[str, Mapping[KeyModifiers,
+ Sequence[tuple[int, int]]]]] = {
+ 'us': {
+ # Redefine erroneous key 86 as generating "\\|"
+ KeyModifiers.NONE: [(KEY_NON_US, ord('\\'))],
+ KeyModifiers.SHIFT: [(KEY_NON_US, ord('|'))],
+ # Treat Ctrl-Backspace as producing Backspace rather than Ctrl-H
+ KeyModifiers.CTRL: [(KEY_BACKSPACE, 0x7f)],
+ },
+ }
+ """Fixups for erroneous keymappings produced by 'loadkeys -b'"""
+
+ @property
+ def unshifted(self):
+ """Basic unshifted key mapping"""
+ return self[KeyModifiers.NONE]
+
+ @property
+ def shifted(self):
+ """Basic shifted key mapping"""
+ return self[KeyModifiers.SHIFT]
+
+ @classmethod
+ def load(cls, name: str) -> KeyMapping:
+ """Load keymap using 'loadkeys -b'"""
+ bkeymap = subprocess.check_output(["loadkeys", "-u", "-b", name])
+ if not bkeymap.startswith(cls.BKEYMAP_MAGIC):
+ raise ValueError("Invalid bkeymap magic signature")
+ bkeymap = bkeymap[len(cls.BKEYMAP_MAGIC):]
+ included = bkeymap[:cls.MAX_NR_KEYMAPS]
+ if len(included) != cls.MAX_NR_KEYMAPS:
+ raise ValueError("Invalid bkeymap inclusion list")
+ keymaps = bkeymap[cls.MAX_NR_KEYMAPS:]
+ keys = {}
+ for modifiers in map(KeyModifiers, range(cls.MAX_NR_KEYMAPS)):
+ if included[modifiers.value]:
+ fmt = Struct('<%dH' % cls.NR_KEYS)
+ keymap = keymaps[:fmt.size]
+ if len(keymap) != fmt.size:
+ raise ValueError("Invalid bkeymap map %#x" %
+ modifiers.value)
+ keys[modifiers] = [
+ Key(modifiers=modifiers, keycode=keycode, keysym=keysym)
+ for keycode, keysym in enumerate(fmt.unpack(keymap))
+ ]
+ keymaps = keymaps[len(keymap):]
+ if keymaps:
+ raise ValueError("Trailing bkeymap data")
+ for modifiers, fixups in cls.FIXUPS.get(name, {}).items():
+ for keycode, keysym in fixups:
+ keys[modifiers][keycode] = Key(modifiers=modifiers,
+ keycode=keycode, keysym=keysym)
+ return cls(keys)
+
+ @property
+ def inverse(self) -> MutableMapping[str, Key]:
+ """Construct inverse mapping from ASCII value to key"""
+ return {
+ key.ascii: key
+ # Give priority to simplest modifier for a given ASCII code
+ for modifiers in sorted(self.keys(), reverse=True,
+ key=lambda x: (x.complexity, x.value))
+ # Give priority to lowest keycode for a given ASCII code
+ for key in reversed(self[modifiers])
+ # Ignore keys with no ASCII value
+ if key.ascii
+ }
+
+
+class BiosKeyMapping(KeyMapping):
+ """Keyboard mapping as used by the BIOS"""
+
+ @property
+ def inverse(self) -> MutableMapping[str, Key]:
+ inverse = super().inverse
+ assert len(inverse) == 0x7f
+ assert all(x.modifiers in {KeyModifiers.NONE, KeyModifiers.SHIFT,
+ KeyModifiers.CTRL}
+ for x in inverse.values())
+ return inverse
+
+
+@dataclass
+class KeyRemapping:
+ """A keyboard remapping"""
+
+ name: str
+ """Mapping name"""
+
+ source: KeyMapping
+ """Source keyboard mapping"""
+
+ target: KeyMapping
+ """Target keyboard mapping"""
+
+ @property
+ def ascii(self) -> MutableMapping[str, str]:
+ """Remapped ASCII key table"""
+ # Construct raw mapping from source ASCII to target ASCII
+ 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 identity mappings
+ table = {source: target for source, target in raw.items()
+ if target
+ and ord(source) != 0x7f
+ and ord(target) != 0x7f
+ and ord(source) != ord(target)}
+ # Recursively delete any mappings that would produce
+ # unreachable alphanumerics (e.g. the "il" keymap, which maps
+ # away the whole lower-case alphabet)
+ while True:
+ unreachable = set(table.keys()) - set(table.values())
+ delete = {x for x in unreachable if x.isascii() and x.isalnum()}
+ if not delete:
+ break
+ table = {k: v for k, v in table.items() if k not in delete}
+ # Sanity check: ensure that all numerics are reachable using
+ # the same shift state
+ digits = '1234567890'
+ unshifted = ''.join(table.get(x, x) for x in '1234567890')
+ shifted = ''.join(table.get(x, x) for x in '!@#$%^&*()')
+ if digits not in (shifted, unshifted):
+ raise ValueError("Inconsistent numeric remapping %s / %s" %
+ (unshifted, shifted))
+ return dict(sorted(table.items()))
+
+ @property
+ def cname(self) -> str:
+ """C variable name"""
+ return re.sub(r'\W', '_', self.name) + "_mapping"
+
+ @staticmethod
+ def ascii_name(char: str) -> str:
+ """ASCII character name"""
+ if char == '\\':
+ name = "'\\\\'"
+ elif char == '\'':
+ name = "'\\\''"
+ elif char.isprintable():
+ name = "'%s'" % char
+ elif ord(char) <= 0x1a:
+ name = "Ctrl-%c" % (ord(char) + 0x40)
+ else:
+ name = "0x%02x" % ord(char)
+ return name
+
+ @property
+ def code(self) -> str:
+ """Generated source code"""
+ code = textwrap.dedent(f"""
+ /** @file
+ *
+ * "{self.name}" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+ FILE_LICENCE ( PUBLIC_DOMAIN );
+
+ #include <ipxe/keymap.h>
+
+ /** "{self.name}" keyboard mapping */
+ struct key_mapping {self.cname}[] __keymap = {{
+ """).lstrip() + ''.join(
+ '\t{ 0x%02x, 0x%02x },\t/* %s => %s */\n' % (
+ ord(source), ord(target),
+ self.ascii_name(source), self.ascii_name(target)
+ )
+ for source, target in self.ascii.items()
+ ) + textwrap.dedent("""
+ };
+ """).strip()
+ return code
+
+
+if __name__ == '__main__':
+
+ # Parse command-line arguments
+ parser = argparse.ArgumentParser(description="Generate iPXE keymaps")
+ parser.add_argument('--verbose', '-v', action='count', default=0,
+ help="Increase verbosity")
+ parser.add_argument('layout', help="Target keyboard layout")
+ args = parser.parse_args()
+
+ # Load source and target keymaps
+ source = BiosKeyMapping.load('us')
+ target = KeyMapping.load(args.layout)
+
+ # Construct remapping
+ remap = KeyRemapping(name=args.layout, source=source, target=target)
+
+ # Output generated code
+ print(remap.code)