2026-04-01 17:29:38 -07:00
<table>
<tr>
2026-04-08 20:11:52 -07:00
<td><img src="screenshot1.jpg?1" height="400"/></td>
<td><img src="screenshot2.jpg?1" height="400"/></td>
2026-04-09 17:27:24 -07:00
<td><img src="screenshot3.jpg?1" height="400"/></td>
2026-04-01 17:29:38 -07:00
</tr>
</table>
2026-04-01 16:21:24 -07:00
# xteink-plugins
2026-04-09 17:21:05 -07:00
A plugin system for customizing and extending https://github.com/crosspoint-reader/crosspoint-reader firmware on your xteink device. Plugins are applied as source-level patches before the firmware is compiled and flashed.
2026-04-01 16:21:24 -07:00
## Plugins
2026-04-01 17:29:38 -07:00
### Dark Mode
2026-04-09 17:21:05 -07:00
Adds a Dark Mode option to the Plugins settings tab and the web interface Settings page. When enabled, the screen is inverted after each page render, producing white-on-black text across all reader formats (EPUB, TXT, and XTC).
2026-04-01 17:29:38 -07:00
2026-04-09 17:21:05 -07:00
State | Effect
------|--------
Disabled | Normal display (default)
Enabled | Screen inverted — white text on black background
---
2026-04-01 17:29:38 -07:00
2026-04-01 16:21:24 -07:00
### Smaller Fonts
2026-04-09 17:21:05 -07:00
Adds a Smaller Fonts option to the Plugins settings tab and the web interface Settings page. When enabled, your chosen reader font is transparently substituted with a smaller variant — no need to change your font preference.
2026-04-01 16:21:24 -07:00
2026-04-09 17:21:05 -07:00
Mode | Effect
-----|--------
Disabled | No change (default)
2026-07-16 15:39:10 -07:00
Enabled | Drops the current font size down by one step (e.g. Bookerly 16 → 14)
2026-04-01 16:21:24 -07:00
2026-07-16 15:39:10 -07:00
Supports Noto Serif, Noto Sans, and Bookerly.
2026-04-01 16:21:24 -07:00
2026-04-09 17:21:05 -07:00
---
### Lockscreen
Adds a customizable Lockscreen experience to your xteink device.
This plugin introduces a dedicated lockscreen activity that is shown when the device wakes or powers on.
Features:
- Custom lockscreen activity integrated into firmware
- Four-digit PIN configurable on plugin enable
- Displays on device wake or power-on
- Replaces default wake screen behavior
- Clean UI consistent with CrossPoint Reader
---
2026-04-23 15:02:44 -07:00
### Bookerly Font
Adds the Bookerly font to your xteink device, available as a reader font option alongside the built-in Noto Serif, Noto Sans, and OpenDyslexic fonts.
- Generates Bookerly at 12pt, 14pt, 16pt, and 18pt during install
- Selectable via Settings → Reader → Font
2026-07-16 15:39:10 -07:00
- Works with the Smaller Fonts plugin to drop one size step down (e.g. 16 → 14)
2026-04-23 15:02:44 -07:00
---
2026-04-08 19:46:35 -07:00
### Hardcover Sync
2026-04-09 17:21:05 -07:00
Automatically syncs your reading progress between your xteink device and https://hardcover.app.
2026-04-08 19:46:35 -07:00
- Extracts ISBN metadata from EPUB files to identify books
- Tracks reading progress (page numbers) while you read
- Automatically syncs progress for books with > 0% completion
2026-04-09 17:21:05 -07:00
- Marks books as "Read" when you reach 100%+ completion
2026-04-08 19:46:35 -07:00
- Requires a Hardcover API token configured in Settings
Books without ISBN metadata or at 0% completion are skipped. 100%+ completed books are automatically moved to your "Read" shelf on Hardcover.
2026-04-09 17:21:05 -07:00
Requirements:
2026-04-08 19:46:35 -07:00
- Active internet connection via WiFi
- Hardcover account and API token
- Books with embedded ISBN metadata
2026-04-23 15:02:44 -07:00
---
### GitHub Sync
Syncs `.epub` files from a private GitHub repository to your device on boot.
- Downloads new or updated books from your configured repo automatically on startup
- Skips files already on the device that haven't changed
2026-07-16 15:39:10 -07:00
- Configurable via Settings → Plugins → GitHub Sync (username, personal access token, repo, branch), after flashing
2026-04-23 15:02:44 -07:00
Requirements:
- Active internet connection via WiFi
- GitHub account with a repository containing your `.epub` files
- Personal access token with read-only Contents access to the repo
---
2026-04-01 16:21:24 -07:00
## Requirements
- Python 3.10+
2026-04-09 17:21:05 -07:00
- PlatformIO (pio on your PATH)
- git
2026-04-01 16:21:24 -07:00
- Your xteink device connected via USB
2026-04-01 17:55:36 -07:00
Install Python dependencies with:
2026-04-01 17:59:09 -07:00
pip3 install -r requirements.txt
2026-04-01 17:55:36 -07:00
2026-04-01 16:21:24 -07:00
## Usage
From the root of this repository, run:
2026-04-01 17:59:09 -07:00
python3 install.py
2026-04-01 16:21:24 -07:00
2026-04-09 17:21:05 -07:00
To auto-accept all plugin prompts, pass --yes (or -y):
2026-04-05 15:04:41 -07:00
python3 install.py --yes
2026-04-09 17:21:05 -07:00
By default this uses the default build environment. To use a different environment pass --environment (or -e):
2026-04-01 19:25:07 -07:00
2026-04-08 20:36:56 -07:00
python3 install.py --environment slim
python3 install.py --environment gh_release
2026-04-01 19:25:07 -07:00
2026-04-05 15:04:41 -07:00
Flags can be combined:
2026-04-08 20:36:56 -07:00
python3 install.py -y -e gh_release
2026-04-05 15:04:41 -07:00
2026-04-09 17:21:05 -07:00
Environment | Description
------------|-------------
default | Debug logging enabled, version from current git branch (recommended)
gh_release | Info logging only, version hardcoded to release tag
slim | No serial logging, smallest binary size
2026-04-01 19:25:07 -07:00
2026-04-01 16:21:24 -07:00
The installer will:
1. Clone the CrossPoint Reader source repository
2. Prompt you to select which plugins to install and apply them as patches
3. Build the firmware with PlatformIO
4. Auto-detect your device's serial port and flash the firmware
2026-04-09 17:21:05 -07:00
Note: This script modifies and flashes custom firmware to your device. The author accepts no responsibility for any damage that may occur to your device as a result of using this installer.
2026-04-01 16:21:24 -07:00
## Repository Structure
2026-04-09 17:30:46 -07:00
```
2026-04-01 16:21:24 -07:00
xteink-plugins/
2026-07-16 15:39:10 -07:00
├── install.py # Interactive installer: clone → select → apply → build → flash
├── framework/ # Shared plugin engine (see "Adding a Plugin" below)
│ ├── manifest.py # Declarative contribution types plugins are built from
│ ├── engine.py # Applies every selected plugin's contributions in one pass
│ └── discovery.py # Finds plugin.py files under plugins/
├── test_harness.py # Applies every plugin, alone and in combination, against a
│ # fresh clone and reports pass/fail - run this after adding
│ # or editing a plugin
2026-04-01 16:21:24 -07:00
└── plugins/
2026-04-01 17:29:38 -07:00
├── darkmode/
2026-07-16 15:39:10 -07:00
│ ├── plugin.py
│ └── DarkModePlugin.h/.cpp
2026-04-08 19:52:08 -07:00
├── smallerfonts/
2026-07-16 15:39:10 -07:00
│ ├── plugin.py
│ └── SmallerFontsPlugin.h/.cpp
2026-04-09 17:21:05 -07:00
├── lockscreen/
2026-07-16 15:39:10 -07:00
│ ├── plugin.py
2026-04-09 17:21:05 -07:00
│ ├── LockscreenPlugin.h/.cpp
│ └── LockscreenActivity.h/.cpp
2026-04-23 15:02:44 -07:00
├── bookerly/
2026-07-16 15:39:10 -07:00
│ ├── plugin.py
2026-04-23 15:02:44 -07:00
│ └── BookerlyPlugin.h/.cpp
├── hardcover/
2026-07-16 15:39:10 -07:00
│ ├── plugin.py
2026-04-23 15:02:44 -07:00
│ ├── HardcoverPlugin.h/.cpp
│ └── HardcoverSyncActivity.h/.cpp
2026-07-16 15:39:10 -07:00
├── githubsync/
│ ├── plugin.py
│ ├── GitHubSync.h/.cpp
│ └── GitHubSyncSettingsActivity.h/.cpp
└── pong/
├── plugin.py
└── PongActivity.h/.cpp
2026-04-09 17:30:46 -07:00
```
2026-04-01 16:21:24 -07:00
2026-04-01 18:34:52 -07:00
## Troubleshooting
### Linux: Permission denied when flashing
2026-04-09 17:21:05 -07:00
If you see an error like:
Could not open /dev/ttyACM0, the port is busy or doesn't exist
or Permission denied
Run:
2026-04-01 18:34:52 -07:00
sudo usermod -aG dialout $USER
2026-04-09 17:21:05 -07:00
Log out and log back in for the change to take effect, then re-run install.py.
2026-04-01 18:34:52 -07:00
2026-04-01 19:12:16 -07:00
### Windows: 'pio' is not recognized
2026-04-09 17:21:05 -07:00
If you see:
'pio' is not recognized as an internal or external command
Run in PowerShell:
2026-04-01 19:12:16 -07:00
$env:PATH += ";$env:USERPROFILE\.platformio\penv\Scripts"
[Environment]::SetEnvironmentVariable("PATH", $env:PATH, "User")
2026-04-09 17:21:05 -07:00
If Python was installed from the Microsoft Store:
2026-04-01 19:25:07 -07:00
$scripts = (Get-ChildItem "$env:USERPROFILE\AppData\Local\Packages" -Filter "Scripts" -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.FullName -like "*Python*" } | Select-Object -First 1).FullName
$env:PATH += ";$scripts"
[Environment]::SetEnvironmentVariable("PATH", $env:PATH, "User")
2026-04-09 17:21:05 -07:00
Restart your terminal and re-run install.py.
2026-04-01 19:12:16 -07:00
2026-04-01 16:21:24 -07:00
## Adding a Plugin
2026-07-16 15:39:10 -07:00
1. Create a new directory under `plugins/` with your plugin's name.
2. Add a `plugin.py` with a `get_manifest(ctx) -> PluginManifest` function. Use an existing plugin (e.g. `plugins/pong/plugin.py` for a simple action-row example, or `plugins/darkmode/plugin.py` for a settings-backed one) as a template. `framework/manifest.py` documents every contribution type: `SettingsField` , `PluginsTabEntry` , `SettingActionEnumValue` , `MainHook` , `ToggleHook` , `TranslationEntry` , and so on.
3. List any plugin-owned `.h` /`.cpp` files under `source_files` so the installer copies them into the firmware tree - you don't touch any shared CrossPoint file directly.
4. Run `python3 test_harness.py <path-to-a-crosspoint-reader-clone> /tmp/scratch <your-plugin-name>` (or `all` to check every plugin and combination) to confirm it applies cleanly alone and alongside everything else, before shipping it.
2026-04-01 16:21:24 -07:00
2026-07-16 15:39:10 -07:00
The installer automatically discovers and offers to install any directory under `plugins/` that contains a `plugin.py` exposing `get_manifest` .