add unicode sending to the protocol
This commit is contained in:
parent
f11d7586a9
commit
1326e78b59
2 changed files with 45 additions and 7 deletions
|
@ -10,6 +10,7 @@ The order of the buttons (from left to right) is the same as in `KEYS_LAYOUT`.
|
|||
Most buttons have the same names as in GeminiPR, except for the extra buttons
|
||||
which are called X1-X26.
|
||||
'''
|
||||
from plover.engine import StenoEngine
|
||||
from plover.machine.base import ThreadedStenotypeBase
|
||||
from plover import log
|
||||
|
||||
|
@ -18,6 +19,7 @@ import hid
|
|||
import platform
|
||||
import threading
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
# This is a hack to not open the hid device in exclusive mode on
|
||||
# darwin, if the version of hidapi installed is current enough
|
||||
|
@ -27,7 +29,7 @@ if platform.system() == "Darwin":
|
|||
hid.hidapi.hid_darwin_set_open_exclusive.argtypes = (ctypes.c_int, )
|
||||
hid.hidapi.hid_darwin_set_open_exclusive.restype = None
|
||||
hid.hidapi.hid_darwin_set_open_exclusive(0)
|
||||
except AttributeError as e:
|
||||
except AttributeError:
|
||||
log.error("hidapi < 0.12 in use, plover-hid will not work correctly")
|
||||
|
||||
USAGE_PAGE: int = 0xFF60
|
||||
|
@ -40,12 +42,35 @@ N_LEVERS: int = 80
|
|||
SIMPLE_REPORT_TYPE: int = 0x62
|
||||
SIMPLE_REPORT_LEN: int = 32
|
||||
|
||||
|
||||
class InvalidReport(Exception):
|
||||
pass
|
||||
|
||||
|
||||
STENO_KEY_CHART = tuple(f"X{i}" for i in range(1, N_LEVERS + 1))
|
||||
|
||||
print('steno key chart', len(STENO_KEY_CHART))
|
||||
|
||||
|
||||
class UnicodeSender:
|
||||
def __init__(self, engine: StenoEngine):
|
||||
self._engine = engine
|
||||
|
||||
def start(self):
|
||||
global unicode_sender
|
||||
unicode_sender = self
|
||||
|
||||
def stop(self):
|
||||
global unicode_sender
|
||||
unicode_sender = None
|
||||
|
||||
def send_string(self, string: str):
|
||||
self._engine.keyboard_emulation.send_string(string)
|
||||
|
||||
|
||||
unicode_sender: Optional[UnicodeSender] = None
|
||||
|
||||
|
||||
class HidMachine(ThreadedStenotypeBase):
|
||||
KEYS_LAYOUT: str = '''
|
||||
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
|
||||
|
@ -57,17 +82,26 @@ class HidMachine(ThreadedStenotypeBase):
|
|||
X61 X62 X63 X64 X65 X66 X67 X68 X69 X70
|
||||
X71 X72 X73 X74 X75 X76 X77 X78 X79 X80
|
||||
'''
|
||||
|
||||
def __init__(self, params):
|
||||
super().__init__()
|
||||
self._params = params
|
||||
self._hid = None
|
||||
|
||||
def _parse(self, report):
|
||||
def _parse(self, report: bytes) -> Optional[BitString]:
|
||||
if len(report) != SIMPLE_REPORT_LEN:
|
||||
raise InvalidReport()
|
||||
if report[:3] != b"STN":
|
||||
if report[:3] == b"STN":
|
||||
return BitString(bytes=report[3:13])
|
||||
elif report[:3] == b"UNI":
|
||||
try:
|
||||
s = report[3:].decode("UTF-8").strip('\0')
|
||||
if unicode_sender is not None:
|
||||
unicode_sender.send_string(s)
|
||||
except UnicodeDecodeError:
|
||||
raise InvalidReport()
|
||||
else:
|
||||
raise InvalidReport()
|
||||
return BitString(bytes=report[3:13])
|
||||
|
||||
def _ping_thread(self):
|
||||
while not self.finished.wait(0):
|
||||
|
@ -89,6 +123,8 @@ class HidMachine(ThreadedStenotypeBase):
|
|||
continue
|
||||
try:
|
||||
report = self._parse(report)
|
||||
if report is None:
|
||||
continue
|
||||
except InvalidReport:
|
||||
continue
|
||||
keystate |= report
|
||||
|
@ -109,14 +145,15 @@ class HidMachine(ThreadedStenotypeBase):
|
|||
devices = [
|
||||
device["path"]
|
||||
for device in hid.enumerate()
|
||||
if device["usage_page"] == USAGE_PAGE and device["usage"] == USAGE
|
||||
if device["usage_page"] == USAGE_PAGE
|
||||
and device["usage"] == USAGE
|
||||
]
|
||||
if not devices:
|
||||
self._error()
|
||||
return
|
||||
# FIXME: if multiple compatible devices are found we should either
|
||||
# let the end user configure which one they want, or support reading
|
||||
# from all connected plover hid devices at the same time.
|
||||
# let the end user configure which one they want, or support
|
||||
# reading from all connected plover hid devices at the same time.
|
||||
self._hid = hid.Device(path=devices[0])
|
||||
except hid.HIDException:
|
||||
self._error()
|
||||
|
|
|
@ -16,3 +16,4 @@ py_modules =
|
|||
[options.entry_points]
|
||||
plover.machine =
|
||||
Plover HID = plover_machine_hid:HidMachine
|
||||
plover.extension = plover_machine_hid:UnicodeSender
|
Loading…
Reference in a new issue