# 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`; your implementation should translate platform-specific events into calls to {meth}`key_down` and {meth}`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`. 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` 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. ```