1111import re
1212from 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+
1432class KeyboardController :
1533
1634 def generateRules (self , configFile ) -> str :
@@ -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" ])
0 commit comments