From de1e1d09f5ab46f0b07f55b2bc5d9722a156bb2c Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sat, 14 Nov 2020 15:36:18 +0100 Subject: render: Add keylayout renderer Not really functional, since we cannot control shift states and keys. --- lulua/keyboard.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lulua/render.py | 49 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/lulua/keyboard.py b/lulua/keyboard.py index c9d3adb..cf96efc 100644 --- a/lulua/keyboard.py +++ b/lulua/keyboard.py @@ -225,6 +225,73 @@ _buttonToWinScancode = { 'Fr_ctrl': (0xe0, 0x1D, ), } +# see https://eastmanreference.com/complete-list-of-applescript-key-codes +_buttonToOsxKeycode = { + 'Bl1': 50, + 'Bl2': 18, + 'Bl3': 19, + 'Bl4': 20, + 'Bl5': 21, + 'Bl6': 23, + 'Bl7': 22, + 'Br6': 26, + 'Br5': 28, + 'Br4': 25, + 'Br3': 29, + 'Br2': 27, + 'Br1': 24, + 'Br_bs': 51, + 'Cl_tab': 48, + 'Cl1': 12, + 'Cl2': 13, + 'Cl3': 14, + 'Cl4': 15, + 'Cl5': 17, + 'Cr7': 16, + 'Cr6': 32, + 'Cr5': 34, + 'Cr4': 31, + 'Cr3': 35, + 'Cr2': 33, + 'Cr1': 30, + 'CD_ret': 36, + 'Dl_caps': 57, + 'Dl1': 0, + 'Dl2': 1, + 'Dl3': 2, + 'Dl4': 3, + 'Dl5': 5, + 'Dr7': 4, + 'Dr6': 38, + 'Dr5': 40, + 'Dr4': 37, + 'Dr3': 41, + 'Dr2': 39, + #'Dr1': 51, + 'El_shift': 57, + #'El1': 6, + 'El2': 6, + 'El3': 7, + 'El4': 8, + 'El5': 9, + 'El6': 11, + 'Er5': 45, + 'Er4': 46, + 'Er3': 43, + 'Er2': 47, + 'Er1': 44, + 'Er_shift': 60, + 'Fl_ctrl': 59, + 'Fl_win': 55, + 'Fl_alt': 58, + 'Fl_space': 49, + 'Fr_space': 49, + 'Fr_altgr': 61, + 'Fr_win': 55, + #'Fr_menu': , + #'Fr_ctrl': 105, + } + class Button: __slots__ = ('width', 'isMarked', 'i') _idToName : Dict[int, Text] = {} @@ -271,6 +338,10 @@ class Button: def windowsScancode (self): return _buttonToWinScancode[self.name] + @property + def osxKeycode (self): + return _buttonToOsxKeycode[self.name] + @classmethod def deserialize (self, data: Dict): kindMap = {'standard': Button, 'letter': LetterButton, 'multi': MultiRowButton} diff --git a/lulua/render.py b/lulua/render.py index b8514f0..08bc9bc 100644 --- a/lulua/render.py +++ b/lulua/render.py @@ -23,7 +23,7 @@ from collections import namedtuple, defaultdict from itertools import chain from operator import attrgetter from datetime import datetime -from xml.etree import ElementTree +from xml.etree import ElementTree as ET import svgwrite import yaml @@ -410,7 +410,6 @@ def renderAsk (args): keyboard = defaultKeyboards[args.keyboard] layout = defaultLayouts[args.layout].specialize (keyboard) - ET = ElementTree namespaces = { 'xmlns:android': 'http://schemas.android.com/apk/res/android', 'xmlns:ask': 'http://schemas.android.com/apk/res-auto', @@ -508,6 +507,50 @@ def renderWinKbd (args): fd.write (makeDriverSources (scancodeToVk, wcharMap)) +def renderKeylayout (args): + """ + For macOS + + See: + https://developer.apple.com/library/archive/technotes/tn2056/_index.html#//apple_ref/doc/uid/DTS10003085 + """ + + logging.info ('MacOS does not support custom modifiers and thus your layout ' + 'is probably not going to work.') + + keyboard = defaultKeyboards[args.keyboard] + layout = defaultLayouts[args.layout].specialize (keyboard) + nextId = 0 + + docroot = ET.Element('keyboard', group="0", id="14242", name=layout.name, maxout="3") + + # fixed modifiers (XXX) + modmapId = nextId + modmap = ET.SubElement (docroot, 'modifierMap', id=str (modmapId), defaultIndex='0') + nextId += 1 + for i, keys in enumerate (('', 'anyShift caps?', 'caps', 'anyOption')): + keymapSelect = ET.SubElement (modmap, 'keyMapSelect', mapIndex=str (i)) + modifier = ET.SubElement (keymapSelect, 'modifier', keys=keys) + + # keymaps + keymapSetId = nextId + keymapSet = ET.SubElement (docroot, 'keyMapSet', id=str (keymapSetId)) + nextId += 1 + for i, l in enumerate (layout.layers): + keymap = ET.SubElement (keymapSet, 'keyMap', index=str (i)) + for btn, text in l.layout.items (): + ET.SubElement (keymap, 'key', code=str (btn.osxKeycode), output=text) + + layouts = ET.SubElement (docroot, 'layouts') + layout = ET.SubElement (layouts, 'layout', first='0', last='0', modifiers=str (modmapId), mapSet=str (keymapSetId)) + + decl = b""" + +""" + with open (args.output, 'wb') as fd: + fd.write (decl) + fd.write (ET.tostring (docroot, encoding='utf-8')) + def yamlload (s): try: with open (s) as fd: @@ -542,6 +585,8 @@ def render (): sp.set_defaults (func=renderAsk) sp = subparsers.add_parser('winkbd') sp.set_defaults (func=renderWinKbd) + sp = subparsers.add_parser('keylayout') + sp.set_defaults (func=renderKeylayout) parser.add_argument('output', metavar='FILE', help='Output file') logging.basicConfig (level=logging.INFO) -- cgit v1.2.3