Skip to content

Commit 2cf10cf

Browse files
keyboardtopads: add combination of keys to generate hotkeys
Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
1 parent 50892fb commit 2cf10cf

2 files changed

Lines changed: 74 additions & 28 deletions

File tree

package/batocera/controllers/pads/keyboardtopads/keyboardToPads.py

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,31 @@
1111
import re
1212
from pathlib import Path
1313

14+
class Loader(yaml.SafeLoader):
15+
pass
16+
17+
def construct_mapping(self, node):
18+
pairs = self.construct_pairs(node, deep=True)
19+
try:
20+
return dict(pairs)
21+
except TypeError:
22+
rv = {}
23+
for key, value in pairs:
24+
if isinstance(key, list):
25+
key = tuple(key)
26+
rv[key] = value
27+
return rv
28+
29+
Loader.construct_mapping = construct_mapping
30+
Loader.add_constructor('tag:yaml.org,2002:map', Loader.construct_mapping)
31+
1432
class KeyboardController:
1533

1634
def generateRules(self, configFile) -> str:
1735
rules = ""
1836
config = {}
1937
with open(configFile, 'r') as file:
20-
config = yaml.safe_load(file)
38+
config = yaml.load(file, Loader=Loader)
2139

2240
if "target_devices" not in config:
2341
raise Exception("missing target_devices entry in config file")
@@ -38,10 +56,24 @@ def generateRules(self, configFile) -> str:
3856
rules += "ENV{ID_INPUT_JOYSTICK}=\"1\", ENV{ID_INPUT_KEYBOARD}=\"0\", ENV{ID_INPUT_KEY}=\"0\"\n"
3957
return rules
4058

59+
def checkMapping(self, mapping):
60+
mappingParts = mapping.split(':')
61+
if len(mappingParts) not in [2, 3]:
62+
raise Exception("invalid key "+mapping)
63+
if mappingParts[0] not in ["key", "abs", "btn"]:
64+
raise Exception("invalid key type "+mapping)
65+
66+
def checkValue(self, value):
67+
valueParts = value.split(':')
68+
if len(valueParts) not in [2, 3]:
69+
raise Exception("invalid key "+value)
70+
if valueParts[0] not in ["key", "abs", "btn"]:
71+
raise Exception("invalid key type "+value)
72+
4173
def generateCommand(self, configFile, inputFile) -> list[str]:
4274
config = {}
4375
with open(configFile, 'r') as file:
44-
config = yaml.safe_load(file)
76+
config = yaml.load(file, Loader=Loader) # specific load for mapping as array (combination of keys ["key:a", "key:b"] : "key:exit")
4577

4678
cmd = ["evsieve", "--input", inputFile, "persist=exit" ]
4779

@@ -59,33 +91,46 @@ def generateCommand(self, configFile, inputFile) -> list[str]:
5991

6092
# check mappings and values
6193
for mapping, value in target_device["mapping"].items():
62-
mappingParts = mapping.split(':')
63-
valueParts = value.split(':')
64-
if len(mappingParts) not in [2, 3]:
65-
raise Exception("invalid key "+mapping)
66-
if len(valueParts) not in [2, 3]:
67-
raise Exception("invalid key "+value)
68-
if mappingParts[0] not in ["key", "abs", "btn"]:
69-
raise Exception("invalid key type "+mapping)
70-
if valueParts[0] not in ["key", "abs", "btn"]:
71-
raise Exception("invalid key type "+value)
72-
73-
# add mappings
94+
if type(mapping) is tuple:
95+
for t in mapping:
96+
self.checkMapping(t)
97+
else:
98+
self.checkMapping(mapping)
99+
self.checkValue(value)
100+
101+
# add key combinations first, to not block them (do, doing a first loop on all device for key combinations)
102+
for target_device in config["target_devices"]:
103+
for mapping_tuple, value in target_device["mapping"].items():
104+
if type(mapping_tuple) is tuple:
105+
cmd.extend(["--hook"])
106+
for mapping in mapping_tuple:
107+
mappingParts = mapping.split(':')
108+
mappingtypename = mappingParts[0] + ":" + mappingParts[1]
109+
valueParts = value.split(':')
110+
valuetypename = valueParts[0] + ":" + valueParts[1]
111+
cmd.extend(["{}".format(mappingtypename)])
112+
cmd.extend(["send-key={}".format(valuetypename)]) # should be hotkeys only
113+
114+
# redo the loop to add the keys, without the checks this time
115+
for target_device in config["target_devices"]:
116+
# simple keys
74117
for mapping, value in target_device["mapping"].items():
75-
mappingParts = mapping.split(':')
76-
mappingtypename = mappingParts[0] + ":" + mappingParts[1]
77-
valueParts = value.split(':')
78-
valuetypename = valueParts[0] + ":" + valueParts[1]
79-
cmd.extend(["--block", "{}:2".format(mappingtypename)]) # block the repeat keys
80-
81-
if len(mappingParts) == 2 and len(valueParts) == 2:
82-
cmd.extend(["--map", "yield", mapping, value])
83-
elif len(mappingParts) == 2 and len(valueParts) == 3:
84-
cmd.extend(["--map", "yield", "{}:1".format(mapping), value])
85-
cmd.extend(["--map", "yield", "{}:0".format(mapping), "{}:0".format(valuetypename)])
86-
elif len(mappingParts) == 3 and len(valueParts) == 2:
87-
cmd.extend(["--map", "yield", mapping, "{}:1".format(value)])
88-
cmd.extend(["--map", "yield", "{}:0".format(mappingtypename), "{}:0".format(value)])
118+
if type(mapping) is not tuple:
119+
# simple keys
120+
mappingParts = mapping.split(':')
121+
mappingtypename = mappingParts[0] + ":" + mappingParts[1]
122+
valueParts = value.split(':')
123+
valuetypename = valueParts[0] + ":" + valueParts[1]
124+
cmd.extend(["--block", "{}:2".format(mappingtypename)]) # block the repeat keys
125+
126+
if len(mappingParts) == 2 and len(valueParts) == 2:
127+
cmd.extend(["--map", "yield", mapping, value])
128+
elif len(mappingParts) == 2 and len(valueParts) == 3:
129+
cmd.extend(["--map", "yield", "{}:1".format(mapping), value])
130+
cmd.extend(["--map", "yield", "{}:0".format(mapping), "{}:0".format(valuetypename)])
131+
elif len(mappingParts) == 3 and len(valueParts) == 2:
132+
cmd.extend(["--map", "yield", mapping, "{}:1".format(value)])
133+
cmd.extend(["--map", "yield", "{}:0".format(mappingtypename), "{}:0".format(value)])
89134

90135
# output device
91136
cmd.extend(["--output", "name={}".format(target_device["name"]), "device-id=ba10:ce8a"])

package/batocera/controllers/pads/keyboardtopads/keyboardToPadsLauncher.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ else
9191
else
9292
# no config file found, do 1 to 1 mapping to enable keyboard
9393
# map the same, but this one will have ID_INPUT_KEYBOARD set to 1
94+
echo "no config file found" >&2
9495
if test -t 1 # check output is a tty
9596
then
9697
evsieve --input "${1}" --output name="Default virtual keyboard"

0 commit comments

Comments
 (0)