reovim_kernel/ipc/events/driver.rs
1//! Driver-level events (hardware/service abstraction layer).
2//!
3//! Linux equivalent: Events similar to device driver notifications
4//!
5//! These events represent hardware-level or service-level notifications:
6//! - Display driver: resize, frame rendered
7//! - Input driver: key/mouse input
8//!
9//! # Design Philosophy
10//!
11//! Driver events bridge the gap between hardware (terminal) and kernel:
12//! - **Input driver**: Translates raw terminal events to kernel types
13//! - **Display driver**: Manages frame rendering and terminal size
14//!
15//! # Example
16//!
17//! ```
18//! use reovim_kernel::api::v1::{Event, EventBus, EventResult};
19//! use reovim_kernel::api::v1::events::driver::{DisplayResized, KeyInput, Modifiers};
20//!
21//! let bus = EventBus::new();
22//!
23//! // Subscribe to display resize
24//! let _sub = bus.subscribe::<DisplayResized, _>(0, |event| {
25//! println!("Terminal resized to {}x{}", event.width, event.height);
26//! EventResult::Handled
27//! });
28//!
29//! // Subscribe to key input
30//! let _sub = bus.subscribe::<KeyInput, _>(0, |event| {
31//! println!("Key: {:?}", event.key);
32//! EventResult::Handled
33//! });
34//!
35//! bus.emit(DisplayResized { width: 120, height: 40 });
36//! ```
37
38use crate::ipc::Event;
39
40// =============================================================================
41// Display Driver Events
42// =============================================================================
43
44/// Terminal display was resized.
45///
46/// Emitted by the display driver when the terminal size changes.
47/// Handlers should adjust layouts and re-render as needed.
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub struct DisplayResized {
50 /// New width in columns
51 pub width: u16,
52 /// New height in rows
53 pub height: u16,
54}
55
56impl Event for DisplayResized {}
57
58/// A frame was rendered to the display.
59///
60/// Emitted after the display driver completes a frame render.
61/// Useful for performance monitoring and synchronization.
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub struct FrameRendered {
64 /// Frame sequence number
65 pub frame_id: u64,
66}
67
68impl Event for FrameRendered {}
69
70// =============================================================================
71// Input Driver Events
72// =============================================================================
73
74/// Key input received from the terminal.
75///
76/// Emitted by the input driver when a key is pressed.
77/// This is the low-level key event before any keybinding processing.
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub struct KeyInput {
80 /// The key code
81 pub key: KeyCode,
82 /// Active modifiers (Ctrl, Alt, Shift)
83 pub modifiers: Modifiers,
84}
85
86impl Event for KeyInput {}
87
88/// Key code representation.
89///
90/// Represents the physical/logical key pressed.
91#[derive(Debug, Clone, PartialEq, Eq, Hash)]
92pub enum KeyCode {
93 /// Regular character
94 Char(char),
95 /// Function key (F1-F12)
96 F(u8),
97 /// Backspace
98 Backspace,
99 /// Enter/Return
100 Enter,
101 /// Left arrow
102 Left,
103 /// Right arrow
104 Right,
105 /// Up arrow
106 Up,
107 /// Down arrow
108 Down,
109 /// Home
110 Home,
111 /// End
112 End,
113 /// Page Up
114 PageUp,
115 /// Page Down
116 PageDown,
117 /// Tab
118 Tab,
119 /// Backab (Shift+Tab)
120 BackTab,
121 /// Delete
122 Delete,
123 /// Insert
124 Insert,
125 /// Escape
126 Esc,
127 /// Null (Ctrl+Space on some terminals)
128 Null,
129}
130
131impl KeyCode {
132 /// Check if this is a character key.
133 #[must_use]
134 pub const fn is_char(&self) -> bool {
135 matches!(self, Self::Char(_))
136 }
137
138 /// Get the character if this is a character key.
139 #[must_use]
140 pub const fn as_char(&self) -> Option<char> {
141 match self {
142 Self::Char(c) => Some(*c),
143 _ => None,
144 }
145 }
146}
147
148/// Keyboard modifier flags.
149///
150/// Represents modifier keys that can be combined with other keys.
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
152#[allow(clippy::struct_excessive_bools)] // Keyboard modifiers are naturally represented as bools
153pub struct Modifiers {
154 /// Control key is held
155 pub ctrl: bool,
156 /// Alt/Option key is held
157 pub alt: bool,
158 /// Shift key is held
159 pub shift: bool,
160 /// Super/Meta/Windows key is held
161 pub super_key: bool,
162}
163
164impl Modifiers {
165 /// No modifiers.
166 pub const NONE: Self = Self {
167 ctrl: false,
168 alt: false,
169 shift: false,
170 super_key: false,
171 };
172
173 /// Control modifier only.
174 pub const CTRL: Self = Self {
175 ctrl: true,
176 alt: false,
177 shift: false,
178 super_key: false,
179 };
180
181 /// Alt modifier only.
182 pub const ALT: Self = Self {
183 ctrl: false,
184 alt: true,
185 shift: false,
186 super_key: false,
187 };
188
189 /// Shift modifier only.
190 pub const SHIFT: Self = Self {
191 ctrl: false,
192 alt: false,
193 shift: true,
194 super_key: false,
195 };
196
197 /// Check if no modifiers are active.
198 #[must_use]
199 #[cfg_attr(coverage_nightly, coverage(off))]
200 pub const fn is_empty(&self) -> bool {
201 !self.ctrl && !self.alt && !self.shift && !self.super_key
202 }
203
204 /// Check if any modifier is active.
205 #[must_use]
206 #[cfg_attr(coverage_nightly, coverage(off))]
207 pub const fn any(&self) -> bool {
208 self.ctrl || self.alt || self.shift || self.super_key
209 }
210}
211
212/// Mouse input received from the terminal.
213///
214/// Emitted by the input driver for mouse events.
215#[derive(Debug, Clone, PartialEq, Eq)]
216pub struct MouseInput {
217 /// Type of mouse event
218 pub event: MouseEvent,
219 /// Column position (0-indexed)
220 pub column: u16,
221 /// Row position (0-indexed)
222 pub row: u16,
223 /// Active keyboard modifiers
224 pub modifiers: Modifiers,
225}
226
227impl Event for MouseInput {}
228
229/// Mouse event types.
230#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
231pub enum MouseEvent {
232 /// Button was pressed
233 Down(MouseButton),
234 /// Button was released
235 Up(MouseButton),
236 /// Mouse was dragged (with button held)
237 Drag(MouseButton),
238 /// Mouse moved (no button)
239 Moved,
240 /// Scroll wheel
241 ScrollUp,
242 /// Scroll wheel
243 ScrollDown,
244 /// Horizontal scroll left
245 ScrollLeft,
246 /// Horizontal scroll right
247 ScrollRight,
248}
249
250/// Mouse button identifier.
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
252pub enum MouseButton {
253 /// Left mouse button
254 Left,
255 /// Right mouse button
256 Right,
257 /// Middle mouse button (scroll wheel click)
258 Middle,
259}