1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
# 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`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) to generate keystrokes.
- The **macOS** implementation uses Quartz's Event Services API: [event taps](https://developer.apple.com/documentation/coregraphics/1454426-cgeventtapcreate)
to listen for key presses, and [keyboard events](https://developer.apple.com/documentation/coregraphics/1456564-cgeventcreatekeyboardevent)
to generate keystrokes.
- For **Linux** and **BSD**, there are two implementations. If the display server is `x11`, an implementation based on Xlib's `xinput` is used to
listen for key presses, and `xtest.fake_input` to generate keystrokes. For all other display servers, for example `wayland`, an implementation based
on `evdev` is used to listen for key presses, and `uinput` to generate keystrokes. The `uinput` implementation needs to know the keyboard layout of the
system, which can be configured in the Plover `Output` configuration tap.
Before implementing new keyboard capture and output mechanisms for a new
platform, make sure to set up the [platform layer](platform_layer) for your
platform.
### Capture
New keyboard capture methods can be implemented as a subclass of
{class}`Capture<plover.machine.keyboard_capture.Capture>`; your implementation
should translate platform-specific events into calls to
{meth}`key_down<plover.machine.keyboard_capture.Capture.key_down>` and {meth}`key_up<plover.machine.keyboard_capture.Capture.key_up>`.
```python
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
{class}`Output<plover.output.Output>`. It _must_ implement all of the methods
specified, by translating them to platform-specific input calls.
```python
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 {class}`SerialStenotypeBase<plover.machine.base.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.
```python
class MySerialMachine(SerialStenotypeBase):
KEYS_LAYOUT = """
...
"""
def run(self):
...
```
## USB-based Protocols
```{todo}
Complete this section.
```
## Other Protocols
```{todo}
Complete this section.
```
|