support for loading a dummy JSON definition
parent
89cf01060a
commit
e4c0f7acdf
|
|
@ -51,7 +51,7 @@ class Keyboard:
|
||||||
self.layout = dict()
|
self.layout = dict()
|
||||||
self.encoder_layout = dict()
|
self.encoder_layout = dict()
|
||||||
self.rows = self.cols = self.layers = 0
|
self.rows = self.cols = self.layers = 0
|
||||||
self.layouts = None
|
self.layout_labels = None
|
||||||
self.layout_options = -1
|
self.layout_options = -1
|
||||||
self.keys = []
|
self.keys = []
|
||||||
self.encoders = []
|
self.encoders = []
|
||||||
|
|
@ -112,7 +112,7 @@ class Keyboard:
|
||||||
vial = payload["vial"]
|
vial = payload["vial"]
|
||||||
self.vibl = vial.get("vibl", False)
|
self.vibl = vial.get("vibl", False)
|
||||||
|
|
||||||
self.layouts = payload.get("layouts")
|
self.layout_labels = payload["layouts"].get("labels")
|
||||||
|
|
||||||
self.rows = payload["matrix"]["rows"]
|
self.rows = payload["matrix"]["rows"]
|
||||||
self.cols = payload["matrix"]["cols"]
|
self.cols = payload["matrix"]["cols"]
|
||||||
|
|
@ -175,7 +175,7 @@ class Keyboard:
|
||||||
self.encoder_layout[(layer, idx, 0)] = struct.unpack(">H", data[0:2])[0]
|
self.encoder_layout[(layer, idx, 0)] = struct.unpack(">H", data[0:2])[0]
|
||||||
self.encoder_layout[(layer, idx, 1)] = struct.unpack(">H", data[2:4])[0]
|
self.encoder_layout[(layer, idx, 1)] = struct.unpack(">H", data[2:4])[0]
|
||||||
|
|
||||||
if self.layouts:
|
if self.layout_labels:
|
||||||
data = self.usb_send(self.dev, struct.pack("BB", CMD_VIA_GET_KEYBOARD_VALUE, VIA_LAYOUT_OPTIONS),
|
data = self.usb_send(self.dev, struct.pack("BB", CMD_VIA_GET_KEYBOARD_VALUE, VIA_LAYOUT_OPTIONS),
|
||||||
retries=20)
|
retries=20)
|
||||||
self.layout_options = struct.unpack(">I", data[2:6])[0]
|
self.layout_options = struct.unpack(">I", data[2:6])[0]
|
||||||
|
|
@ -356,3 +356,71 @@ class Keyboard:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.usb_send(self.dev, struct.pack("BB", CMD_VIA_VIAL_PREFIX, CMD_VIAL_LOCK), retries=20)
|
self.usb_send(self.dev, struct.pack("BB", CMD_VIA_VIAL_PREFIX, CMD_VIAL_LOCK), retries=20)
|
||||||
|
|
||||||
|
|
||||||
|
class DummyKeyboard(Keyboard):
|
||||||
|
|
||||||
|
def reload_layers(self):
|
||||||
|
self.layers = 4
|
||||||
|
|
||||||
|
def reload_keymap(self):
|
||||||
|
for layer in range(self.layers):
|
||||||
|
for row, col in self.rowcol.keys():
|
||||||
|
self.layout[(layer, row, col)] = 0
|
||||||
|
|
||||||
|
for layer in range(self.layers):
|
||||||
|
for idx in self.encoderpos:
|
||||||
|
self.encoder_layout[(layer, idx, 0)] = 0
|
||||||
|
self.encoder_layout[(layer, idx, 1)] = 0
|
||||||
|
|
||||||
|
if self.layout_labels:
|
||||||
|
self.layout_options = 0
|
||||||
|
|
||||||
|
def reload_macros(self):
|
||||||
|
self.macro_count = 16
|
||||||
|
self.macro_memory = 900
|
||||||
|
|
||||||
|
self.macro = b"\x00" * self.macro_count
|
||||||
|
|
||||||
|
def set_key(self, layer, row, col, code):
|
||||||
|
if code < 0:
|
||||||
|
return
|
||||||
|
self.layout[(layer, row, col)] = code
|
||||||
|
|
||||||
|
def set_encoder(self, layer, index, direction, code):
|
||||||
|
if code < 0:
|
||||||
|
return
|
||||||
|
self.encoder_layout[(layer, index, direction)] = code
|
||||||
|
|
||||||
|
def set_layout_options(self, options):
|
||||||
|
if self.layout_options != -1 and self.layout_options != options:
|
||||||
|
self.layout_options = options
|
||||||
|
|
||||||
|
def set_macro(self, data):
|
||||||
|
if len(data) > self.macro_memory:
|
||||||
|
raise RuntimeError("the macro is too big: got {} max {}".format(len(data), self.macro_memory))
|
||||||
|
self.macro = data
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_uid(self):
|
||||||
|
return b"\x00" * 8
|
||||||
|
|
||||||
|
def get_unlock_status(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def get_unlock_in_progress(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def get_unlock_keys(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def unlock_start(self):
|
||||||
|
return
|
||||||
|
|
||||||
|
def unlock_poll(self):
|
||||||
|
return b""
|
||||||
|
|
||||||
|
def lock(self):
|
||||||
|
return
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ class LayoutEditor(BasicEditor):
|
||||||
choice.delete()
|
choice.delete()
|
||||||
self.choices = []
|
self.choices = []
|
||||||
|
|
||||||
for item in device.keyboard.layouts["labels"]:
|
for item in device.keyboard.layout_labels:
|
||||||
if isinstance(item, str):
|
if isinstance(item, str):
|
||||||
choice = BooleanChoice(self.on_changed, self.container, item)
|
choice = BooleanChoice(self.on_changed, self.container, item)
|
||||||
else:
|
else:
|
||||||
|
|
@ -124,7 +124,7 @@ class LayoutEditor(BasicEditor):
|
||||||
self.blockSignals(False)
|
self.blockSignals(False)
|
||||||
|
|
||||||
def valid(self):
|
def valid(self):
|
||||||
return isinstance(self.device, VialKeyboard) and "labels" in self.device.keyboard.layouts
|
return isinstance(self.device, VialKeyboard) and self.device.keyboard.layout_labels
|
||||||
|
|
||||||
def pack(self):
|
def pack(self):
|
||||||
if not self.choices:
|
if not self.choices:
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,9 @@ class MainWindow(QMainWindow):
|
||||||
download_via_stack_act = QAction(tr("MenuFile", "Download VIA definitions"), self)
|
download_via_stack_act = QAction(tr("MenuFile", "Download VIA definitions"), self)
|
||||||
download_via_stack_act.triggered.connect(self.load_via_stack_json)
|
download_via_stack_act.triggered.connect(self.load_via_stack_json)
|
||||||
|
|
||||||
|
load_dummy_act = QAction(tr("MenuFile", "Load dummy JSON..."), self)
|
||||||
|
load_dummy_act.triggered.connect(self.on_load_dummy)
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -106,6 +109,7 @@ class MainWindow(QMainWindow):
|
||||||
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.addAction(download_via_stack_act)
|
||||||
|
file_menu.addAction(load_dummy_act)
|
||||||
file_menu.addSeparator()
|
file_menu.addSeparator()
|
||||||
file_menu.addAction(exit_act)
|
file_menu.addAction(exit_act)
|
||||||
|
|
||||||
|
|
@ -243,6 +247,18 @@ class MainWindow(QMainWindow):
|
||||||
self.sideload_pid = int(self.sideload_json["productId"], 16)
|
self.sideload_pid = int(self.sideload_json["productId"], 16)
|
||||||
self.on_click_refresh()
|
self.on_click_refresh()
|
||||||
|
|
||||||
|
def on_load_dummy(self):
|
||||||
|
dialog = QFileDialog()
|
||||||
|
dialog.setDefaultSuffix("json")
|
||||||
|
dialog.setAcceptMode(QFileDialog.AcceptOpen)
|
||||||
|
dialog.setNameFilters(["VIA layout JSON (*.json)"])
|
||||||
|
if dialog.exec_() == QDialog.Accepted:
|
||||||
|
with open(dialog.selectedFiles()[0], "rb") as inf:
|
||||||
|
data = inf.read()
|
||||||
|
self.sideload_json = json.loads(data)
|
||||||
|
self.sideload_vid = self.sideload_pid = 0
|
||||||
|
self.on_click_refresh()
|
||||||
|
|
||||||
def lock_ui(self):
|
def lock_ui(self):
|
||||||
self.tabs.setEnabled(False)
|
self.tabs.setEnabled(False)
|
||||||
self.combobox_devices.setEnabled(False)
|
self.combobox_devices.setEnabled(False)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ def is_rawhid(dev):
|
||||||
|
|
||||||
|
|
||||||
def find_vial_devices(via_stack_json, 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, VialDummyKeyboard
|
||||||
|
|
||||||
filtered = []
|
filtered = []
|
||||||
for dev in hid.enumerate():
|
for dev in hid.enumerate():
|
||||||
|
|
@ -66,6 +66,9 @@ def find_vial_devices(via_stack_json, sideload_vid=None, sideload_pid=None):
|
||||||
elif str(dev["vendor_id"] * 65536 + dev["product_id"]) in via_stack_json["definitions"] and is_rawhid(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))
|
filtered.append(VialKeyboard(dev, via_stack=True))
|
||||||
|
|
||||||
|
if sideload_vid == sideload_pid == 0:
|
||||||
|
filtered.append(VialDummyKeyboard())
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
from hidproxy import hid
|
from hidproxy import hid
|
||||||
from keyboard_comm import Keyboard
|
from keyboard_comm import Keyboard, DummyKeyboard
|
||||||
from util import MSG_LEN, pad_for_vibl
|
from util import MSG_LEN, pad_for_vibl
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -74,3 +74,22 @@ class VialBootloader(VialDevice):
|
||||||
data = self.recv(8, timeout_ms=500)
|
data = self.recv(8, timeout_ms=500)
|
||||||
super().close()
|
super().close()
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class VialDummyKeyboard(VialKeyboard):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.sideload = True
|
||||||
|
|
||||||
|
def open(self, override_json=None):
|
||||||
|
self.keyboard = DummyKeyboard(None, usb_send=self.raise_usb_send)
|
||||||
|
self.keyboard.reload(override_json)
|
||||||
|
|
||||||
|
def title(self):
|
||||||
|
return "[Dummy Keyboard]"
|
||||||
|
|
||||||
|
def raise_usb_send(self, *args, **kwargs):
|
||||||
|
raise RuntimeError("usb_send - should not be called!")
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
pass
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue