summaryrefslogtreecommitdiff
path: root/kvmd/keyboard
diff options
context:
space:
mode:
authorDevaev Maxim <[email protected]>2020-05-23 15:57:02 +0300
committerDevaev Maxim <[email protected]>2020-05-23 15:57:02 +0300
commite9d86c058d715af343be355b1ab3d58b7eed43b9 (patch)
tree6ae712152e4e9d7c274c5e369755f7030269677e /kvmd/keyboard
parenta795fe5ed63b960cbf24c9130ed37f9f7f33280c (diff)
major keymaps improvement
Diffstat (limited to 'kvmd/keyboard')
-rw-r--r--kvmd/keyboard/keysym.py38
-rw-r--r--kvmd/keyboard/printer.py79
2 files changed, 46 insertions, 71 deletions
diff --git a/kvmd/keyboard/keysym.py b/kvmd/keyboard/keysym.py
index fbfeb913..d12e2b84 100644
--- a/kvmd/keyboard/keysym.py
+++ b/kvmd/keyboard/keysym.py
@@ -20,6 +20,7 @@
# ========================================================================== #
+import dataclasses
import pkgutil
import functools
@@ -29,22 +30,34 @@ import Xlib.keysymdef
from ..logging import get_logger
+from .mappings import At1Key
from .mappings import X11_TO_AT1
from .mappings import AT1_TO_WEB
# =====
-def build_symmap(path: str) -> Dict[int, str]:
[email protected](frozen=True)
+class SymmapWebKey:
+ name: str
+ shift: bool
+
+
+def build_symmap(path: str) -> Dict[int, SymmapWebKey]:
# https://github.com/qemu/qemu/blob/95a9457fd44ad97c518858a4e1586a5498f9773c/ui/keymaps.c
- symmap: Dict[int, str] = {}
+ symmap: Dict[int, SymmapWebKey] = {}
for (x11_code, at1_key) in X11_TO_AT1.items():
- symmap[x11_code] = AT1_TO_WEB[at1_key.code]
-
- for (x11_code, at1_code) in _read_keyboard_layout(path).items():
- if (web_name := AT1_TO_WEB.get(at1_code)) is not None:
- # mypy bug
- symmap[x11_code] = web_name # type: ignore
+ symmap[x11_code] = SymmapWebKey(
+ name=AT1_TO_WEB[at1_key.code],
+ shift=False,
+ )
+
+ for (x11_code, at1_key) in _read_keyboard_layout(path).items():
+ if (web_name := AT1_TO_WEB.get(at1_key.code)) is not None:
+ symmap[x11_code] = SymmapWebKey(
+ name=web_name,
+ shift=at1_key.shift,
+ )
return symmap
@@ -76,14 +89,14 @@ def _resolve_keysym(name: str) -> int:
return 0
-def _read_keyboard_layout(path: str) -> Dict[int, int]: # Keysym to evdev (at1)
+def _read_keyboard_layout(path: str) -> Dict[int, At1Key]: # Keysym to evdev (at1)
logger = get_logger(0)
logger.info("Reading keyboard layout %s ...", path)
with open(path) as layout_file:
lines = list(map(str.strip, layout_file.read().split("\n")))
- layout: Dict[int, int] = {}
+ layout: Dict[int, At1Key] = {}
for (number, line) in enumerate(lines):
if len(line) == 0 or line.startswith(("#", "map ", "include ")):
continue
@@ -92,7 +105,10 @@ def _read_keyboard_layout(path: str) -> Dict[int, int]: # Keysym to evdev (at1)
if len(parts) >= 2:
if (code := _resolve_keysym(parts[0])) != 0:
try:
- layout[code] = int(parts[1], 16)
+ layout[code] = At1Key(
+ code=int(parts[1], 16),
+ shift=bool(len(parts) == 3 and parts[2] == "shift"),
+ )
except ValueError as err:
logger.error("Can't parse layout line #%d: %s", number, str(err))
return layout
diff --git a/kvmd/keyboard/printer.py b/kvmd/keyboard/printer.py
index f8086be3..2e26c232 100644
--- a/kvmd/keyboard/printer.py
+++ b/kvmd/keyboard/printer.py
@@ -20,84 +20,43 @@
# ========================================================================== #
-import string
-
from typing import Tuple
+from typing import Dict
from typing import Generator
-from .mappings import KEYMAP
+from .keysym import SymmapWebKey
# =====
-_LOWER_CHARS = {
- "\n": "Enter",
- "\t": "Tab",
- " ": "Space",
- "`": "Backquote",
- "\\": "Backslash",
- "[": "BracketLeft",
- "]": "BracketLeft",
- ",": "Comma",
- ".": "Period",
- "-": "Minus",
- "'": "Quote",
- ";": "Semicolon",
- "/": "Slash",
- "=": "Equal",
- **{str(number): f"Digit{number}" for number in range(0, 10)},
- **{ch: f"Key{ch.upper()}" for ch in string.ascii_lowercase},
-}
-assert not set(_LOWER_CHARS.values()).difference(KEYMAP)
-
-_UPPER_CHARS = {
- "~": "Backquote",
- "|": "Backslash",
- "{": "BracketLeft",
- "}": "BracketRight",
- "<": "Comma",
- ">": "Period",
- "!": "Digit1",
- "@": "Digit2",
- "#": "Digit3",
- "$": "Digit4",
- "%": "Digit5",
- "^": "Digit6",
- "&": "Digit7",
- "*": "Digit8",
- "(": "Digit9",
- ")": "Digit0",
- "_": "Minus",
- "\"": "Quote",
- ":": "Semicolon",
- "?": "Slash",
- "+": "Equal",
- **{ch: f"Key{ch}" for ch in string.ascii_uppercase},
-}
-assert not set(_UPPER_CHARS.values()).difference(KEYMAP)
+def text_to_web_keys(
+ text: str,
+ symmap: Dict[int, SymmapWebKey],
+ shift_key: str="ShiftLeft",
+) -> Generator[Tuple[str, bool], None, None]:
-
-# =====
-def text_to_web_keys(text: str, shift_key: str="ShiftLeft") -> Generator[Tuple[str, bool], None, None]:
assert shift_key in ["ShiftLeft", "ShiftRight"]
shifted = False
for ch in text:
- upper = False
- key = _LOWER_CHARS.get(ch)
- if key is None:
- if (key := _UPPER_CHARS.get(ch)) is None:
+ try:
+ code = ord(ch)
+ if not (0x20 <= code <= 0x7E):
+ # https://stackoverflow.com/questions/12343987/convert-ascii-character-to-x11-keycode
+ # https://www.ascii-code.com
continue
- upper = True
+ key = symmap[code]
+ except Exception:
+ continue
- if upper and not shifted:
+ if key.shift and not shifted:
yield (shift_key, True)
shifted = True
- elif not upper and shifted:
+ elif not key.shift and shifted:
yield (shift_key, False)
shifted = False
- yield (key, True)
- yield (key, False)
+ yield (key.name, True)
+ yield (key.name, False)
if shifted:
yield (shift_key, False)