summaryrefslogtreecommitdiff
path: root/lulua/render.py
diff options
context:
space:
mode:
Diffstat (limited to 'lulua/render.py')
-rw-r--r--lulua/render.py247
1 files changed, 21 insertions, 226 deletions
diff --git a/lulua/render.py b/lulua/render.py
index 78e2b17..b8514f0 100644
--- a/lulua/render.py
+++ b/lulua/render.py
@@ -32,6 +32,7 @@ from .layout import LITTLE, RING, MIDDLE, INDEX, THUMB, GenericLayout, defaultLa
from .writer import Writer
from .keyboard import defaultKeyboards, LetterButton
from .util import first, displayText
+from .winkbd import qwertyScancodeToVk, VirtualKey, WChar, makeDriverSources
RendererSettings = namedtuple ('RendererSetting', ['buttonMargin', 'middleGap', 'buttonWidth', 'rounded', 'shadowOffset', 'markerStroke'])
@@ -474,244 +475,38 @@ def renderWinKbd (args):
resPath = pkg_resources.resource_filename (__package__, 'data/winkbd')
with open (args.output, 'w') as fd:
- lines = []
- lines.append (f'/* This header was auto-generated by {__package__}. It is included by {resPath}/keyboard.h. Do not modify. */')
- lines.append ('')
-
- # copied from kbdneo2.c as well
- # XXX: modifier keys are fixed for now
- # maps virtual keys (first value) to shift bitfield value (second value)
- lines.append ('#define MODIFIER_BITS\\')
- lines.append (""" { VK_SHIFT , KBDSHIFT }, \\
- { VK_CONTROL , KBDCTRL }, \\
- { VK_MENU , KBDALT }, \\
- { VK_OEM_8 , KBDKANA }, \\
- { VK_OEM_102 , 16 },""")
-
- # copied from kbdneo2.c
- # maps a shift bitfield value (array index) to a layer number in
- # virtual key translation (VK_TO_WCHARS, array value)
- lines.append ('#define CHAR_MODIFIERS_MASK 24')
- lines.append ('#define CHAR_MODIFIERS\\')
- lines.append ('\t{ 0, 1, 6, 7, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 3, 8, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 2, 4, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 5, }')
-
- # this is the standard layout from windows’ kbd.h (for KBD_TYPE == 4)
- scancodeToVk = {
- 'T01': 'ESCAPE',
- 'T02': '1',
- 'T03': '2',
- 'T04': '3',
- 'T05': '4',
- 'T06': '5',
- 'T07': '6',
- 'T08': '7',
- 'T09': '8',
- 'T0A': '9',
- 'T0B': '0',
- 'T0C': 'OEM_MINUS',
- 'T0D': 'OEM_PLUS',
- 'T0E': 'BACK',
- 'T0F': 'TAB',
- 'T10': 'Q',
- 'T11': 'W',
- 'T12': 'E',
- 'T13': 'R',
- 'T14': 'T',
- 'T15': 'Y',
- 'T16': 'U',
- 'T17': 'I',
- 'T18': 'O',
- 'T19': 'P',
- 'T1A': 'OEM_4',
- 'T1B': 'OEM_6',
- 'T1C': 'RETURN',
- 'T1D': 'LCONTROL',
- 'T1E': 'A',
- 'T1F': 'S',
- 'T20': 'D',
- 'T21': 'F',
- 'T22': 'G',
- 'T23': 'H',
- 'T24': 'J',
- 'T25': 'K',
- 'T26': 'L',
- 'T27': 'OEM_1',
- 'T28': 'OEM_7',
- 'T29': 'OEM_3',
- 'T2A': 'LSHIFT',
- 'T2B': 'OEM_5',
- 'T2C': 'Z',
- 'T2D': 'X',
- 'T2E': 'C',
- 'T2F': 'V',
- 'T30': 'B',
- 'T31': 'N',
- 'T32': 'M',
- 'T33': 'OEM_COMMA',
- 'T34': 'OEM_PERIOD',
- 'T35': 'OEM_2',
- 'T36': 'RSHIFT',
- 'T37': 'MULTIPLY',
- 'T38': 'LMENU',
- 'T39': 'SPACE',
- 'T3A': 'CAPITAL',
- 'T3B': 'F1',
- 'T3C': 'F2',
- 'T3D': 'F3',
- 'T3E': 'F4',
- 'T3F': 'F5',
- 'T40': 'F6',
- 'T41': 'F7',
- 'T42': 'F8',
- 'T43': 'F9',
- 'T44': 'F10',
- 'T45': 'NUMLOCK',
- 'T46': 'SCROLL',
- 'T47': 'HOME',
- 'T48': 'UP',
- 'T49': 'PRIOR',
- 'T4A': 'SUBTRACT',
- 'T4B': 'LEFT',
- 'T4C': 'CLEAR',
- 'T4D': 'RIGHT',
- 'T4E': 'ADD',
- 'T4F': 'END',
- 'T50': 'DOWN',
- 'T51': 'NEXT',
- 'T52': 'INSERT',
- 'T53': 'DELETE',
- 'T54': 'SNAPSHOT',
- 'T56': 'OEM_102',
- 'T57': 'F11',
- 'T58': 'F12',
- 'T59': 'CLEAR',
- 'T5A': 'OEM_WSCTRL',
- 'T5B': 'OEM_FINISH',
- 'T5C': 'OEM_JUMP',
- 'T5D': 'EREOF',
- 'T5E': 'OEM_BACKTAB',
- 'T5F': 'OEM_AUTO',
- 'T62': 'ZOOM',
- 'T63': 'HELP',
- 'T64': 'F13',
- 'T65': 'F14',
- 'T66': 'F15',
- 'T67': 'F16',
- 'T68': 'F17',
- 'T69': 'F18',
- 'T6A': 'F19',
- 'T6B': 'F20',
- 'T6C': 'F21',
- 'T6D': 'F22',
- 'T6E': 'F23',
- 'T6F': 'OEM_PA3',
- 'T71': 'OEM_RESET',
- 'T73': 'ABNT_C1',
- 'T76': 'F24',
- 'T7B': 'OEM_PA1',
- 'T7C': 'TAB',
- 'T7E': 'ABNT_C2',
- 'T7F': 'OEM_PA2',
-
- 'X10': 'MEDIA_PREV_TRACK',
- 'X19': 'MEDIA_NEXT_TRACK',
- 'X1C': 'RETURN',
- 'X1D': 'RCONTROL',
- 'X20': 'VOLUME_MUTE',
- 'X21': 'LAUNCH_APP2',
- 'X22': 'MEDIA_PLAY_PAUSE',
- 'X24': 'MEDIA_STOP',
- 'X2E': 'VOLUME_DOWN',
- 'X30': 'VOLUME_UP',
- 'X32': 'BROWSER_HOME',
- 'X35': 'DIVIDE',
- 'X37': 'SNAPSHOT',
- 'X38': 'RMENU',
- 'X46': 'CANCEL',
- 'X47': 'HOME',
- 'X48': 'UP',
- 'X49': 'PRIOR',
- 'X4B': 'LEFT',
- 'X4D': 'RIGHT',
- 'X4F': 'END',
- 'X50': 'DOWN',
- 'X51': 'NEXT',
- 'X52': 'INSERT',
- 'X53': 'DELETE',
- 'X5B': 'LWIN',
- 'X5C': 'RWIN',
- 'X5D': 'APPS',
- 'X5E': 'POWER',
- 'X5F': 'SLEEP',
- 'X65': 'BROWSER_SEARCH',
- 'X66': 'BROWSER_FAVORITES',
- 'X67': 'BROWSER_REFRESH',
- 'X68': 'BROWSER_STOP',
- 'X69': 'BROWSER_FORWARD',
- 'X6A': 'BROWSER_BACK',
- 'X6B': 'LAUNCH_APP1',
- 'X6C': 'LAUNCH_MAIL',
- 'X6D': 'LAUNCH_MEDIA_SELECT',
- }
- # modifications copied from kbdneo2.c
- # maps modifier keys to oem values used above.
+ fd.write (f'/* This header was auto-generated by {__package__}. Do not modify directly. */\n\n')
+
+ scancodeToVk = dict (qwertyScancodeToVk)
+ # Updates for 3rd and 4th layer modifier keys
scancodeToVk.update ({
# mod 3
- 'T2B': 'OEM_102',
- 'T3A': 'OEM_102',
+ (0x2B, ): (VirtualKey.OEM_102, ),
+ (0x3A, ): (VirtualKey.OEM_102, ),
# mod 4
- 'X38': 'OEM_8',
- 'T56': 'OEM_8',
+ (0x56, ): (VirtualKey.OEM_8, ),
+ (0xe0, 0x38): (VirtualKey.OEM_8, ),
})
- for k, v in scancodeToVk.items ():
- lines.append (f'#undef {k}')
- if len (v) == 1:
- # character value if not symbolic
- lines.append (f'#define {k} \'{v}\'')
- else:
- lines.append (f'#define {k} _EQ({v})')
- lines.append ('')
- lines.append ('#define VK_TO_WCH6 \\')
+ # translate keyboard buttons to text
+ def toWindows (s):
+ # convert to windows-convention
+ if s == '\n':
+ s = '\r'
+ return s
+ wcharMap = []
for btn in unique (keyboard.keys (), key=attrgetter ('windowsScancode')):
- def toUnicode (s):
- if s is None:
- return 'WCH_NONE'
- elif len (s) != 1:
- logging.error (f'only single-character strings are supported, ignoring {s}')
- return 'WCH_NONE'
- elif s == '\n':
- # convert to windows-convention
- s = '\r'
- return f'0x{ord (s):x} /*{repr (s)}*/'
-
text = list (layout.getButtonText (btn))
- assert len (text) < 7, "supporting six layers only right now"
# skip unused keys
- if sum (map (lambda x: 1 if x is not None else 0, text)) == 0:
+ if len (list (filter (lambda x: x is not None, text))) == 0:
continue
- # fixed-length array, need padding
- mappedText = [toUnicode (s) for s in text]
- while len (mappedText) < 6:
- mappedText.append ('WCH_NONE')
+ mappedText = [toWindows (s) for s in text]
+ vk = next (filter (lambda x: isinstance (x, VirtualKey), scancodeToVk[btn.windowsScancode]))
+ wcharMap.append ((vk, 0, mappedText))
- vk = scancodeToVk[btn.windowsScancode]
- if len (vk) == 1:
- # character value
- vk = f"'{vk}'"
- else:
- # symbolic value
- vk = f'VK_{vk}'
- mappingStr = ', '.join (mappedText)
- lines.append (f'\t{{ {vk}, 0, {mappingStr} }}, \\')
- # NUL-termination entry is already present in keyboard.c
- lines.append ('\n')
-
- fd.write ('\n'.join (lines))
- logging.info ('refer to README.rst on how to build a windows driver. '
- f'Template files are located in {resPath}')
+ fd.write (makeDriverSources (scancodeToVk, wcharMap))
def yamlload (s):
try: