Initial commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# Architecture
|
||||
|
||||
`surface-dial-renewed` is a userspace Linux driver. It reads the Microsoft
|
||||
Surface Dial through evdev, emits virtual input devices through uinput, uses HID
|
||||
for haptic feedback, and uses KDE's OSD service for sensitivity feedback.
|
||||
|
||||
## Runtime Threads
|
||||
|
||||
The process has one main event loop and one input worker thread.
|
||||
|
||||
The input worker is created by `DialReader::spawn` in `src/dial.rs`. It finds
|
||||
the `Surface Dial System Multi Axis` event node through udev, blocks on evdev
|
||||
events, and sends simplified raw events through a channel.
|
||||
|
||||
The main thread owns all output state:
|
||||
|
||||
- `DriverState` in `src/main.rs`
|
||||
- `VirtualInput` in `src/virtual_input.rs`
|
||||
- `Haptics` in `src/haptics.rs`
|
||||
- `SensitivityNotifier` in `src/notify.rs`
|
||||
|
||||
Keeping output ownership on one thread avoids locking around uinput devices and
|
||||
keeps gesture lifecycle decisions local to the main loop.
|
||||
|
||||
## Module Responsibilities
|
||||
|
||||
`src/main.rs`
|
||||
|
||||
The state machine. It decides whether a Dial rotation means scroll or
|
||||
sensitivity adjustment. It starts and ends multitouch gestures, updates
|
||||
sensitivity, and calls haptics/OSD hooks.
|
||||
|
||||
`src/dial.rs`
|
||||
|
||||
Device discovery and event decoding. It converts evdev events into
|
||||
`DialEventKind` values: connect, disconnect, button press/release, long press,
|
||||
rotation, and ignored noise.
|
||||
|
||||
`src/virtual_input.rs`
|
||||
|
||||
Creates two uinput devices:
|
||||
|
||||
- `Surface Dial Renewed Touchpad` for multitouch scrolling.
|
||||
- `Surface Dial Renewed Wheel` for regular wheel mode.
|
||||
|
||||
The touchpad device is intentionally not advertised as a buttonpad and does not
|
||||
expose `BTN_LEFT`, reducing the chance that very short gestures become tap or
|
||||
right-click behavior.
|
||||
|
||||
`src/sensitivity.rs`
|
||||
|
||||
Defines the 1-32 sensitivity scale and maps each level to scroll scaling.
|
||||
|
||||
`src/haptics.rs`
|
||||
|
||||
Opens the Dial's HID device and sends manual haptic buzz reports. Haptics are
|
||||
best-effort; failure disables haptics but does not stop scrolling.
|
||||
|
||||
`src/notify.rs`
|
||||
|
||||
Shows the sensitivity value. KDE uses `qdbus6` with
|
||||
`org.kde.osdService.showText`. If that fails, the code falls back to
|
||||
FreeDesktop notifications.
|
||||
|
||||
`src/error.rs`
|
||||
|
||||
Small shared error enum for the concept driver.
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. `DialReader` finds `Surface Dial System Multi Axis`.
|
||||
2. Raw evdev events are sent to the main loop.
|
||||
3. `main.rs` decodes intent:
|
||||
- button held + rotate: sensitivity adjustment
|
||||
- rotate alone: scrolling
|
||||
- connect/disconnect: haptics and gesture cleanup
|
||||
4. `VirtualInput` emits either multitouch or wheel events.
|
||||
5. `Haptics` buzzes on selector entry and sensitivity level changes.
|
||||
6. `SensitivityNotifier` displays `Surface Dial sensitivity N/32`.
|
||||
|
||||
## Reconnect Model
|
||||
|
||||
The input worker scans for an existing Dial at startup. If the device is removed
|
||||
or an input read fails, it sends a disconnect event, sleeps briefly, and retries
|
||||
discovery/monitoring. The main loop ends any active multitouch gesture and drops
|
||||
the HID haptics handle on disconnect. On reconnect it reopens haptics.
|
||||
Reference in New Issue
Block a user