add via stack generator
parent
2afa18d4cd
commit
898a157f6d
|
|
@ -1,10 +1,12 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# 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, \
|
from PyQt5.QtWidgets import QWidget, QComboBox, QToolButton, QHBoxLayout, QVBoxLayout, QMainWindow, QAction, qApp, \
|
||||||
QFileDialog, QDialog, QTabWidget, QActionGroup
|
QFileDialog, QDialog, QTabWidget, QActionGroup
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
from urllib.request import urlopen
|
||||||
|
|
||||||
from firmware_flasher import FirmwareFlasher
|
from firmware_flasher import FirmwareFlasher
|
||||||
from keymap_editor import KeymapEditor
|
from keymap_editor import KeymapEditor
|
||||||
|
|
@ -28,6 +30,8 @@ class MainWindow(QMainWindow):
|
||||||
|
|
||||||
self.current_device = None
|
self.current_device = None
|
||||||
self.devices = []
|
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_json = None
|
||||||
self.sideload_vid = self.sideload_pid = -1
|
self.sideload_vid = self.sideload_pid = -1
|
||||||
|
|
||||||
|
|
@ -64,6 +68,16 @@ class MainWindow(QMainWindow):
|
||||||
|
|
||||||
self.init_menu()
|
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
|
# make sure initial state is valid
|
||||||
self.on_click_refresh()
|
self.on_click_refresh()
|
||||||
|
|
||||||
|
|
@ -79,6 +93,9 @@ class MainWindow(QMainWindow):
|
||||||
sideload_json_act = QAction(tr("MenuFile", "Sideload VIA JSON..."), self)
|
sideload_json_act = QAction(tr("MenuFile", "Sideload VIA JSON..."), self)
|
||||||
sideload_json_act.triggered.connect(self.on_sideload_json)
|
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 = QAction(tr("MenuFile", "Exit"), self)
|
||||||
exit_act.setShortcut("Ctrl+Q")
|
exit_act.setShortcut("Ctrl+Q")
|
||||||
exit_act.triggered.connect(qApp.exit)
|
exit_act.triggered.connect(qApp.exit)
|
||||||
|
|
@ -88,6 +105,7 @@ class MainWindow(QMainWindow):
|
||||||
file_menu.addAction(layout_save_act)
|
file_menu.addAction(layout_save_act)
|
||||||
file_menu.addSeparator()
|
file_menu.addSeparator()
|
||||||
file_menu.addAction(sideload_json_act)
|
file_menu.addAction(sideload_json_act)
|
||||||
|
file_menu.addAction(download_via_stack_act)
|
||||||
file_menu.addSeparator()
|
file_menu.addSeparator()
|
||||||
file_menu.addAction(exit_act)
|
file_menu.addAction(exit_act)
|
||||||
|
|
||||||
|
|
@ -156,7 +174,7 @@ class MainWindow(QMainWindow):
|
||||||
outf.write(self.keymap_editor.save_layout())
|
outf.write(self.keymap_editor.save_layout())
|
||||||
|
|
||||||
def on_click_refresh(self):
|
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()
|
self.combobox_devices.clear()
|
||||||
|
|
||||||
for dev in self.devices:
|
for dev in self.devices:
|
||||||
|
|
@ -171,7 +189,12 @@ class MainWindow(QMainWindow):
|
||||||
self.current_device = self.devices[idx]
|
self.current_device = self.devices[idx]
|
||||||
|
|
||||||
if self.current_device is not None:
|
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()
|
self.rebuild()
|
||||||
|
|
||||||
|
|
@ -199,6 +222,14 @@ class MainWindow(QMainWindow):
|
||||||
w.setLayout(container)
|
w.setLayout(container)
|
||||||
self.tabs.addTab(w, tr("MainWindow", lbl))
|
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):
|
def on_sideload_json(self):
|
||||||
dialog = QFileDialog()
|
dialog = QFileDialog()
|
||||||
dialog.setDefaultSuffix("json")
|
dialog.setDefaultSuffix("json")
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ def is_rawhid(dev):
|
||||||
return dev["interface_number"] == 1
|
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
|
from vial_device import VialBootloader, VialKeyboard
|
||||||
|
|
||||||
filtered = []
|
filtered = []
|
||||||
|
|
@ -63,6 +63,8 @@ def find_vial_devices(sideload_vid=None, sideload_pid=None):
|
||||||
filtered.append(VialKeyboard(dev))
|
filtered.append(VialKeyboard(dev))
|
||||||
elif VIBL_SERIAL_NUMBER_MAGIC in dev["serial_number"]:
|
elif VIBL_SERIAL_NUMBER_MAGIC in dev["serial_number"]:
|
||||||
filtered.append(VialBootloader(dev))
|
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
|
return filtered
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@ class VialDevice:
|
||||||
|
|
||||||
class VialKeyboard(VialDevice):
|
class VialKeyboard(VialDevice):
|
||||||
|
|
||||||
def __init__(self, dev, sideload=False):
|
def __init__(self, dev, sideload=False, via_stack=False):
|
||||||
super().__init__(dev)
|
super().__init__(dev)
|
||||||
|
self.via_id = str(dev["vendor_id"] * 65536 + dev["product_id"])
|
||||||
self.sideload = sideload
|
self.sideload = sideload
|
||||||
|
self.via_stack = via_stack
|
||||||
self.keyboard = None
|
self.keyboard = None
|
||||||
|
|
||||||
def open(self, override_json=None):
|
def open(self, override_json=None):
|
||||||
|
|
@ -43,6 +45,8 @@ class VialKeyboard(VialDevice):
|
||||||
s = "{} {}".format(self.desc["manufacturer_string"], self.desc["product_string"])
|
s = "{} {}".format(self.desc["manufacturer_string"], self.desc["product_string"])
|
||||||
if self.sideload:
|
if self.sideload:
|
||||||
s += " [sideload]"
|
s += " [sideload]"
|
||||||
|
elif self.via_stack:
|
||||||
|
s += " [VIA]"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def get_uid(self):
|
def get_uid(self):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue