Hardware Communication#
This page covers the details of communication protocols Plover uses to capture keyboard or steno writer input.
Keyboard Capture & Output#
Three implementations of keyboard capture and output are currently available:
The Windows implementation installs low-level event hooks to listen for key presses, and the Win32 API’s
SendInput
to generate keystrokes.The macOS implementation uses Quartz’s Event Services API: event taps to listen for key presses, and keyboard events to generate keystrokes.
Linux and BSD both use an implementation based on Xlib’s
xinput
to listen for key presses, andxtest.fake_input
to generate keystrokes, both of which require an X display server.Wayland is not currently supported.
Before implementing new keyboard capture and output mechanisms for a new platform, make sure to set up the platform layer for your platform.
Capture#
New keyboard capture methods can be implemented as a subclass of
Capture
; your implementation
should translate platform-specific events into calls to
key_down
and key_up
.
class MyKeyboardCapture(Capture):
def start(self):
self._thread = threading.Thread(target=self._run)
self._thread.start()
def _run(self):
while True:
key, pressed = ... # wait for key event
if pressed:
self.key_down(key)
else:
self.key_up(key)
Plover’s engine handles translating these calls into steno strokes, as well as handling keymaps and arpeggiation.
Output#
New keyboard emulation methods can be implemented as a subclass of
Output
. It must implement all of the methods
specified, by translating them to platform-specific input calls.
class MyKeyboardEmulation(Output):
def send_backspaces(self, num):
...
def send_string(self, s):
...
def send_key_combination(self, combo):
...
Serial Protocols#
Plover supports communicating with hobbyist, student, and professional steno writers through a serial interface. The most common protocols are Gemini PR for hobbyist writers and Stentura for Stenograph writers, but custom protocols may be implemented.
The SerialStenotypeBase
class
handles all of the connection establishment and configuration; when
implementing a new serial interface, you only need to define your key layout
and implement a way to parse each packet.
class MySerialMachine(SerialStenotypeBase):
KEYS_LAYOUT = """
...
"""
def run(self):
...
USB-based Protocols#
Todo
Complete this section.
Other Protocols#
Todo
Complete this section.