Skip to main content

fresh/services/gpm/
types.rs

1//! Rust types for GPM events, buttons, and modifiers
2
3/// GPM event types (from gpm.h)
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[repr(u32)]
6pub enum GpmEventType {
7    Move = 1,
8    Drag = 2,
9    Down = 4,
10    Up = 8,
11    Single = 16,
12    Double = 32,
13    Triple = 64,
14    MFlag = 128,
15    Hard = 256,
16    Enter = 512,
17    Leave = 1024,
18}
19
20/// GPM button flags (from gpm.h)
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct GpmButtons(pub u8);
23
24impl GpmButtons {
25    pub const NONE: u8 = 0;
26    pub const RIGHT: u8 = 1;
27    pub const MIDDLE: u8 = 2;
28    pub const LEFT: u8 = 4;
29    pub const FOURTH: u8 = 8;
30    pub const UP: u8 = 16; // Scroll up
31    pub const DOWN: u8 = 32; // Scroll down
32
33    pub fn left(&self) -> bool {
34        self.0 & Self::LEFT != 0
35    }
36
37    pub fn middle(&self) -> bool {
38        self.0 & Self::MIDDLE != 0
39    }
40
41    pub fn right(&self) -> bool {
42        self.0 & Self::RIGHT != 0
43    }
44
45    pub fn scroll_up(&self) -> bool {
46        self.0 & Self::UP != 0
47    }
48
49    pub fn scroll_down(&self) -> bool {
50        self.0 & Self::DOWN != 0
51    }
52}
53
54/// GPM modifier flags
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct GpmModifiers(pub u8);
57
58impl GpmModifiers {
59    pub fn shift(&self) -> bool {
60        self.0 & 1 != 0
61    }
62
63    pub fn ctrl(&self) -> bool {
64        self.0 & 4 != 0
65    }
66
67    pub fn alt(&self) -> bool {
68        self.0 & 8 != 0
69    }
70}
71
72/// A mouse event from GPM
73#[derive(Debug, Clone)]
74pub struct GpmEvent {
75    pub buttons: GpmButtons,
76    pub modifiers: GpmModifiers,
77    pub x: i16,
78    pub y: i16,
79    pub dx: i16,
80    pub dy: i16,
81    pub event_type: u32,
82    pub clicks: i32,
83    pub wdx: i16, // Wheel delta x
84    pub wdy: i16, // Wheel delta y
85}
86
87impl GpmEvent {
88    /// Check if this is a move event
89    pub fn is_move(&self) -> bool {
90        self.event_type & GpmEventType::Move as u32 != 0
91    }
92
93    /// Check if this is a drag event
94    pub fn is_drag(&self) -> bool {
95        self.event_type & GpmEventType::Drag as u32 != 0
96    }
97
98    /// Check if this is a button down event
99    pub fn is_down(&self) -> bool {
100        self.event_type & GpmEventType::Down as u32 != 0
101    }
102
103    /// Check if this is a button up event
104    pub fn is_up(&self) -> bool {
105        self.event_type & GpmEventType::Up as u32 != 0
106    }
107
108    /// Check if this is a single click
109    pub fn is_single_click(&self) -> bool {
110        self.event_type & GpmEventType::Single as u32 != 0
111    }
112
113    /// Check if this is a double click
114    pub fn is_double_click(&self) -> bool {
115        self.event_type & GpmEventType::Double as u32 != 0
116    }
117
118    /// Check if this is a triple click
119    pub fn is_triple_click(&self) -> bool {
120        self.event_type & GpmEventType::Triple as u32 != 0
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn test_gpm_buttons() {
130        let buttons = GpmButtons(GpmButtons::LEFT | GpmButtons::MIDDLE);
131        assert!(buttons.left());
132        assert!(buttons.middle());
133        assert!(!buttons.right());
134    }
135
136    #[test]
137    fn test_gpm_modifiers() {
138        let mods = GpmModifiers(1 | 4); // Shift + Ctrl
139        assert!(mods.shift());
140        assert!(mods.ctrl());
141        assert!(!mods.alt());
142    }
143
144    #[test]
145    fn test_gpm_event_types() {
146        let event = GpmEvent {
147            buttons: GpmButtons(0),
148            modifiers: GpmModifiers(0),
149            x: 10,
150            y: 20,
151            dx: 0,
152            dy: 0,
153            event_type: GpmEventType::Down as u32 | GpmEventType::Single as u32,
154            clicks: 1,
155            wdx: 0,
156            wdy: 0,
157        };
158
159        assert!(event.is_down());
160        assert!(event.is_single_click());
161        assert!(!event.is_up());
162        assert!(!event.is_move());
163    }
164}