Add native Linux controls and tray menu for BTD 700

This commit is contained in:
Justin
2026-09-05 20:43:35 +02:00
commit 3579667c6e
25 changed files with 2047 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
"""One thread owns the USB handle; the GTK main loop never waits for USB."""
import queue
import threading
from gi.repository import GLib
from .controller import Controller
from .transport import DeviceError, Hidraw, discover
class Worker(threading.Thread):
def __init__(self, callback, *, device_path=None, demo=False):
super().__init__(name='btd700-usb', daemon=True)
self.callback = callback
self.device_path = device_path
self.demo = demo
self.commands = queue.Queue()
self.stopping = threading.Event()
self.controller = None
self.transport = None
def submit(self, method, args, kwargs):
self.commands.put((method, args, kwargs))
def stop(self):
self.stopping.set()
self.commands.put(None)
def run(self):
try:
while not self.stopping.is_set():
try:
action = self.commands.get(timeout=2)
except queue.Empty:
action = None
if self.stopping.is_set():
break
error = ''
try:
if self.controller is None:
if self.demo:
from .demo import DemoTransport
self.transport = DemoTransport()
else:
devices = discover()
if self.device_path:
devices = [d for d in devices if d.path == self.device_path]
if not devices:
raise DeviceError('Kein BTD 700 gefunden. Bitte den Dongle einstecken.')
if len(devices) > 1:
raise DeviceError('Mehrere BTD 700 gefunden. Mit --device /dev/hidrawN auswählen.')
self.transport = Hidraw(devices[0])
self.controller = Controller(self.transport)
if action:
method, args, kwargs = action
try:
getattr(self.controller, method)(*args, **kwargs)
except (ValueError, DeviceError, TimeoutError) as exc:
error = str(exc)
status = self.controller.snapshot()
GLib.idle_add(self.callback, status, error, bool(action))
except Exception as exc:
if self.transport:
self.transport.close()
self.transport = self.controller = None
GLib.idle_add(self.callback, None, error or str(exc), bool(action))
finally:
if self.transport:
self.transport.close()