[console] Allow for named keyboard mappings

Separate the concept of a keyboard mapping from a list of remapped
keys, to allow for the possibility of supporting multiple keyboard
mappings at runtime.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/591/head
Michael Brown 2022-02-14 13:22:48 +00:00
parent 1150321595
commit 871dd236d4
33 changed files with 373 additions and 130 deletions

View File

@ -31,6 +31,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* *
*/ */
/** Default keyboard mapping */
static TABLE_START ( keymap_start, KEYMAP );
/** Current keyboard mapping */
static struct keymap *keymap = keymap_start;
/** /**
* Remap a key * Remap a key
* *
@ -38,12 +44,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* @ret character Mapped character * @ret character Mapped character
*/ */
unsigned int key_remap ( unsigned int character ) { unsigned int key_remap ( unsigned int character ) {
struct key_mapping *mapping; struct keymap_key *key;
/* Remap via table */ /* Remap via table */
for_each_table_entry ( mapping, KEYMAP ) { for ( key = keymap->basic ; key->from ; key++ ) {
if ( mapping->from == character ) { if ( key->from == character ) {
character = mapping->to; character = key->to;
break; break;
} }
} }

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "al" keyboard mapping */ /** "al" basic remapping */
struct key_mapping al_mapping[] __keymap = { static struct keymap_key al_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1c, 0x1d }, /* 0x1c => 0x1d */ { 0x1c, 0x1d }, /* 0x1c => 0x1d */
@ -32,4 +32,11 @@ struct key_mapping al_mapping[] __keymap = {
{ 0x7e, 0x7c }, /* '~' => '|' */ { 0x7e, 0x7c }, /* '~' => '|' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "al" keyboard map */
struct keymap al_keymap __keymap = {
.name = "al",
.basic = al_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "az" keyboard mapping */ /** "az" basic remapping */
struct key_mapping az_mapping[] __keymap = { static struct keymap_key az_basic[] = {
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x24, 0x3b }, /* '$' => ';' */ { 0x24, 0x3b }, /* '$' => ';' */
{ 0x26, 0x3f }, /* '&' => '?' */ { 0x26, 0x3f }, /* '&' => '?' */
@ -23,4 +23,11 @@ struct key_mapping az_mapping[] __keymap = {
{ 0x7c, 0x2f }, /* '|' => '/' */ { 0x7c, 0x2f }, /* '|' => '/' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "az" keyboard map */
struct keymap az_keymap __keymap = {
.name = "az",
.basic = az_basic,
}; };

View File

@ -10,8 +10,15 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "by" keyboard mapping */ /** "by" basic remapping */
struct key_mapping by_mapping[] __keymap = { static struct keymap_key by_basic[] = {
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "by" keyboard map */
struct keymap by_keymap __keymap = {
.name = "by",
.basic = by_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "cf" keyboard mapping */ /** "cf" basic remapping */
struct key_mapping cf_mapping[] __keymap = { static struct keymap_key cf_basic[] = {
{ 0x23, 0x2f }, /* '#' => '/' */ { 0x23, 0x2f }, /* '#' => '/' */
{ 0x3c, 0x27 }, /* '<' => '\'' */ { 0x3c, 0x27 }, /* '<' => '\'' */
{ 0x3e, 0x2e }, /* '>' => '.' */ { 0x3e, 0x2e }, /* '>' => '.' */
@ -21,4 +21,11 @@ struct key_mapping cf_mapping[] __keymap = {
{ 0x60, 0x23 }, /* '`' => '#' */ { 0x60, 0x23 }, /* '`' => '#' */
{ 0x7c, 0x3e }, /* '|' => '>' */ { 0x7c, 0x3e }, /* '|' => '>' */
{ 0x7e, 0x7c }, /* '~' => '|' */ { 0x7e, 0x7c }, /* '~' => '|' */
{ 0, 0 }
};
/** "cf" keyboard map */
struct keymap cf_keymap __keymap = {
.name = "cf",
.basic = cf_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "cz" keyboard mapping */ /** "cz" basic remapping */
struct key_mapping cz_mapping[] __keymap = { static struct keymap_key cz_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1f, 0x1c }, /* 0x1f => 0x1c */ { 0x1f, 0x1c }, /* 0x1f => 0x1c */
@ -43,4 +43,11 @@ struct key_mapping cz_mapping[] __keymap = {
{ 0x7b, 0x2f }, /* '{' => '/' */ { 0x7b, 0x2f }, /* '{' => '/' */
{ 0x7c, 0x27 }, /* '|' => '\'' */ { 0x7c, 0x27 }, /* '|' => '\'' */
{ 0x7d, 0x28 }, /* '}' => '(' */ { 0x7d, 0x28 }, /* '}' => '(' */
{ 0, 0 }
};
/** "cz" keyboard map */
struct keymap cz_keymap __keymap = {
.name = "cz",
.basic = cz_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "de" keyboard mapping */ /** "de" basic remapping */
struct key_mapping de_mapping[] __keymap = { static struct keymap_key de_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1c, 0x23 }, /* 0x1c => '#' */ { 0x1c, 0x23 }, /* 0x1c => '#' */
@ -38,4 +38,11 @@ struct key_mapping de_mapping[] __keymap = {
{ 0x7d, 0x2a }, /* '}' => '*' */ { 0x7d, 0x2a }, /* '}' => '*' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "de" keyboard map */
struct keymap de_keymap __keymap = {
.name = "de",
.basic = de_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "dk" keyboard mapping */ /** "dk" basic remapping */
struct key_mapping dk_mapping[] __keymap = { static struct keymap_key dk_basic[] = {
{ 0x1c, 0x27 }, /* 0x1c => '\'' */ { 0x1c, 0x27 }, /* 0x1c => '\'' */
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
@ -30,4 +30,11 @@ struct key_mapping dk_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */ { 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "dk" keyboard map */
struct keymap dk_keymap __keymap = {
.name = "dk",
.basic = dk_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "es" keyboard mapping */ /** "es" basic remapping */
struct key_mapping es_mapping[] __keymap = { static struct keymap_key es_basic[] = {
{ 0x1c, 0x1d }, /* 0x1c => 0x1d */ { 0x1c, 0x1d }, /* 0x1c => 0x1d */
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
@ -30,4 +30,11 @@ struct key_mapping es_mapping[] __keymap = {
{ 0x7d, 0x2a }, /* '}' => '*' */ { 0x7d, 0x2a }, /* '}' => '*' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "es" keyboard map */
struct keymap es_keymap __keymap = {
.name = "es",
.basic = es_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "et" keyboard mapping */ /** "et" basic remapping */
struct key_mapping et_mapping[] __keymap = { static struct keymap_key et_basic[] = {
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */ { 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */ { 0x29, 0x3d }, /* ')' => '=' */
@ -28,4 +28,11 @@ struct key_mapping et_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */ { 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "et" keyboard map */
struct keymap et_keymap __keymap = {
.name = "et",
.basic = et_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "fi" keyboard mapping */ /** "fi" basic remapping */
struct key_mapping fi_mapping[] __keymap = { static struct keymap_key fi_basic[] = {
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */ { 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */ { 0x29, 0x3d }, /* ')' => '=' */
@ -28,4 +28,11 @@ struct key_mapping fi_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */ { 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "fi" keyboard map */
struct keymap fi_keymap __keymap = {
.name = "fi",
.basic = fi_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "fr" keyboard mapping */ /** "fr" basic remapping */
struct key_mapping fr_mapping[] __keymap = { static struct keymap_key fr_basic[] = {
{ 0x01, 0x11 }, /* Ctrl-A => Ctrl-Q */ { 0x01, 0x11 }, /* Ctrl-A => Ctrl-Q */
{ 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */ { 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */
{ 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */ { 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */
@ -59,4 +59,11 @@ struct key_mapping fr_mapping[] __keymap = {
{ 0x7a, 0x77 }, /* 'z' => 'w' */ { 0x7a, 0x77 }, /* 'z' => 'w' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "fr" keyboard map */
struct keymap fr_keymap __keymap = {
.name = "fr",
.basic = fr_basic,
}; };

View File

@ -10,8 +10,15 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "gr" keyboard mapping */ /** "gr" basic remapping */
struct key_mapping gr_mapping[] __keymap = { static struct keymap_key gr_basic[] = {
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "gr" keyboard map */
struct keymap gr_keymap __keymap = {
.name = "gr",
.basic = gr_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "hu" keyboard mapping */ /** "hu" basic remapping */
struct key_mapping hu_mapping[] __keymap = { static struct keymap_key hu_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
@ -32,4 +32,11 @@ struct key_mapping hu_mapping[] __keymap = {
{ 0x60, 0x30 }, /* '`' => '0' */ { 0x60, 0x30 }, /* '`' => '0' */
{ 0x79, 0x7a }, /* 'y' => 'z' */ { 0x79, 0x7a }, /* 'y' => 'z' */
{ 0x7a, 0x79 }, /* 'z' => 'y' */ { 0x7a, 0x79 }, /* 'z' => 'y' */
{ 0, 0 }
};
/** "hu" keyboard map */
struct keymap hu_keymap __keymap = {
.name = "hu",
.basic = hu_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "il" keyboard mapping */ /** "il" basic remapping */
struct key_mapping il_mapping[] __keymap = { static struct keymap_key il_basic[] = {
{ 0x1d, 0x1b }, /* 0x1d => 0x1b */ { 0x1d, 0x1b }, /* 0x1d => 0x1b */
{ 0x27, 0x2c }, /* '\'' => ',' */ { 0x27, 0x2c }, /* '\'' => ',' */
{ 0x28, 0x29 }, /* '(' => ')' */ { 0x28, 0x29 }, /* '(' => ')' */
@ -26,4 +26,11 @@ struct key_mapping il_mapping[] __keymap = {
{ 0x7d, 0x7b }, /* '}' => '{' */ { 0x7d, 0x7b }, /* '}' => '{' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "il" keyboard map */
struct keymap il_keymap __keymap = {
.name = "il",
.basic = il_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "it" keyboard mapping */ /** "it" basic remapping */
struct key_mapping it_mapping[] __keymap = { static struct keymap_key it_basic[] = {
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */ { 0x28, 0x29 }, /* '(' => ')' */
@ -32,4 +32,11 @@ struct key_mapping it_mapping[] __keymap = {
{ 0x7e, 0x7c }, /* '~' => '|' */ { 0x7e, 0x7c }, /* '~' => '|' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "it" keyboard map */
struct keymap it_keymap __keymap = {
.name = "it",
.basic = it_basic,
}; };

View File

@ -10,6 +10,13 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "lt" keyboard mapping */ /** "lt" basic remapping */
struct key_mapping lt_mapping[] __keymap = { static struct keymap_key lt_basic[] = {
{ 0, 0 }
};
/** "lt" keyboard map */
struct keymap lt_keymap __keymap = {
.name = "lt",
.basic = lt_basic,
}; };

View File

@ -10,8 +10,15 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "mk" keyboard mapping */ /** "mk" basic remapping */
struct key_mapping mk_mapping[] __keymap = { static struct keymap_key mk_basic[] = {
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "mk" keyboard map */
struct keymap mk_keymap __keymap = {
.name = "mk",
.basic = mk_basic,
}; };

View File

@ -10,11 +10,18 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "mt" keyboard mapping */ /** "mt" basic remapping */
struct key_mapping mt_mapping[] __keymap = { static struct keymap_key mt_basic[] = {
{ 0x1c, 0x1e }, /* 0x1c => 0x1e */ { 0x1c, 0x1e }, /* 0x1c => 0x1e */
{ 0x22, 0x40 }, /* '"' => '@' */ { 0x22, 0x40 }, /* '"' => '@' */
{ 0x40, 0x22 }, /* '@' => '"' */ { 0x40, 0x22 }, /* '@' => '"' */
{ 0x5c, 0x23 }, /* '\\' => '#' */ { 0x5c, 0x23 }, /* '\\' => '#' */
{ 0x7c, 0x7e }, /* '|' => '~' */ { 0x7c, 0x7e }, /* '|' => '~' */
{ 0, 0 }
};
/** "mt" keyboard map */
struct keymap mt_keymap __keymap = {
.name = "mt",
.basic = mt_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "nl" keyboard mapping */ /** "nl" basic remapping */
struct key_mapping nl_mapping[] __keymap = { static struct keymap_key nl_basic[] = {
{ 0x1c, 0x3c }, /* 0x1c => '<' */ { 0x1c, 0x3c }, /* 0x1c => '<' */
{ 0x1d, 0x1c }, /* 0x1d => 0x1c */ { 0x1d, 0x1c }, /* 0x1d => 0x1c */
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
@ -35,4 +35,11 @@ struct key_mapping nl_mapping[] __keymap = {
{ 0x7d, 0x7c }, /* '}' => '|' */ { 0x7d, 0x7c }, /* '}' => '|' */
{ 0xdc, 0x5d }, /* Pseudo-'\\' => ']' */ { 0xdc, 0x5d }, /* Pseudo-'\\' => ']' */
{ 0xfc, 0x5b }, /* Pseudo-'|' => '[' */ { 0xfc, 0x5b }, /* Pseudo-'|' => '[' */
{ 0, 0 }
};
/** "nl" keyboard map */
struct keymap nl_keymap __keymap = {
.name = "nl",
.basic = nl_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "no-latin1" keyboard mapping */ /** "no-latin1" basic remapping */
struct key_mapping no_latin1_mapping[] __keymap = { static struct keymap_key no_latin1_basic[] = {
{ 0x1d, 0x1e }, /* 0x1d => 0x1e */ { 0x1d, 0x1e }, /* 0x1d => 0x1e */
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */ { 0x28, 0x29 }, /* '(' => ')' */
@ -34,4 +34,11 @@ struct key_mapping no_latin1_mapping[] __keymap = {
{ 0x7d, 0x5e }, /* '}' => '^' */ { 0x7d, 0x5e }, /* '}' => '^' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "no-latin1" keyboard map */
struct keymap no_latin1_keymap __keymap = {
.name = "no-latin1",
.basic = no_latin1_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "no" keyboard mapping */ /** "no" basic remapping */
struct key_mapping no_mapping[] __keymap = { static struct keymap_key no_basic[] = {
{ 0x1c, 0x27 }, /* 0x1c => '\'' */ { 0x1c, 0x27 }, /* 0x1c => '\'' */
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
@ -32,4 +32,11 @@ struct key_mapping no_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */ { 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "no" keyboard map */
struct keymap no_keymap __keymap = {
.name = "no",
.basic = no_basic,
}; };

View File

@ -10,8 +10,15 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "pl" keyboard mapping */ /** "pl" basic remapping */
struct key_mapping pl_mapping[] __keymap = { static struct keymap_key pl_basic[] = {
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "pl" keyboard map */
struct keymap pl_keymap __keymap = {
.name = "pl",
.basic = pl_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "pt" keyboard mapping */ /** "pt" basic remapping */
struct key_mapping pt_mapping[] __keymap = { static struct keymap_key pt_basic[] = {
{ 0x1e, 0x36 }, /* 0x1e => '6' */ { 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */ { 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */ { 0x28, 0x29 }, /* '(' => ')' */
@ -31,4 +31,11 @@ struct key_mapping pt_mapping[] __keymap = {
{ 0x7e, 0x7c }, /* '~' => '|' */ { 0x7e, 0x7c }, /* '~' => '|' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "pt" keyboard map */
struct keymap pt_keymap __keymap = {
.name = "pt",
.basic = pt_basic,
}; };

View File

@ -10,6 +10,13 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "ro" keyboard mapping */ /** "ro" basic remapping */
struct key_mapping ro_mapping[] __keymap = { static struct keymap_key ro_basic[] = {
{ 0, 0 }
};
/** "ro" keyboard map */
struct keymap ro_keymap __keymap = {
.name = "ro",
.basic = ro_basic,
}; };

View File

@ -10,9 +10,16 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "ru" keyboard mapping */ /** "ru" basic remapping */
struct key_mapping ru_mapping[] __keymap = { static struct keymap_key ru_basic[] = {
{ 0x0d, 0x0a }, /* Ctrl-M => Ctrl-J */ { 0x0d, 0x0a }, /* Ctrl-M => Ctrl-J */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "ru" keyboard map */
struct keymap ru_keymap __keymap = {
.name = "ru",
.basic = ru_basic,
}; };

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "sg" keyboard mapping */ /** "sg" basic remapping */
struct key_mapping sg_mapping[] __keymap = { static struct keymap_key sg_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x21, 0x2b }, /* '!' => '+' */ { 0x21, 0x2b }, /* '!' => '+' */
@ -40,4 +40,11 @@ struct key_mapping sg_mapping[] __keymap = {
{ 0x7d, 0x21 }, /* '}' => '!' */ { 0x7d, 0x21 }, /* '}' => '!' */
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "sg" keyboard map */
struct keymap sg_keymap __keymap = {
.name = "sg",
.basic = sg_basic,
}; };

View File

@ -10,8 +10,15 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "sr-latin" keyboard mapping */ /** "sr-latin" basic remapping */
struct key_mapping sr_latin_mapping[] __keymap = { static struct keymap_key sr_latin_basic[] = {
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "sr-latin" keyboard map */
struct keymap sr_latin_keymap __keymap = {
.name = "sr-latin",
.basic = sr_latin_basic,
}; };

View File

@ -10,8 +10,15 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "ua" keyboard mapping */ /** "ua" basic remapping */
struct key_mapping ua_mapping[] __keymap = { static struct keymap_key ua_basic[] = {
{ 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */ { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
{ 0xfc, 0x3e }, /* Pseudo-'|' => '>' */ { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
{ 0, 0 }
};
/** "ua" keyboard map */
struct keymap ua_keymap __keymap = {
.name = "ua",
.basic = ua_basic,
}; };

View File

@ -10,10 +10,17 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "uk" keyboard mapping */ /** "uk" basic remapping */
struct key_mapping uk_mapping[] __keymap = { static struct keymap_key uk_basic[] = {
{ 0x22, 0x40 }, /* '"' => '@' */ { 0x22, 0x40 }, /* '"' => '@' */
{ 0x40, 0x22 }, /* '@' => '"' */ { 0x40, 0x22 }, /* '@' => '"' */
{ 0x5c, 0x23 }, /* '\\' => '#' */ { 0x5c, 0x23 }, /* '\\' => '#' */
{ 0x7c, 0x7e }, /* '|' => '~' */ { 0x7c, 0x7e }, /* '|' => '~' */
{ 0, 0 }
};
/** "uk" keyboard map */
struct keymap uk_keymap __keymap = {
.name = "uk",
.basic = uk_basic,
}; };

View File

@ -10,6 +10,13 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "us" keyboard mapping */ /** "us" basic remapping */
struct key_mapping us_mapping[] __keymap = { static struct keymap_key us_basic[] = {
{ 0, 0 }
};
/** "us" keyboard map */
struct keymap us_keymap __keymap = {
.name = "us",
.basic = us_basic,
}; };

View File

@ -13,16 +13,29 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h> #include <stdint.h>
#include <ipxe/tables.h> #include <ipxe/tables.h>
/** A keyboard mapping */ /** A remapped key
struct key_mapping { *
* Represents a mapping from an ASCII character (as interpreted from a
* keyboard scancode by the US-only keyboard driver provided by the
* BIOS) to the appropriate ASCII value for the keyboard layout.
*/
struct keymap_key {
/** Character read from keyboard */ /** Character read from keyboard */
uint8_t from; uint8_t from;
/** Character to be used instead */ /** Character to be used instead */
uint8_t to; uint8_t to;
} __attribute__ (( packed )); } __attribute__ (( packed ));
/** A keyboard mapping */
struct keymap {
/** Name */
const char *name;
/** Basic remapping table (zero-terminated) */
struct keymap_key *basic;
};
/** Keyboard mapping table */ /** Keyboard mapping table */
#define KEYMAP __table ( struct key_mapping, "keymap" ) #define KEYMAP __table ( struct keymap, "keymap" )
/** Define a keyboard mapping */ /** Define a keyboard mapping */
#define __keymap __table_entry ( KEYMAP, 01 ) #define __keymap __table_entry ( KEYMAP, 01 )

View File

@ -79,7 +79,7 @@ class KeyModifiers(Flag):
return 3 + bin(self.value).count('1') return 3 + bin(self.value).count('1')
@dataclass @dataclass(frozen=True)
class Key: class Key:
"""A single key definition""" """A single key definition"""
@ -120,8 +120,8 @@ class Key:
return None return None
class KeyMapping(UserDict[KeyModifiers, Sequence[Key]]): class KeyLayout(UserDict[KeyModifiers, Sequence[Key]]):
"""A keyboard mapping""" """A keyboard layout"""
BKEYMAP_MAGIC: ClassVar[bytes] = b'bkeymap' BKEYMAP_MAGIC: ClassVar[bytes] = b'bkeymap'
"""Magic signature for output produced by 'loadkeys -b'""" """Magic signature for output produced by 'loadkeys -b'"""
@ -163,16 +163,16 @@ class KeyMapping(UserDict[KeyModifiers, Sequence[Key]]):
@property @property
def unshifted(self): def unshifted(self):
"""Basic unshifted key mapping""" """Basic unshifted keyboard layout"""
return self[KeyModifiers.NONE] return self[KeyModifiers.NONE]
@property @property
def shifted(self): def shifted(self):
"""Basic shifted key mapping""" """Basic shifted keyboard layout"""
return self[KeyModifiers.SHIFT] return self[KeyModifiers.SHIFT]
@classmethod @classmethod
def load(cls, name: str) -> KeyMapping: def load(cls, name: str) -> KeyLayout:
"""Load keymap using 'loadkeys -b'""" """Load keymap using 'loadkeys -b'"""
bkeymap = subprocess.check_output(["loadkeys", "-u", "-b", name]) bkeymap = subprocess.check_output(["loadkeys", "-u", "-b", name])
if not bkeymap.startswith(cls.BKEYMAP_MAGIC): if not bkeymap.startswith(cls.BKEYMAP_MAGIC):
@ -181,21 +181,21 @@ class KeyMapping(UserDict[KeyModifiers, Sequence[Key]]):
included = bkeymap[:cls.MAX_NR_KEYMAPS] included = bkeymap[:cls.MAX_NR_KEYMAPS]
if len(included) != cls.MAX_NR_KEYMAPS: if len(included) != cls.MAX_NR_KEYMAPS:
raise ValueError("Invalid bkeymap inclusion list") raise ValueError("Invalid bkeymap inclusion list")
keymaps = bkeymap[cls.MAX_NR_KEYMAPS:] bkeymap = bkeymap[cls.MAX_NR_KEYMAPS:]
keys = {} keys = {}
for modifiers in map(KeyModifiers, range(cls.MAX_NR_KEYMAPS)): for modifiers in map(KeyModifiers, range(cls.MAX_NR_KEYMAPS)):
if included[modifiers.value]: if included[modifiers.value]:
fmt = Struct('<%dH' % cls.NR_KEYS) fmt = Struct('<%dH' % cls.NR_KEYS)
keymap = keymaps[:fmt.size] bkeylist = bkeymap[:fmt.size]
if len(keymap) != fmt.size: if len(bkeylist) != fmt.size:
raise ValueError("Invalid bkeymap map %#x" % raise ValueError("Invalid bkeymap map %#x" %
modifiers.value) modifiers.value)
keys[modifiers] = [ keys[modifiers] = [
Key(modifiers=modifiers, keycode=keycode, keysym=keysym) Key(modifiers=modifiers, keycode=keycode, keysym=keysym)
for keycode, keysym in enumerate(fmt.unpack(keymap)) for keycode, keysym in enumerate(fmt.unpack(bkeylist))
] ]
keymaps = keymaps[len(keymap):] bkeymap = bkeymap[len(bkeylist):]
if keymaps: if bkeymap:
raise ValueError("Trailing bkeymap data") raise ValueError("Trailing bkeymap data")
for modifiers, fixups in cls.FIXUPS.get(name, {}).items(): for modifiers, fixups in cls.FIXUPS.get(name, {}).items():
for keycode, keysym in fixups: for keycode, keysym in fixups:
@ -218,8 +218,8 @@ class KeyMapping(UserDict[KeyModifiers, Sequence[Key]]):
} }
class BiosKeyMapping(KeyMapping): class BiosKeyLayout(KeyLayout):
"""Keyboard mapping as used by the BIOS """Keyboard layout as used by the BIOS
To allow for remappings of the somewhat interesting key 86, we To allow for remappings of the somewhat interesting key 86, we
arrange for our keyboard drivers to generate this key as "\\|" arrange for our keyboard drivers to generate this key as "\\|"
@ -247,22 +247,56 @@ class BiosKeyMapping(KeyMapping):
return inverse return inverse
class KeymapKeys(UserDict[str, str]):
"""An ASCII character remapping"""
@classmethod
def ascii_name(cls, char: str) -> str:
"""ASCII character name"""
if char == '\\':
name = "'\\\\'"
elif char == '\'':
name = "'\\\''"
elif ord(char) & BiosKeyLayout.KEY_PSEUDO:
name = "Pseudo-%s" % cls.ascii_name(
chr(ord(char) & ~BiosKeyLayout.KEY_PSEUDO)
)
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):
"""Generated source code for C array"""
return '{\n' + ''.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.items()
) + '\t{ 0, 0 }\n}'
@dataclass @dataclass
class KeyRemapping: class Keymap:
"""A keyboard remapping""" """An iPXE keyboard mapping"""
name: str name: str
"""Mapping name""" """Mapping name"""
source: KeyMapping source: KeyLayout
"""Source keyboard mapping""" """Source keyboard layout"""
target: KeyMapping target: KeyLayout
"""Target keyboard mapping""" """Target keyboard layout"""
@property @property
def ascii(self) -> MutableMapping[str, str]: def basic(self) -> KeymapKeys:
"""Remapped ASCII key table""" """Basic remapping table"""
# Construct raw mapping from source ASCII to target ASCII # Construct raw mapping from source ASCII to target ASCII
raw = {source: self.target[key.modifiers][key.keycode].ascii raw = {source: self.target[key.modifiers][key.keycode].ascii
for source, key in self.source.inverse.items()} for source, key in self.source.inverse.items()}
@ -273,7 +307,7 @@ class KeyRemapping:
if target if target
and ord(source) != 0x7f and ord(source) != 0x7f
and ord(target) != 0x7f and ord(target) != 0x7f
and ord(source) & ~BiosKeyMapping.KEY_PSEUDO != ord(target)} and ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target)}
# Recursively delete any mappings that would produce # Recursively delete any mappings that would produce
# unreachable alphanumerics (e.g. the "il" keymap, which maps # unreachable alphanumerics (e.g. the "il" keymap, which maps
# away the whole lower-case alphabet) # away the whole lower-case alphabet)
@ -291,35 +325,17 @@ class KeyRemapping:
if digits not in (shifted, unshifted): if digits not in (shifted, unshifted):
raise ValueError("Inconsistent numeric remapping %s / %s" % raise ValueError("Inconsistent numeric remapping %s / %s" %
(unshifted, shifted)) (unshifted, shifted))
return dict(sorted(table.items())) return KeymapKeys(dict(sorted(table.items())))
@property def cname(self, suffix: str) -> str:
def cname(self) -> str:
"""C variable name""" """C variable name"""
return re.sub(r'\W', '_', self.name) + "_mapping" return re.sub(r'\W', '_', (self.name + '_' + suffix))
@classmethod
def ascii_name(cls, char: str) -> str:
"""ASCII character name"""
if char == '\\':
name = "'\\\\'"
elif char == '\'':
name = "'\\\''"
elif ord(char) & BiosKeyMapping.KEY_PSEUDO:
name = "Pseudo-%s" % cls.ascii_name(
chr(ord(char) & ~BiosKeyMapping.KEY_PSEUDO)
)
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 @property
def code(self) -> str: def code(self) -> str:
"""Generated source code""" """Generated source code"""
keymap_name = self.cname("keymap")
basic_name = self.cname("basic")
code = textwrap.dedent(f""" code = textwrap.dedent(f"""
/** @file /** @file
* *
@ -333,17 +349,15 @@ class KeyRemapping:
#include <ipxe/keymap.h> #include <ipxe/keymap.h>
/** "{self.name}" keyboard mapping */ /** "{self.name}" basic remapping */
struct key_mapping {self.cname}[] __keymap = {{ static struct keymap_key {basic_name}[] = %s;
""").lstrip() + ''.join(
'\t{ 0x%02x, 0x%02x },\t/* %s => %s */\n' % ( /** "{self.name}" keyboard map */
ord(source), ord(target), struct keymap {keymap_name} __keymap = {{
self.ascii_name(source), self.ascii_name(target) \t.name = "{self.name}",
) \t.basic = {basic_name},
for source, target in self.ascii.items() }};
) + textwrap.dedent(""" """).strip() % self.basic.code
};
""").strip()
return code return code
@ -356,12 +370,12 @@ if __name__ == '__main__':
parser.add_argument('layout', help="Target keyboard layout") parser.add_argument('layout', help="Target keyboard layout")
args = parser.parse_args() args = parser.parse_args()
# Load source and target keymaps # Load source and target keyboard layouts
source = BiosKeyMapping.load('us') source = BiosKeyLayout.load('us')
target = KeyMapping.load(args.layout) target = KeyLayout.load(args.layout)
# Construct remapping # Construct keyboard mapping
remap = KeyRemapping(name=args.layout, source=source, target=target) keymap = Keymap(name=args.layout, source=source, target=target)
# Output generated code # Output generated code
print(remap.code) print(keymap.code)