diff options
author | Devaev Maxim <[email protected]> | 2020-10-08 12:18:38 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2020-10-08 12:18:38 +0300 |
commit | f1910f7c8ec085eece1adc56ff999527881e71d9 (patch) | |
tree | 4f3cb6c481a7d0f29b91fa8ccc9e320f3a29b73b /kvmd/keyboard | |
parent | 920f648d6526217009f8ee4dc6e943a28a4886db (diff) |
more correct keymap handling
Diffstat (limited to 'kvmd/keyboard')
-rw-r--r-- | kvmd/keyboard/keysym.py | 128 | ||||
-rw-r--r-- | kvmd/keyboard/mappings.py | 310 | ||||
-rw-r--r-- | kvmd/keyboard/mappings.py.mako | 2 | ||||
-rw-r--r-- | kvmd/keyboard/printer.py | 35 |
4 files changed, 254 insertions, 221 deletions
diff --git a/kvmd/keyboard/keysym.py b/kvmd/keyboard/keysym.py index e3695b3c..0f3568ed 100644 --- a/kvmd/keyboard/keysym.py +++ b/kvmd/keyboard/keysym.py @@ -20,10 +20,11 @@ # ========================================================================== # -import dataclasses import pkgutil import functools +from typing import Tuple +from typing import List from typing import Dict import Xlib.keysymdef @@ -36,39 +37,58 @@ from .mappings import AT1_TO_WEB # ===== [email protected](frozen=True) -class SymmapWebKey: - name: str - shift: bool - altgr: bool - ctrl: bool - - -def build_symmap(path: str) -> Dict[int, SymmapWebKey]: +class SymmapModifiers: + SHIFT: int = 0x1 + ALTGR: int = 0x2 + CTRL: int = 0x4 + + +def switch_symmap_modifiers(modifiers: int, code: int, state: bool) -> Tuple[bool, int]: + mod = 0 + if code == 65505 or code == 65506: # XK_Shift_L, XK_Shift_R + mod = SymmapModifiers.SHIFT + elif code == 65027: # AltGR aka XK_ISO_Level3_Shift + mod = SymmapModifiers.ALTGR + elif code == 65507 or code == 65508: # XK_Control_L, XK_Control_R + mod = SymmapModifiers.CTRL + if mod == 0: + return (False, modifiers) + if state: + modifiers |= mod + else: + modifiers &= ~mod + return (True, modifiers) + + +def build_symmap(path: str) -> Dict[int, Dict[int, str]]: # https://github.com/qemu/qemu/blob/95a9457fd44ad97c518858a4e1586a5498f9773c/ui/keymaps.c logger = get_logger() - symmap: Dict[int, SymmapWebKey] = {} + symmap: Dict[int, Dict[int, str]] = {} for (src, items) in [ ("<builtin>", list(X11_TO_AT1.items())), (path, list(_read_keyboard_layout(path).items())), ]: - for (code, key) in items: - web_name = AT1_TO_WEB.get(key.code) - if web_name is not None: - if ( - (web_name in ["ShiftLeft", "ShiftRight"] and key.shift) # pylint: disable=too-many-boolean-expressions - or (web_name in ["AltLeft", "AltRight"] and key.altgr) - or (web_name in ["ControlLeft", "ControlRight"] and key.ctrl) - ): - logger.error("Invalid modifier key at mapping %s: %s / %s", src, web_name, key) - continue - symmap[code] = SymmapWebKey( - name=web_name, - shift=key.shift, - altgr=key.altgr, - ctrl=key.ctrl, - ) + for (code, keys) in items: + for key in keys: + web_name = AT1_TO_WEB.get(key.code) + if web_name is not None: + if ( + (web_name in ["ShiftLeft", "ShiftRight"] and key.shift) # pylint: disable=too-many-boolean-expressions + or (web_name in ["AltLeft", "AltRight"] and key.altgr) + or (web_name in ["ControlLeft", "ControlRight"] and key.ctrl) + ): + logger.error("Invalid modifier key at mapping %s: %s / %s", src, web_name, key) + continue + + if code not in symmap: + symmap[code] = {} + symmap[code][ + 0 + | (SymmapModifiers.SHIFT if key.shift else 0) + | (SymmapModifiers.ALTGR if key.altgr else 0) + | (SymmapModifiers.CTRL if key.ctrl else 0) + ] = web_name return symmap @@ -100,14 +120,14 @@ def _resolve_keysym(name: str) -> int: return 0 -def _read_keyboard_layout(path: str) -> Dict[int, At1Key]: # Keysym to evdev (at1) +def _read_keyboard_layout(path: str) -> Dict[int, List[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, At1Key] = {} + layout: Dict[int, List[At1Key]] = {} for (lineno, line) in enumerate(lines): if len(line) == 0 or line.startswith(("#", "map ", "include ")): continue @@ -115,26 +135,32 @@ def _read_keyboard_layout(path: str) -> Dict[int, At1Key]: # Keysym to evdev (a parts = line.split() if len(parts) >= 2: x11_code = _resolve_keysym(parts[0]) - if x11_code != 0: - try: - at1_code = int(parts[1], 16) - except ValueError as err: - logger.error("Syntax error at %s:%d: %s", path, lineno, err) - continue - rest = parts[2:] - - layout[x11_code] = At1Key( - code=at1_code, - shift=("shift" in rest), - altgr=("altgr" in rest), - ctrl=("ctrl" in rest), - ) - - if "addupper" in rest: - x11_code = _resolve_keysym(parts[0].upper()) - if x11_code != 0: - layout[x11_code] = At1Key( - code=at1_code, - shift=True, - ) + if x11_code == 0: + continue + + try: + at1_code = int(parts[1], 16) + except ValueError as err: + logger.error("Syntax error at %s:%d: %s", path, lineno, err) + continue + rest = parts[2:] + + if x11_code not in layout: + layout[x11_code] = [] + layout[x11_code].append(At1Key( + code=at1_code, + shift=("shift" in rest), + altgr=("altgr" in rest), + ctrl=("ctrl" in rest), + )) + + if "addupper" in rest: + x11_code = _resolve_keysym(parts[0].upper()) + if x11_code != 0: + if x11_code not in layout: + layout[x11_code] = [] + layout[x11_code].append(At1Key( + code=at1_code, + shift=True, + )) return layout diff --git a/kvmd/keyboard/mappings.py b/kvmd/keyboard/mappings.py index b4bebbf3..310c50a0 100644 --- a/kvmd/keyboard/mappings.py +++ b/kvmd/keyboard/mappings.py @@ -163,161 +163,161 @@ class At1Key: X11_TO_AT1 = { - 65307: At1Key(code=1, shift=False), # XK_Escape - 33: At1Key(code=2, shift=True), # XK_exclam - 49: At1Key(code=2, shift=False), # XK_1 - 50: At1Key(code=3, shift=False), # XK_2 - 64: At1Key(code=3, shift=True), # XK_at - 35: At1Key(code=4, shift=True), # XK_numbersign - 51: At1Key(code=4, shift=False), # XK_3 - 36: At1Key(code=5, shift=True), # XK_dollar - 52: At1Key(code=5, shift=False), # XK_4 - 37: At1Key(code=6, shift=True), # XK_percent - 53: At1Key(code=6, shift=False), # XK_5 - 54: At1Key(code=7, shift=False), # XK_6 - 94: At1Key(code=7, shift=True), # XK_asciicircum - 38: At1Key(code=8, shift=True), # XK_ampersand - 55: At1Key(code=8, shift=False), # XK_7 - 42: At1Key(code=9, shift=True), # XK_asterisk - 56: At1Key(code=9, shift=False), # XK_8 - 40: At1Key(code=10, shift=True), # XK_parenleft - 57: At1Key(code=10, shift=False), # XK_9 - 41: At1Key(code=11, shift=True), # XK_parenright - 48: At1Key(code=11, shift=False), # XK_0 - 45: At1Key(code=12, shift=False), # XK_minus - 95: At1Key(code=12, shift=True), # XK_underscore - 43: At1Key(code=13, shift=True), # XK_plus - 61: At1Key(code=13, shift=False), # XK_equal - 65288: At1Key(code=14, shift=False), # XK_BackSpace - 65289: At1Key(code=15, shift=False), # XK_Tab - 81: At1Key(code=16, shift=True), # XK_Q - 113: At1Key(code=16, shift=False), # XK_q - 87: At1Key(code=17, shift=True), # XK_W - 119: At1Key(code=17, shift=False), # XK_w - 69: At1Key(code=18, shift=True), # XK_E - 101: At1Key(code=18, shift=False), # XK_e - 82: At1Key(code=19, shift=True), # XK_R - 114: At1Key(code=19, shift=False), # XK_r - 84: At1Key(code=20, shift=True), # XK_T - 116: At1Key(code=20, shift=False), # XK_t - 89: At1Key(code=21, shift=True), # XK_Y - 121: At1Key(code=21, shift=False), # XK_y - 85: At1Key(code=22, shift=True), # XK_U - 117: At1Key(code=22, shift=False), # XK_u - 73: At1Key(code=23, shift=True), # XK_I - 105: At1Key(code=23, shift=False), # XK_i - 79: At1Key(code=24, shift=True), # XK_O - 111: At1Key(code=24, shift=False), # XK_o - 80: At1Key(code=25, shift=True), # XK_P - 112: At1Key(code=25, shift=False), # XK_p - 91: At1Key(code=26, shift=False), # XK_bracketleft - 123: At1Key(code=26, shift=True), # XK_braceleft - 93: At1Key(code=27, shift=False), # XK_bracketright - 125: At1Key(code=27, shift=True), # XK_braceright - 65293: At1Key(code=28, shift=False), # XK_Return - 65507: At1Key(code=29, shift=False), # XK_Control_L - 65: At1Key(code=30, shift=True), # XK_A - 97: At1Key(code=30, shift=False), # XK_a - 83: At1Key(code=31, shift=True), # XK_S - 115: At1Key(code=31, shift=False), # XK_s - 68: At1Key(code=32, shift=True), # XK_D - 100: At1Key(code=32, shift=False), # XK_d - 70: At1Key(code=33, shift=True), # XK_F - 102: At1Key(code=33, shift=False), # XK_f - 71: At1Key(code=34, shift=True), # XK_G - 103: At1Key(code=34, shift=False), # XK_g - 72: At1Key(code=35, shift=True), # XK_H - 104: At1Key(code=35, shift=False), # XK_h - 74: At1Key(code=36, shift=True), # XK_J - 106: At1Key(code=36, shift=False), # XK_j - 75: At1Key(code=37, shift=True), # XK_K - 107: At1Key(code=37, shift=False), # XK_k - 76: At1Key(code=38, shift=True), # XK_L - 108: At1Key(code=38, shift=False), # XK_l - 58: At1Key(code=39, shift=True), # XK_colon - 59: At1Key(code=39, shift=False), # XK_semicolon - 34: At1Key(code=40, shift=True), # XK_quotedbl - 39: At1Key(code=40, shift=False), # XK_apostrophe - 96: At1Key(code=41, shift=False), # XK_grave - 126: At1Key(code=41, shift=True), # XK_asciitilde - 65505: At1Key(code=42, shift=False), # XK_Shift_L - 92: At1Key(code=43, shift=False), # XK_backslash - 124: At1Key(code=43, shift=True), # XK_bar - 90: At1Key(code=44, shift=True), # XK_Z - 122: At1Key(code=44, shift=False), # XK_z - 88: At1Key(code=45, shift=True), # XK_X - 120: At1Key(code=45, shift=False), # XK_x - 67: At1Key(code=46, shift=True), # XK_C - 99: At1Key(code=46, shift=False), # XK_c - 86: At1Key(code=47, shift=True), # XK_V - 118: At1Key(code=47, shift=False), # XK_v - 66: At1Key(code=48, shift=True), # XK_B - 98: At1Key(code=48, shift=False), # XK_b - 78: At1Key(code=49, shift=True), # XK_N - 110: At1Key(code=49, shift=False), # XK_n - 77: At1Key(code=50, shift=True), # XK_M - 109: At1Key(code=50, shift=False), # XK_m - 44: At1Key(code=51, shift=False), # XK_comma - 60: At1Key(code=51, shift=True), # XK_less - 46: At1Key(code=52, shift=False), # XK_period - 62: At1Key(code=52, shift=True), # XK_greater - 47: At1Key(code=53, shift=False), # XK_slash - 63: At1Key(code=53, shift=True), # XK_question - 65506: At1Key(code=54, shift=False), # XK_Shift_R - 215: At1Key(code=55, shift=False), # XK_multiply - 65513: At1Key(code=56, shift=False), # XK_Alt_L - 32: At1Key(code=57, shift=False), # XK_space - 65509: At1Key(code=58, shift=False), # XK_Caps_Lock - 65470: At1Key(code=59, shift=False), # XK_F1 - 65471: At1Key(code=60, shift=False), # XK_F2 - 65472: At1Key(code=61, shift=False), # XK_F3 - 65473: At1Key(code=62, shift=False), # XK_F4 - 65474: At1Key(code=63, shift=False), # XK_F5 - 65475: At1Key(code=64, shift=False), # XK_F6 - 65476: At1Key(code=65, shift=False), # XK_F7 - 65477: At1Key(code=66, shift=False), # XK_F8 - 65478: At1Key(code=67, shift=False), # XK_F9 - 65479: At1Key(code=68, shift=False), # XK_F10 - 65407: At1Key(code=69, shift=False), # XK_Num_Lock - 65300: At1Key(code=70, shift=False), # XK_Scroll_Lock - 65463: At1Key(code=71, shift=False), # XK_KP_7 - 65464: At1Key(code=72, shift=False), # XK_KP_8 - 65465: At1Key(code=73, shift=False), # XK_KP_9 - 65453: At1Key(code=74, shift=False), # XK_KP_Subtract - 65460: At1Key(code=75, shift=False), # XK_KP_4 - 65461: At1Key(code=76, shift=False), # XK_KP_5 - 65462: At1Key(code=77, shift=False), # XK_KP_6 - 65451: At1Key(code=78, shift=False), # XK_KP_Add - 65457: At1Key(code=79, shift=False), # XK_KP_1 - 65458: At1Key(code=80, shift=False), # XK_KP_2 - 65459: At1Key(code=81, shift=False), # XK_KP_3 - 65456: At1Key(code=82, shift=False), # XK_KP_0 - 65454: At1Key(code=83, shift=False), # XK_KP_Decimal - 65301: At1Key(code=84, shift=False), # XK_Sys_Req - 65480: At1Key(code=87, shift=False), # XK_F11 - 65481: At1Key(code=88, shift=False), # XK_F12 - 65421: At1Key(code=57372, shift=False), # XK_KP_Enter - 65508: At1Key(code=57373, shift=False), # XK_Control_R - 65455: At1Key(code=57397, shift=False), # XK_KP_Divide - 65027: At1Key(code=57400, shift=False), # XK_ISO_Level3_Shift - 65514: At1Key(code=57400, shift=False), # XK_Alt_R - 65299: At1Key(code=57414, shift=False), # XK_Pause - 65360: At1Key(code=57415, shift=False), # XK_Home - 65362: At1Key(code=57416, shift=False), # XK_Up - 65365: At1Key(code=57417, shift=False), # XK_Page_Up - 65361: At1Key(code=57419, shift=False), # XK_Left - 65363: At1Key(code=57421, shift=False), # XK_Right - 65367: At1Key(code=57423, shift=False), # XK_End - 65364: At1Key(code=57424, shift=False), # XK_Down - 65366: At1Key(code=57425, shift=False), # XK_Page_Down - 65379: At1Key(code=57426, shift=False), # XK_Insert - 65535: At1Key(code=57427, shift=False), # XK_Delete - 65511: At1Key(code=57435, shift=False), # XK_Meta_L - 65515: At1Key(code=57435, shift=False), # XK_Super_L - 65512: At1Key(code=57436, shift=False), # XK_Meta_R - 65516: At1Key(code=57436, shift=False), # XK_Super_R - 65383: At1Key(code=57437, shift=False), # XK_Menu - 269025071: At1Key(code=57438, shift=False), # XK_XF86_Sleep + 65307: [At1Key(code=1, shift=False)], # XK_Escape + 33: [At1Key(code=2, shift=True)], # XK_exclam + 49: [At1Key(code=2, shift=False)], # XK_1 + 50: [At1Key(code=3, shift=False)], # XK_2 + 64: [At1Key(code=3, shift=True)], # XK_at + 35: [At1Key(code=4, shift=True)], # XK_numbersign + 51: [At1Key(code=4, shift=False)], # XK_3 + 36: [At1Key(code=5, shift=True)], # XK_dollar + 52: [At1Key(code=5, shift=False)], # XK_4 + 37: [At1Key(code=6, shift=True)], # XK_percent + 53: [At1Key(code=6, shift=False)], # XK_5 + 54: [At1Key(code=7, shift=False)], # XK_6 + 94: [At1Key(code=7, shift=True)], # XK_asciicircum + 38: [At1Key(code=8, shift=True)], # XK_ampersand + 55: [At1Key(code=8, shift=False)], # XK_7 + 42: [At1Key(code=9, shift=True)], # XK_asterisk + 56: [At1Key(code=9, shift=False)], # XK_8 + 40: [At1Key(code=10, shift=True)], # XK_parenleft + 57: [At1Key(code=10, shift=False)], # XK_9 + 41: [At1Key(code=11, shift=True)], # XK_parenright + 48: [At1Key(code=11, shift=False)], # XK_0 + 45: [At1Key(code=12, shift=False)], # XK_minus + 95: [At1Key(code=12, shift=True)], # XK_underscore + 43: [At1Key(code=13, shift=True)], # XK_plus + 61: [At1Key(code=13, shift=False)], # XK_equal + 65288: [At1Key(code=14, shift=False)], # XK_BackSpace + 65289: [At1Key(code=15, shift=False)], # XK_Tab + 81: [At1Key(code=16, shift=True)], # XK_Q + 113: [At1Key(code=16, shift=False)], # XK_q + 87: [At1Key(code=17, shift=True)], # XK_W + 119: [At1Key(code=17, shift=False)], # XK_w + 69: [At1Key(code=18, shift=True)], # XK_E + 101: [At1Key(code=18, shift=False)], # XK_e + 82: [At1Key(code=19, shift=True)], # XK_R + 114: [At1Key(code=19, shift=False)], # XK_r + 84: [At1Key(code=20, shift=True)], # XK_T + 116: [At1Key(code=20, shift=False)], # XK_t + 89: [At1Key(code=21, shift=True)], # XK_Y + 121: [At1Key(code=21, shift=False)], # XK_y + 85: [At1Key(code=22, shift=True)], # XK_U + 117: [At1Key(code=22, shift=False)], # XK_u + 73: [At1Key(code=23, shift=True)], # XK_I + 105: [At1Key(code=23, shift=False)], # XK_i + 79: [At1Key(code=24, shift=True)], # XK_O + 111: [At1Key(code=24, shift=False)], # XK_o + 80: [At1Key(code=25, shift=True)], # XK_P + 112: [At1Key(code=25, shift=False)], # XK_p + 91: [At1Key(code=26, shift=False)], # XK_bracketleft + 123: [At1Key(code=26, shift=True)], # XK_braceleft + 93: [At1Key(code=27, shift=False)], # XK_bracketright + 125: [At1Key(code=27, shift=True)], # XK_braceright + 65293: [At1Key(code=28, shift=False)], # XK_Return + 65507: [At1Key(code=29, shift=False)], # XK_Control_L + 65: [At1Key(code=30, shift=True)], # XK_A + 97: [At1Key(code=30, shift=False)], # XK_a + 83: [At1Key(code=31, shift=True)], # XK_S + 115: [At1Key(code=31, shift=False)], # XK_s + 68: [At1Key(code=32, shift=True)], # XK_D + 100: [At1Key(code=32, shift=False)], # XK_d + 70: [At1Key(code=33, shift=True)], # XK_F + 102: [At1Key(code=33, shift=False)], # XK_f + 71: [At1Key(code=34, shift=True)], # XK_G + 103: [At1Key(code=34, shift=False)], # XK_g + 72: [At1Key(code=35, shift=True)], # XK_H + 104: [At1Key(code=35, shift=False)], # XK_h + 74: [At1Key(code=36, shift=True)], # XK_J + 106: [At1Key(code=36, shift=False)], # XK_j + 75: [At1Key(code=37, shift=True)], # XK_K + 107: [At1Key(code=37, shift=False)], # XK_k + 76: [At1Key(code=38, shift=True)], # XK_L + 108: [At1Key(code=38, shift=False)], # XK_l + 58: [At1Key(code=39, shift=True)], # XK_colon + 59: [At1Key(code=39, shift=False)], # XK_semicolon + 34: [At1Key(code=40, shift=True)], # XK_quotedbl + 39: [At1Key(code=40, shift=False)], # XK_apostrophe + 96: [At1Key(code=41, shift=False)], # XK_grave + 126: [At1Key(code=41, shift=True)], # XK_asciitilde + 65505: [At1Key(code=42, shift=False)], # XK_Shift_L + 92: [At1Key(code=43, shift=False)], # XK_backslash + 124: [At1Key(code=43, shift=True)], # XK_bar + 90: [At1Key(code=44, shift=True)], # XK_Z + 122: [At1Key(code=44, shift=False)], # XK_z + 88: [At1Key(code=45, shift=True)], # XK_X + 120: [At1Key(code=45, shift=False)], # XK_x + 67: [At1Key(code=46, shift=True)], # XK_C + 99: [At1Key(code=46, shift=False)], # XK_c + 86: [At1Key(code=47, shift=True)], # XK_V + 118: [At1Key(code=47, shift=False)], # XK_v + 66: [At1Key(code=48, shift=True)], # XK_B + 98: [At1Key(code=48, shift=False)], # XK_b + 78: [At1Key(code=49, shift=True)], # XK_N + 110: [At1Key(code=49, shift=False)], # XK_n + 77: [At1Key(code=50, shift=True)], # XK_M + 109: [At1Key(code=50, shift=False)], # XK_m + 44: [At1Key(code=51, shift=False)], # XK_comma + 60: [At1Key(code=51, shift=True)], # XK_less + 46: [At1Key(code=52, shift=False)], # XK_period + 62: [At1Key(code=52, shift=True)], # XK_greater + 47: [At1Key(code=53, shift=False)], # XK_slash + 63: [At1Key(code=53, shift=True)], # XK_question + 65506: [At1Key(code=54, shift=False)], # XK_Shift_R + 215: [At1Key(code=55, shift=False)], # XK_multiply + 65513: [At1Key(code=56, shift=False)], # XK_Alt_L + 32: [At1Key(code=57, shift=False)], # XK_space + 65509: [At1Key(code=58, shift=False)], # XK_Caps_Lock + 65470: [At1Key(code=59, shift=False)], # XK_F1 + 65471: [At1Key(code=60, shift=False)], # XK_F2 + 65472: [At1Key(code=61, shift=False)], # XK_F3 + 65473: [At1Key(code=62, shift=False)], # XK_F4 + 65474: [At1Key(code=63, shift=False)], # XK_F5 + 65475: [At1Key(code=64, shift=False)], # XK_F6 + 65476: [At1Key(code=65, shift=False)], # XK_F7 + 65477: [At1Key(code=66, shift=False)], # XK_F8 + 65478: [At1Key(code=67, shift=False)], # XK_F9 + 65479: [At1Key(code=68, shift=False)], # XK_F10 + 65407: [At1Key(code=69, shift=False)], # XK_Num_Lock + 65300: [At1Key(code=70, shift=False)], # XK_Scroll_Lock + 65463: [At1Key(code=71, shift=False)], # XK_KP_7 + 65464: [At1Key(code=72, shift=False)], # XK_KP_8 + 65465: [At1Key(code=73, shift=False)], # XK_KP_9 + 65453: [At1Key(code=74, shift=False)], # XK_KP_Subtract + 65460: [At1Key(code=75, shift=False)], # XK_KP_4 + 65461: [At1Key(code=76, shift=False)], # XK_KP_5 + 65462: [At1Key(code=77, shift=False)], # XK_KP_6 + 65451: [At1Key(code=78, shift=False)], # XK_KP_Add + 65457: [At1Key(code=79, shift=False)], # XK_KP_1 + 65458: [At1Key(code=80, shift=False)], # XK_KP_2 + 65459: [At1Key(code=81, shift=False)], # XK_KP_3 + 65456: [At1Key(code=82, shift=False)], # XK_KP_0 + 65454: [At1Key(code=83, shift=False)], # XK_KP_Decimal + 65301: [At1Key(code=84, shift=False)], # XK_Sys_Req + 65480: [At1Key(code=87, shift=False)], # XK_F11 + 65481: [At1Key(code=88, shift=False)], # XK_F12 + 65421: [At1Key(code=57372, shift=False)], # XK_KP_Enter + 65508: [At1Key(code=57373, shift=False)], # XK_Control_R + 65455: [At1Key(code=57397, shift=False)], # XK_KP_Divide + 65027: [At1Key(code=57400, shift=False)], # XK_ISO_Level3_Shift + 65514: [At1Key(code=57400, shift=False)], # XK_Alt_R + 65299: [At1Key(code=57414, shift=False)], # XK_Pause + 65360: [At1Key(code=57415, shift=False)], # XK_Home + 65362: [At1Key(code=57416, shift=False)], # XK_Up + 65365: [At1Key(code=57417, shift=False)], # XK_Page_Up + 65361: [At1Key(code=57419, shift=False)], # XK_Left + 65363: [At1Key(code=57421, shift=False)], # XK_Right + 65367: [At1Key(code=57423, shift=False)], # XK_End + 65364: [At1Key(code=57424, shift=False)], # XK_Down + 65366: [At1Key(code=57425, shift=False)], # XK_Page_Down + 65379: [At1Key(code=57426, shift=False)], # XK_Insert + 65535: [At1Key(code=57427, shift=False)], # XK_Delete + 65511: [At1Key(code=57435, shift=False)], # XK_Meta_L + 65515: [At1Key(code=57435, shift=False)], # XK_Super_L + 65512: [At1Key(code=57436, shift=False)], # XK_Meta_R + 65516: [At1Key(code=57436, shift=False)], # XK_Super_R + 65383: [At1Key(code=57437, shift=False)], # XK_Menu + 269025071: [At1Key(code=57438, shift=False)], # XK_XF86_Sleep } diff --git a/kvmd/keyboard/mappings.py.mako b/kvmd/keyboard/mappings.py.mako index 35b3b281..1c13b8a9 100644 --- a/kvmd/keyboard/mappings.py.mako +++ b/kvmd/keyboard/mappings.py.mako @@ -62,7 +62,7 @@ class At1Key: X11_TO_AT1 = { % for km in sorted(keymap, key=operator.attrgetter("at1_code")): % for x11_key in sorted(km.x11_keys, key=(lambda key: (key.code, key.shift))): - ${x11_key.code}: At1Key(code=${km.at1_code}, shift=${x11_key.shift}), # ${x11_key.name} + ${x11_key.code}: [At1Key(code=${km.at1_code}, shift=${x11_key.shift})], # ${x11_key.name} % endfor % endfor } diff --git a/kvmd/keyboard/printer.py b/kvmd/keyboard/printer.py index 2fb7d756..acef102b 100644 --- a/kvmd/keyboard/printer.py +++ b/kvmd/keyboard/printer.py @@ -24,13 +24,13 @@ from typing import Tuple from typing import Dict from typing import Generator -from .keysym import SymmapWebKey +from .keysym import SymmapModifiers # ===== def text_to_web_keys( text: str, - symmap: Dict[int, SymmapWebKey], + symmap: Dict[int, Dict[int, str]], shift_key: str="ShiftLeft", ) -> Generator[Tuple[str, bool], None, None]: @@ -40,25 +40,32 @@ def text_to_web_keys( for ch in text: try: code = ord(ch) - if not (0x20 <= code <= 0x7E): + if 0x20 <= code <= 0x7E: # https://stackoverflow.com/questions/12343987/convert-ascii-character-to-x11-keycode # https://www.ascii-code.com + keys = symmap[code] + elif code == 0x0A: # Enter: + keys = {0: "Enter"} + else: continue - key = symmap[code] except Exception: continue - if key.altgr or key.ctrl: - continue # Not supported yet - if key.shift and not shifted: - yield (shift_key, True) - shifted = True - elif not key.shift and shifted: - yield (shift_key, False) - shifted = False + for (modifiers, key) in reversed(keys.items()): + if (modifiers & SymmapModifiers.ALTGR) or (modifiers & SymmapModifiers.CTRL): + # Not supported yet + continue + + if modifiers & SymmapModifiers.SHIFT and not shifted: + yield (shift_key, True) + shifted = True + elif not (modifiers & SymmapModifiers.SHIFT) and shifted: + yield (shift_key, False) + shifted = False - yield (key.name, True) - yield (key.name, False) + yield (key, True) + yield (key, False) + break if shifted: yield (shift_key, False) |