From 898a157f6d4e5a6713e1a4e1deb51f60cb284b4a Mon Sep 17 00:00:00 2001 From: Lorenz Wellmer Date: Mon, 11 Jan 2021 07:51:24 +0100 Subject: [PATCH] add via stack generator --- src/main/python/main_window.py | 37 +++++++++++++++++++++++++++++++--- src/main/python/util.py | 4 +++- src/main/python/vial_device.py | 6 +++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/python/main_window.py b/src/main/python/main_window.py index fa673bf..78e39a9 100644 --- a/src/main/python/main_window.py +++ b/src/main/python/main_window.py @@ -1,10 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-or-later -from PyQt5.QtCore import Qt, QSettings +from PyQt5.QtCore import Qt, QSettings, QStandardPaths from PyQt5.QtWidgets import QWidget, QComboBox, QToolButton, QHBoxLayout, QVBoxLayout, QMainWindow, QAction, qApp, \ QFileDialog, QDialog, QTabWidget, QActionGroup import json +import os +from urllib.request import urlopen from firmware_flasher import FirmwareFlasher from keymap_editor import KeymapEditor @@ -28,6 +30,8 @@ class MainWindow(QMainWindow): self.current_device = None self.devices = [] + # create empty VIA definitions. Easier than setting it to none and handling a bunch of exceptions + self.via_stack_json = {"definitions": {}} self.sideload_json = None self.sideload_vid = self.sideload_pid = -1 @@ -64,6 +68,16 @@ class MainWindow(QMainWindow): self.init_menu() + # cache for via definition files + self.cache_path = QStandardPaths.writableLocation(QStandardPaths.CacheLocation) + if not os.path.exists(self.cache_path): + os.makedirs(self.cache_path) + # check if the via defitions already exist + if os.path.isfile(os.path.join(self.cache_path, "via_keyboards.json")): + with open(os.path.join(self.cache_path, "via_keyboards.json")) as vf: + self.via_stack_json = json.load(vf) + vf.close() + # make sure initial state is valid self.on_click_refresh() @@ -79,6 +93,9 @@ class MainWindow(QMainWindow): sideload_json_act = QAction(tr("MenuFile", "Sideload VIA JSON..."), self) sideload_json_act.triggered.connect(self.on_sideload_json) + download_via_stack_act = QAction(tr("MenuFile", "Download VIA definitions"), self) + download_via_stack_act.triggered.connect(self.load_via_stack_json) + exit_act = QAction(tr("MenuFile", "Exit"), self) exit_act.setShortcut("Ctrl+Q") exit_act.triggered.connect(qApp.exit) @@ -88,6 +105,7 @@ class MainWindow(QMainWindow): file_menu.addAction(layout_save_act) file_menu.addSeparator() file_menu.addAction(sideload_json_act) + file_menu.addAction(download_via_stack_act) file_menu.addSeparator() file_menu.addAction(exit_act) @@ -156,7 +174,7 @@ class MainWindow(QMainWindow): outf.write(self.keymap_editor.save_layout()) def on_click_refresh(self): - self.devices = find_vial_devices(self.sideload_vid, self.sideload_pid) + self.devices = find_vial_devices(self.via_stack_json, self.sideload_vid, self.sideload_pid) self.combobox_devices.clear() for dev in self.devices: @@ -171,7 +189,12 @@ class MainWindow(QMainWindow): self.current_device = self.devices[idx] if self.current_device is not None: - self.current_device.open(self.sideload_json if self.current_device.sideload else None) + if self.current_device.sideload: + self.current_device.open(self.sideload_json) + elif self.current_device.via_stack: + self.current_device.open(self.via_stack_json["definitions"][self.current_device.via_id]) + else: + self.current_device.open(None) self.rebuild() @@ -199,6 +222,14 @@ class MainWindow(QMainWindow): w.setLayout(container) self.tabs.addTab(w, tr("MainWindow", lbl)) + def load_via_stack_json(self): + data = urlopen("https://github.com/vial-kb/via-keymap-precompiled/raw/main/via_keyboard_stack.json") + self.via_stack_json = json.load(data) + # write to cache + with open(os.path.join(self.cache_path, "via_keyboards.json"), "w") as cf: + cf.write(json.dumps(self.via_stack_json, indent=2)) + cf.close() + def on_sideload_json(self): dialog = QFileDialog() dialog.setDefaultSuffix("json") diff --git a/src/main/python/util.py b/src/main/python/util.py index 807aed6..f22b40b 100644 --- a/src/main/python/util.py +++ b/src/main/python/util.py @@ -52,7 +52,7 @@ def is_rawhid(dev): return dev["interface_number"] == 1 -def find_vial_devices(sideload_vid=None, sideload_pid=None): +def find_vial_devices(via_stack_json, sideload_vid=None, sideload_pid=None): from vial_device import VialBootloader, VialKeyboard filtered = [] @@ -63,6 +63,8 @@ def find_vial_devices(sideload_vid=None, sideload_pid=None): filtered.append(VialKeyboard(dev)) elif VIBL_SERIAL_NUMBER_MAGIC in dev["serial_number"]: filtered.append(VialBootloader(dev)) + elif str(dev["vendor_id"] * 65536 + dev["product_id"]) in via_stack_json["definitions"] and is_rawhid(dev): + filtered.append(VialKeyboard(dev, via_stack=True)) return filtered diff --git a/src/main/python/vial_device.py b/src/main/python/vial_device.py index f424571..83cc1b9 100644 --- a/src/main/python/vial_device.py +++ b/src/main/python/vial_device.py @@ -29,9 +29,11 @@ class VialDevice: class VialKeyboard(VialDevice): - def __init__(self, dev, sideload=False): + def __init__(self, dev, sideload=False, via_stack=False): super().__init__(dev) + self.via_id = str(dev["vendor_id"] * 65536 + dev["product_id"]) self.sideload = sideload + self.via_stack = via_stack self.keyboard = None def open(self, override_json=None): @@ -43,6 +45,8 @@ class VialKeyboard(VialDevice): s = "{} {}".format(self.desc["manufacturer_string"], self.desc["product_string"]) if self.sideload: s += " [sideload]" + elif self.via_stack: + s += " [VIA]" return s def get_uid(self):