diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-02-15 16:41:19 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-02-15 16:46:58 +0000 |
commit | 419b2e71da689ded944c3789c87b7ae3646c7a7c (patch) | |
tree | f4010535ce5b80d1d556ec97822ec10268573c7b /src/util | |
parent | 4a37b050081cbb9ea384a203502eca09a2d8038c (diff) | |
download | ipxe-419b2e71da689ded944c3789c87b7ae3646c7a7c.tar.gz |
[console] Fix definition of unreachability for remapped keys
The AltGr remapping table is constructed to include only keys that are
not reachable after applying the basic remapping table. The logic
currently fails to include keys that are omitted entirely from the
basic remapping table since they would map to a non-ASCII character.
Fix this logic by allowing the remapping tables to include null
mappings, which are then elided only at the point of constructing the
C code fragment.
Reported-by: Christian Nilsson <nikize@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/util')
-rwxr-xr-x | src/util/genkeymap.py | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/src/util/genkeymap.py b/src/util/genkeymap.py index 8df949612..632f71eda 100755 --- a/src/util/genkeymap.py +++ b/src/util/genkeymap.py @@ -33,6 +33,10 @@ import textwrap from typing import ClassVar, Optional +BACKSPACE = chr(0x7f) +"""Backspace character""" + + class KeyType(IntEnum): """Key types""" @@ -174,7 +178,7 @@ class KeyLayout(UserDict[KeyModifiers, Sequence[Key]]): 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)], + KeyModifiers.CTRL: [(KEY_BACKSPACE, ord(BACKSPACE))], }, 'il': { # Redefine some otherwise unreachable ASCII characters @@ -200,11 +204,6 @@ class KeyLayout(UserDict[KeyModifiers, Sequence[Key]]): """Basic shifted keyboard layout""" return self[KeyModifiers.SHIFT] - @property - def altgr(self): - """AltGr keyboard layout""" - return self.get(KeyModifiers.ALTGR, self.unshifted) - @classmethod def load(cls, name: str) -> KeyLayout: """Load keymap using 'loadkeys -b'""" @@ -281,7 +280,7 @@ class BiosKeyLayout(KeyLayout): return inverse -class KeymapKeys(UserDict[str, str]): +class KeymapKeys(UserDict[str, Optional[str]]): """An ASCII character remapping""" @classmethod @@ -312,7 +311,8 @@ class KeymapKeys(UserDict[str, str]): self.ascii_name(source), self.ascii_name(target) ) for source, target in self.items() - if ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target) + if target + and ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target) ) + '\t{ 0, 0 }\n}' @@ -335,13 +335,12 @@ class Keymap: # 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 + # Eliminate any identity mappings, or mappings that attempt to + # remap the backspace key table = {source: target for source, target in raw.items() - if target - and ord(source) != 0x7f - and ord(target) != 0x7f - and source != target} + if source != target + and source != BACKSPACE + and target != BACKSPACE} # Recursively delete any mappings that would produce # unreachable alphanumerics (e.g. the "il" keymap, which maps # away the whole lower-case alphabet) @@ -354,8 +353,8 @@ class Keymap: # 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 '!@#$%^&*()') + unshifted = ''.join(table.get(x) or x for x in '1234567890') + shifted = ''.join(table.get(x) or x for x in '!@#$%^&*()') if digits not in (shifted, unshifted): raise ValueError("Inconsistent numeric remapping %s / %s" % (unshifted, shifted)) @@ -365,21 +364,22 @@ class Keymap: def altgr(self) -> KeymapKeys: """AltGr remapping table""" # Construct raw mapping from source ASCII to target ASCII - raw = {source: self.target.altgr[key.keycode].ascii - for source, key in self.source.inverse.items() - if key.modifiers == KeyModifiers.NONE} + raw = { + source: + self.target.get((key.modifiers | KeyModifiers.ALTGR), + self.target[key.modifiers])[key.keycode].ascii + for source, key in self.source.inverse.items() + } # Identify printable keys that are unreachable via the basic map basic = self.basic unmapped = set(x for x in basic.keys() if x.isascii() and x.isprintable()) remapped = set(basic.values()) unreachable = unmapped - remapped - # Eliminate any null mappings, mappings for unprintable - # characters, or mappings for characters that are reachable - # via the basic map + # Eliminate any mappings for unprintable characters, or + # mappings for characters that are reachable via the basic map table = {source: target for source, target in raw.items() if source.isprintable() - and target and target in unreachable} # Check that all characters are now reachable unreachable -= set(table.values()) |