Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:00:14.930Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

event.rs

155 lines · 5.5 KB · rust
1use x11rb::protocol::{
2    xinput,
3    xproto::{self, ModMask},
4};
5
6use gpui::{Modifiers, MouseButton, NavigationDirection};
7
8pub(crate) enum ButtonOrScroll {
9    Button(MouseButton),
10    Scroll(ScrollDirection),
11}
12
13pub(crate) enum ScrollDirection {
14    Up,
15    Down,
16    Left,
17    Right,
18}
19
20pub(crate) fn button_or_scroll_from_event_detail(detail: u32) -> Option<ButtonOrScroll> {
21    Some(match detail {
22        1 => ButtonOrScroll::Button(MouseButton::Left),
23        2 => ButtonOrScroll::Button(MouseButton::Middle),
24        3 => ButtonOrScroll::Button(MouseButton::Right),
25        4 => ButtonOrScroll::Scroll(ScrollDirection::Up),
26        5 => ButtonOrScroll::Scroll(ScrollDirection::Down),
27        6 => ButtonOrScroll::Scroll(ScrollDirection::Left),
28        7 => ButtonOrScroll::Scroll(ScrollDirection::Right),
29        8 => ButtonOrScroll::Button(MouseButton::Navigate(NavigationDirection::Back)),
30        9 => ButtonOrScroll::Button(MouseButton::Navigate(NavigationDirection::Forward)),
31        _ => return None,
32    })
33}
34
35pub(crate) fn modifiers_from_state(state: xproto::KeyButMask) -> Modifiers {
36    Modifiers {
37        control: state.contains(xproto::KeyButMask::CONTROL),
38        alt: state.contains(xproto::KeyButMask::MOD1),
39        shift: state.contains(xproto::KeyButMask::SHIFT),
40        platform: state.contains(xproto::KeyButMask::MOD4),
41        function: false,
42    }
43}
44
45pub(crate) fn modifiers_from_xinput_info(modifier_info: xinput::ModifierInfo) -> Modifiers {
46    Modifiers {
47        control: modifier_info.effective as u16 & ModMask::CONTROL.bits()
48            == ModMask::CONTROL.bits(),
49        alt: modifier_info.effective as u16 & ModMask::M1.bits() == ModMask::M1.bits(),
50        shift: modifier_info.effective as u16 & ModMask::SHIFT.bits() == ModMask::SHIFT.bits(),
51        platform: modifier_info.effective as u16 & ModMask::M4.bits() == ModMask::M4.bits(),
52        function: false,
53    }
54}
55
56pub(crate) fn pressed_button_from_mask(button_mask: u32) -> Option<MouseButton> {
57    Some(if button_mask & 2 == 2 {
58        MouseButton::Left
59    } else if button_mask & 4 == 4 {
60        MouseButton::Middle
61    } else if button_mask & 8 == 8 {
62        MouseButton::Right
63    } else {
64        return None;
65    })
66}
67
68pub(crate) fn get_valuator_axis_index(
69    valuator_mask: &Vec<u32>,
70    valuator_number: u16,
71) -> Option<usize> {
72    // XInput valuator masks have a 1 at the bit indexes corresponding to each
73    // valuator present in this event's axisvalues. Axisvalues is ordered from
74    // lowest valuator number to highest, so counting bits before the 1 bit for
75    // this valuator yields the index in axisvalues.
76    if bit_is_set_in_vec(valuator_mask, valuator_number) {
77        Some(popcount_upto_bit_index(valuator_mask, valuator_number) as usize)
78    } else {
79        None
80    }
81}
82
83/// Returns the number of 1 bits in `bit_vec` for all bits where `i < bit_index`.
84fn popcount_upto_bit_index(bit_vec: &Vec<u32>, bit_index: u16) -> u32 {
85    let array_index = bit_index as usize / 32;
86    let popcount: u32 = bit_vec
87        .get(array_index)
88        .map_or(0, |bits| keep_bits_upto(*bits, bit_index % 32).count_ones());
89    if array_index == 0 {
90        popcount
91    } else {
92        // Valuator numbers over 32 probably never occur for scroll position, but may as well
93        // support it.
94        let leading_popcount: u32 = bit_vec
95            .iter()
96            .take(array_index)
97            .map(|bits| bits.count_ones())
98            .sum();
99        popcount + leading_popcount
100    }
101}
102
103fn bit_is_set_in_vec(bit_vec: &Vec<u32>, bit_index: u16) -> bool {
104    let array_index = bit_index as usize / 32;
105    bit_vec
106        .get(array_index)
107        .is_some_and(|bits| bit_is_set(*bits, bit_index % 32))
108}
109
110fn bit_is_set(bits: u32, bit_index: u16) -> bool {
111    bits & (1 << bit_index) != 0
112}
113
114/// Sets every bit with `i >= bit_index` to 0.
115fn keep_bits_upto(bits: u32, bit_index: u16) -> u32 {
116    if bit_index == 0 {
117        0
118    } else if bit_index >= 32 {
119        u32::MAX
120    } else {
121        bits & ((1 << bit_index) - 1)
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn test_get_valuator_axis_index() {
131        assert!(get_valuator_axis_index(&vec![0b11], 0) == Some(0));
132        assert!(get_valuator_axis_index(&vec![0b11], 1) == Some(1));
133        assert!(get_valuator_axis_index(&vec![0b11], 2) == None);
134
135        assert!(get_valuator_axis_index(&vec![0b100], 0) == None);
136        assert!(get_valuator_axis_index(&vec![0b100], 1) == None);
137        assert!(get_valuator_axis_index(&vec![0b100], 2) == Some(0));
138        assert!(get_valuator_axis_index(&vec![0b100], 3) == None);
139
140        assert!(get_valuator_axis_index(&vec![0b1010, 0], 0) == None);
141        assert!(get_valuator_axis_index(&vec![0b1010, 0], 1) == Some(0));
142        assert!(get_valuator_axis_index(&vec![0b1010, 0], 2) == None);
143        assert!(get_valuator_axis_index(&vec![0b1010, 0], 3) == Some(1));
144
145        assert!(get_valuator_axis_index(&vec![0b1010, 0b1], 0) == None);
146        assert!(get_valuator_axis_index(&vec![0b1010, 0b1], 1) == Some(0));
147        assert!(get_valuator_axis_index(&vec![0b1010, 0b1], 2) == None);
148        assert!(get_valuator_axis_index(&vec![0b1010, 0b1], 3) == Some(1));
149        assert!(get_valuator_axis_index(&vec![0b1010, 0b1], 32) == Some(2));
150        assert!(get_valuator_axis_index(&vec![0b1010, 0b1], 33) == None);
151
152        assert!(get_valuator_axis_index(&vec![0b1010, 0b101], 34) == Some(3));
153    }
154}
155
Served at tenant.openagents/omega Member data and write actions are omitted.