Browse Source

Refactor XAP keycode logic

zvecr 3 years ago
parent
commit
9e1b8a710c

+ 7 - 7
data/constants/keycodes_0.0.1.json → data/constants/keycodes_0.0.1.hjson

@@ -817,7 +817,7 @@
             "key": "KC_LOCKING_NUM_LOCK",
             "label": "Num Lock",
             "aliases": [
-                "KC_LSCR"
+                "KC_LNUM"
             ]
         },
         "0x0084": {
@@ -825,7 +825,7 @@
             "key": "KC_LOCKING_SCROLL_LOCK",
             "label": "Scroll Lock",
             "aliases": [
-                "KC_LCAP"
+                "KC_LSCR"
             ]
         },
         "0x0085": {
@@ -1246,23 +1246,23 @@
             "key": "KC_WWW_FAVORITES",
             "label": "Browser Favorites",
             "aliases": [
-                "KC_WREF"
+                "KC_WFAV"
             ]
         },
         "0x00bb": {
             "group": "media",
             "key": "KC_MEDIA_FAST_FORWARD",
-            "label": "Browser Favorites",
+            "label": "Next Track",
             "aliases": [
-                "KC_WREF"
+                "KC_MFFD"
             ]
         },
         "0x00bc": {
             "group": "media",
             "key": "KC_MEDIA_REWIND",
-            "label": "Browser Favorites",
+            "label": "Previous Track",
             "aliases": [
-                "KC_WFAV"
+                "KC_MRWD"
             ]
         },
         "0x00bd": {

+ 0 - 6
data/schemas/xap.jsonschema

@@ -135,12 +135,6 @@
         "define": {
             "$ref": "qmk.definitions.v1#/define"
         },
-        "uses": {
-            "type": "object",
-            "additionalProperties": {
-                "$ref": "qmk.definitions.v1#/bcd_version"
-            }
-        },
         "documentation": {
             "type": "object",
             "properties": {

+ 0 - 4
data/xap/xap_0.1.0.hjson

@@ -1,10 +1,6 @@
 {
     version: 0.1.0
 
-    uses: {
-        keycodes: 0.0.1
-    }
-
     documentation: {
         order: [
             broadcast_messages

+ 0 - 6
data/xap/xap_0.3.0.hjson

@@ -1,12 +1,6 @@
 {
     version: 0.3.0
 
-    uses: {
-        rgblight: 0.0.1
-        rgb_matrix: 0.0.1
-        led_matrix: 0.0.1
-    }
-
     routes: {
 
         0x06: {

+ 13 - 4
lib/python/qmk/cli/xap/xap.py

@@ -4,13 +4,12 @@ import cmd
 
 from milc import cli
 
+from qmk.keycodes import load_spec
+from qmk.decorators import lru_cache
 from qmk.keyboard import render_layout
-from qmk.xap.common import get_xap_keycodes
 
 from xap_client import XAPClient, XAPEventType, XAPSecureStatus, XAPConfigRgblight, XAPConfigBacklight, XAPConfigRgbMatrix, XAPRoutes
 
-KEYCODE_MAP = get_xap_keycodes('latest')
-
 
 def print_dotted_output(kb_info_json, prefix=''):
     """Print the info.json in a plain text format with dot-joined keys.
@@ -38,6 +37,16 @@ def print_dotted_output(kb_info_json, prefix=''):
             cli.echo('    {fg_blue}%s{fg_reset}: %s', new_prefix, kb_info_json[key])
 
 
+@lru_cache(timeout=5)
+def _load_keycodes(keycode_version):
+    """Gets keycode data for the required version of the XAP definitions.
+    """
+    spec = load_spec(keycode_version)
+
+    # Transform into something more usable - { raw_value : first alias || keycode }
+    return {int(k, 16): v.get('aliases', [v.get('key')])[0] for k, v in spec['keycodes'].items()}
+
+
 def _list_devices():
     """Dump out available devices
     """
@@ -62,7 +71,7 @@ class XAPShell(cmd.Cmd):
         cmd.Cmd.__init__(self)
         self.device = device
         # cache keycodes for this device
-        self.keycodes = get_xap_keycodes(device.version()['xap'])
+        self.keycodes = _load_keycodes(device.version().get('keycodes', 'latest'))
 
     def do_about(self, arg):
         """Prints out the version info of QMK

+ 54 - 0
lib/python/qmk/keycodes.py

@@ -0,0 +1,54 @@
+from pathlib import Path
+
+from qmk.json_schema import deep_update, json_load
+
+CONSTANTS_PATH = Path('data/constants/')
+
+
+def _validate(spec):
+    # no duplicate keycodes
+    keycodes = []
+    for value in spec['keycodes'].values():
+        keycodes.append(value['key'])
+        keycodes.extend(value.get('aliases', []))
+    duplicates = set([x for x in keycodes if keycodes.count(x) > 1])
+    if duplicates:
+        raise ValueError(f'Keycode spec contains duplicate keycodes! ({",".join(duplicates)})')
+
+
+def load_spec(version):
+    """Build keycode data from the requested spec file
+    """
+    if version == 'latest':
+        version = list_versions()[0]
+
+    file = CONSTANTS_PATH / f'keycodes_{version}.hjson'
+    if not file.exists():
+        raise ValueError(f'Requested keycode spec ({version}) is invalid!')
+
+    # Load base
+    spec = json_load(file)
+
+    # Merge in fragments
+    fragments = CONSTANTS_PATH.glob(f'keycodes_{version}_*.hjson')
+    for file in fragments:
+        deep_update(spec, json_load(file))
+
+    # Sort?
+    spec['keycodes'] = dict(sorted(spec['keycodes'].items()))
+
+    # Validate?
+    _validate(spec)
+
+    return spec
+
+
+def list_versions():
+    """Return available versions - sorted newest first
+    """
+    ret = []
+    for file in CONSTANTS_PATH.glob('keycodes_[0-9].[0-9].[0-9].hjson'):
+        ret.append(file.stem.split('_')[1])
+
+    ret.sort(reverse=True)
+    return ret

+ 1 - 15
lib/python/qmk/xap/common.py

@@ -9,7 +9,7 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape
 
 from qmk.casing import to_snake
 from qmk.constants import QMK_FIRMWARE
-from qmk.json_schema import json_load, validate
+from qmk.json_schema import validate
 from qmk.decorators import lru_cache
 from qmk.keymap import locate_keymap
 from qmk.path import keyboard
@@ -149,20 +149,6 @@ def merge_xap_defs(kb, km):
     return defs
 
 
-@lru_cache(timeout=5)
-def get_xap_keycodes(xap_version):
-    """Gets keycode data for the required version of the XAP definitions.
-    """
-    defs = get_xap_defs(xap_version)
-
-    # Load DD keycodes for the dependency
-    keycode_version = defs['uses']['keycodes']
-    spec = json_load(Path(f'data/constants/keycodes_{keycode_version}.json'))
-
-    # Transform into something more usable - { raw_value : first alias || keycode }
-    return {int(k, 16): v.get('aliases', [v.get('key')])[0] for k, v in spec['keycodes'].items()}
-
-
 def route_conditions(route_stack):
     """Handles building the C preprocessor conditional based on the current route.
     """