[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
*
@ -38,12 +44,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* @ret character Mapped character
*/
unsigned int key_remap ( unsigned int character ) {
struct key_mapping *mapping;
struct keymap_key *key;
/* Remap via table */
for_each_table_entry ( mapping, KEYMAP ) {
if ( mapping->from == character ) {
character = mapping->to;
for ( key = keymap->basic ; key->from ; key++ ) {
if ( key->from == character ) {
character = key->to;
break;
}
}

View File

@ -10,8 +10,8 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
#include <ipxe/keymap.h>
/** "al" keyboard mapping */
struct key_mapping al_mapping[] __keymap = {
/** "al" basic remapping */
static struct keymap_key al_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1c, 0x1d }, /* 0x1c => 0x1d */
@ -32,4 +32,11 @@ struct key_mapping al_mapping[] __keymap = {
{ 0x7e, 0x7c }, /* '~' => '|' */
{ 0xdc, 0x3c }, /* 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>
/** "az" keyboard mapping */
struct key_mapping az_mapping[] __keymap = {
/** "az" basic remapping */
static struct keymap_key az_basic[] = {
{ 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x24, 0x3b }, /* '$' => ';' */
{ 0x26, 0x3f }, /* '&' => '?' */
@ -23,4 +23,11 @@ struct key_mapping az_mapping[] __keymap = {
{ 0x7c, 0x2f }, /* '|' => '/' */
{ 0xdc, 0x3c }, /* 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>
/** "by" keyboard mapping */
struct key_mapping by_mapping[] __keymap = {
/** "by" basic remapping */
static struct keymap_key by_basic[] = {
{ 0xdc, 0x3c }, /* 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>
/** "cf" keyboard mapping */
struct key_mapping cf_mapping[] __keymap = {
/** "cf" basic remapping */
static struct keymap_key cf_basic[] = {
{ 0x23, 0x2f }, /* '#' => '/' */
{ 0x3c, 0x27 }, /* '<' => '\'' */
{ 0x3e, 0x2e }, /* '>' => '.' */
@ -21,4 +21,11 @@ struct key_mapping cf_mapping[] __keymap = {
{ 0x60, 0x23 }, /* '`' => '#' */
{ 0x7c, 0x3e }, /* '|' => '>' */
{ 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>
/** "cz" keyboard mapping */
struct key_mapping cz_mapping[] __keymap = {
/** "cz" basic remapping */
static struct keymap_key cz_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1f, 0x1c }, /* 0x1f => 0x1c */
@ -43,4 +43,11 @@ struct key_mapping cz_mapping[] __keymap = {
{ 0x7b, 0x2f }, /* '{' => '/' */
{ 0x7c, 0x27 }, /* '|' => '\'' */
{ 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>
/** "de" keyboard mapping */
struct key_mapping de_mapping[] __keymap = {
/** "de" basic remapping */
static struct keymap_key de_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1c, 0x23 }, /* 0x1c => '#' */
@ -38,4 +38,11 @@ struct key_mapping de_mapping[] __keymap = {
{ 0x7d, 0x2a }, /* '}' => '*' */
{ 0xdc, 0x3c }, /* 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>
/** "dk" keyboard mapping */
struct key_mapping dk_mapping[] __keymap = {
/** "dk" basic remapping */
static struct keymap_key dk_basic[] = {
{ 0x1c, 0x27 }, /* 0x1c => '\'' */
{ 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
@ -30,4 +30,11 @@ struct key_mapping dk_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* 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>
/** "es" keyboard mapping */
struct key_mapping es_mapping[] __keymap = {
/** "es" basic remapping */
static struct keymap_key es_basic[] = {
{ 0x1c, 0x1d }, /* 0x1c => 0x1d */
{ 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
@ -30,4 +30,11 @@ struct key_mapping es_mapping[] __keymap = {
{ 0x7d, 0x2a }, /* '}' => '*' */
{ 0xdc, 0x3c }, /* 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>
/** "et" keyboard mapping */
struct key_mapping et_mapping[] __keymap = {
/** "et" basic remapping */
static struct keymap_key et_basic[] = {
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
@ -28,4 +28,11 @@ struct key_mapping et_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* 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>
/** "fi" keyboard mapping */
struct key_mapping fi_mapping[] __keymap = {
/** "fi" basic remapping */
static struct keymap_key fi_basic[] = {
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
{ 0x29, 0x3d }, /* ')' => '=' */
@ -28,4 +28,11 @@ struct key_mapping fi_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* 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>
/** "fr" keyboard mapping */
struct key_mapping fr_mapping[] __keymap = {
/** "fr" basic remapping */
static struct keymap_key fr_basic[] = {
{ 0x01, 0x11 }, /* Ctrl-A => Ctrl-Q */
{ 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */
{ 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */
@ -59,4 +59,11 @@ struct key_mapping fr_mapping[] __keymap = {
{ 0x7a, 0x77 }, /* 'z' => 'w' */
{ 0xdc, 0x3c }, /* 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>
/** "gr" keyboard mapping */
struct key_mapping gr_mapping[] __keymap = {
/** "gr" basic remapping */
static struct keymap_key gr_basic[] = {
{ 0xdc, 0x3c }, /* 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>
/** "hu" keyboard mapping */
struct key_mapping hu_mapping[] __keymap = {
/** "hu" basic remapping */
static struct keymap_key hu_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x1e, 0x36 }, /* 0x1e => '6' */
@ -32,4 +32,11 @@ struct key_mapping hu_mapping[] __keymap = {
{ 0x60, 0x30 }, /* '`' => '0' */
{ 0x79, 0x7a }, /* 'y' => 'z' */
{ 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>
/** "il" keyboard mapping */
struct key_mapping il_mapping[] __keymap = {
/** "il" basic remapping */
static struct keymap_key il_basic[] = {
{ 0x1d, 0x1b }, /* 0x1d => 0x1b */
{ 0x27, 0x2c }, /* '\'' => ',' */
{ 0x28, 0x29 }, /* '(' => ')' */
@ -26,4 +26,11 @@ struct key_mapping il_mapping[] __keymap = {
{ 0x7d, 0x7b }, /* '}' => '{' */
{ 0xdc, 0x3c }, /* 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>
/** "it" keyboard mapping */
struct key_mapping it_mapping[] __keymap = {
/** "it" basic remapping */
static struct keymap_key it_basic[] = {
{ 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
@ -32,4 +32,11 @@ struct key_mapping it_mapping[] __keymap = {
{ 0x7e, 0x7c }, /* '~' => '|' */
{ 0xdc, 0x3c }, /* 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>
/** "lt" keyboard mapping */
struct key_mapping lt_mapping[] __keymap = {
/** "lt" basic remapping */
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>
/** "mk" keyboard mapping */
struct key_mapping mk_mapping[] __keymap = {
/** "mk" basic remapping */
static struct keymap_key mk_basic[] = {
{ 0xdc, 0x3c }, /* 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>
/** "mt" keyboard mapping */
struct key_mapping mt_mapping[] __keymap = {
/** "mt" basic remapping */
static struct keymap_key mt_basic[] = {
{ 0x1c, 0x1e }, /* 0x1c => 0x1e */
{ 0x22, 0x40 }, /* '"' => '@' */
{ 0x40, 0x22 }, /* '@' => '"' */
{ 0x5c, 0x23 }, /* '\\' => '#' */
{ 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>
/** "nl" keyboard mapping */
struct key_mapping nl_mapping[] __keymap = {
/** "nl" basic remapping */
static struct keymap_key nl_basic[] = {
{ 0x1c, 0x3c }, /* 0x1c => '<' */
{ 0x1d, 0x1c }, /* 0x1d => 0x1c */
{ 0x1e, 0x36 }, /* 0x1e => '6' */
@ -35,4 +35,11 @@ struct key_mapping nl_mapping[] __keymap = {
{ 0x7d, 0x7c }, /* '}' => '|' */
{ 0xdc, 0x5d }, /* 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>
/** "no-latin1" keyboard mapping */
struct key_mapping no_latin1_mapping[] __keymap = {
/** "no-latin1" basic remapping */
static struct keymap_key no_latin1_basic[] = {
{ 0x1d, 0x1e }, /* 0x1d => 0x1e */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
@ -34,4 +34,11 @@ struct key_mapping no_latin1_mapping[] __keymap = {
{ 0x7d, 0x5e }, /* '}' => '^' */
{ 0xdc, 0x3c }, /* 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>
/** "no" keyboard mapping */
struct key_mapping no_mapping[] __keymap = {
/** "no" basic remapping */
static struct keymap_key no_basic[] = {
{ 0x1c, 0x27 }, /* 0x1c => '\'' */
{ 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
@ -32,4 +32,11 @@ struct key_mapping no_mapping[] __keymap = {
{ 0x7c, 0x2a }, /* '|' => '*' */
{ 0xdc, 0x3c }, /* 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>
/** "pl" keyboard mapping */
struct key_mapping pl_mapping[] __keymap = {
/** "pl" basic remapping */
static struct keymap_key pl_basic[] = {
{ 0xdc, 0x3c }, /* 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>
/** "pt" keyboard mapping */
struct key_mapping pt_mapping[] __keymap = {
/** "pt" basic remapping */
static struct keymap_key pt_basic[] = {
{ 0x1e, 0x36 }, /* 0x1e => '6' */
{ 0x26, 0x2f }, /* '&' => '/' */
{ 0x28, 0x29 }, /* '(' => ')' */
@ -31,4 +31,11 @@ struct key_mapping pt_mapping[] __keymap = {
{ 0x7e, 0x7c }, /* '~' => '|' */
{ 0xdc, 0x3c }, /* 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>
/** "ro" keyboard mapping */
struct key_mapping ro_mapping[] __keymap = {
/** "ro" basic remapping */
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>
/** "ru" keyboard mapping */
struct key_mapping ru_mapping[] __keymap = {
/** "ru" basic remapping */
static struct keymap_key ru_basic[] = {
{ 0x0d, 0x0a }, /* Ctrl-M => Ctrl-J */
{ 0xdc, 0x3c }, /* 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>
/** "sg" keyboard mapping */
struct key_mapping sg_mapping[] __keymap = {
/** "sg" basic remapping */
static struct keymap_key sg_basic[] = {
{ 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
{ 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
{ 0x21, 0x2b }, /* '!' => '+' */
@ -40,4 +40,11 @@ struct key_mapping sg_mapping[] __keymap = {
{ 0x7d, 0x21 }, /* '}' => '!' */
{ 0xdc, 0x3c }, /* 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>
/** "sr-latin" keyboard mapping */
struct key_mapping sr_latin_mapping[] __keymap = {
/** "sr-latin" basic remapping */
static struct keymap_key sr_latin_basic[] = {
{ 0xdc, 0x3c }, /* 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>
/** "ua" keyboard mapping */
struct key_mapping ua_mapping[] __keymap = {
/** "ua" basic remapping */
static struct keymap_key ua_basic[] = {
{ 0xdc, 0x3c }, /* 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>
/** "uk" keyboard mapping */
struct key_mapping uk_mapping[] __keymap = {
/** "uk" basic remapping */
static struct keymap_key uk_basic[] = {
{ 0x22, 0x40 }, /* '"' => '@' */
{ 0x40, 0x22 }, /* '@' => '"' */
{ 0x5c, 0x23 }, /* '\\' => '#' */
{ 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>
/** "us" keyboard mapping */
struct key_mapping us_mapping[] __keymap = {
/** "us" basic remapping */
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 <ipxe/tables.h>
/** A keyboard mapping */
struct key_mapping {
/** A remapped key
*
* 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 */
uint8_t from;
/** Character to be used instead */
uint8_t to;
} __attribute__ (( packed ));
/** A keyboard mapping */
struct keymap {
/** Name */
const char *name;
/** Basic remapping table (zero-terminated) */
struct keymap_key *basic;
};
/** Keyboard mapping table */
#define KEYMAP __table ( struct key_mapping, "keymap" )
#define KEYMAP __table ( struct keymap, "keymap" )
/** Define a keyboard mapping */
#define __keymap __table_entry ( KEYMAP, 01 )

View File

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