libnotcurses_sys/input/
mod.rs

1//! `NcInput`
2
3// functions manually reimplemented: 6
4// ------------------------------------------
5// (+) done: 6
6// (W) wrap: 6
7// (#) test: 0
8// ------------------------------------------
9//W+ ncinput_nomod_p
10//W+ ncinput_shift_p
11//W+ ncinput_ctrl_p
12//W+ ncinput_alt_p
13//W+ ncinput_meta_p
14//W+ ncinput_equal_p
15
16use core::ffi::CStr;
17
18use crate::NcKeyMod;
19
20pub(crate) mod reimplemented;
21
22mod input_type;
23pub use input_type::NcInputType;
24mod mice_events;
25pub use mice_events::NcMiceEvents;
26mod received;
27pub use received::NcReceived;
28
29/// Reads and decodes input events.
30///
31/// Reads from stdin and decodes the input to stdout, including synthesized
32/// events and mouse events. Notcurses provides input from keyboards and mice.
33///
34/// Single Unicode codepoints are received from the keyboard, directly encoded
35/// as `u32`.
36///
37/// All events carry an `NcInput` structure with them.
38///
39/// For mouse events, the x and y coordinates are reported within this struct.
40/// For all events, modifiers (e.g. "Alt") are carried as bools in this struct.
41///
42//
43// WIP:
44//
45// An input event. Cell coordinates are currently defined only for mouse
46// events. It is not guaranteed that we can set the modifiers for a given
47// ncinput.
48//
49// We encompass single Unicode codepoints, not complete EGCs.
50pub type NcInput = crate::c_api::ffi::ncinput;
51
52mod core_impls {
53    use super::NcInput;
54
55    impl PartialEq for NcInput {
56        fn eq(&self, other: &Self) -> bool {
57            self.equal_p(other)
58        }
59    }
60}
61
62/// # Constructors
63impl NcInput {
64    /// New empty `NcInput`.
65    pub fn new_empty() -> NcInput {
66        NcInput {
67            id: 0,
68            y: 0,
69            x: 0,
70            utf8: [0; 5],
71            eff_text: [0; 4],
72            // TODO: DEPRECATED: do not use! going away in nc-4.0
73            alt: false,
74            shift: false,
75            ctrl: false,
76            // END DEPRECATION
77            evtype: NcInputType::Unknown as u32,
78            ypx: -1,
79            xpx: -1,
80            modifiers: 0,
81        }
82    }
83
84    /// New `NcInput`.
85    pub fn new(id: char) -> NcInput {
86        Self::with_all_args(id, None, None, NcKeyMod::None, NcInputType::Unknown)
87    }
88
89    /// New `NcInput` with `alt` key.
90    pub fn with_alt(id: char) -> NcInput {
91        Self::with_all_args(id, None, None, NcKeyMod::Alt, NcInputType::Unknown)
92    }
93
94    /// New `NcInput` with `shift` key.
95    pub fn with_shift(id: char) -> NcInput {
96        Self::with_all_args(id, None, None, NcKeyMod::Shift, NcInputType::Unknown)
97    }
98
99    /// New `NcInput` with `ctrl` key.
100    pub fn with_ctrl(id: char) -> NcInput {
101        Self::with_all_args(id, None, None, NcKeyMod::Ctrl, NcInputType::Unknown)
102    }
103
104    /// New `NcInput`, expecting all the arguments (except utf8).
105    pub fn with_all_args(
106        id: char,
107        x: Option<u32>,
108        y: Option<u32>,
109        modifiers: NcKeyMod,
110        evtype: NcInputType,
111    ) -> NcInput {
112        let (ix, iy);
113        if let Some(x) = x {
114            ix = x as i32
115        } else {
116            ix = -1
117        };
118        if let Some(y) = y {
119            iy = y as i32
120        } else {
121            iy = -1
122        };
123
124        NcInput {
125            id: id as u32,
126            y: ix,
127            x: iy,
128            eff_text: [0; 4],
129            utf8: [0; 5],
130            alt: false,
131            shift: false,
132            ctrl: false,
133            evtype: evtype as u32,
134            ypx: -1,
135            xpx: -1,
136            modifiers: modifiers.into(),
137        }
138    }
139}
140
141/// # Methods
142impl NcInput {
143    /// Returns the `char` from the utf8 representation of the input.
144    pub fn char(&self) -> Option<char> {
145        let cstr = unsafe { CStr::from_ptr(self.utf8.as_ptr()) };
146        let string = cstr.to_string_lossy();
147        let raw_char = string.chars().next();
148        raw_char.filter(|&ch| !ch.is_ascii_control())
149    }
150
151    /// Returns true if there are no modifiers present.
152    ///
153    /// *C style function: [ncinput_nomod_p()][crate::c_api::ncinput_nomod_p].*
154    pub fn nomod_p(&self) -> bool {
155        crate::c_api::ncinput_nomod_p(self)
156    }
157
158    /// Returns true if the [`Shift`][crate::NcKeyMod::Shift] modifier is present.
159    ///
160    /// *C style function: [ncinput_shift_p()][crate::c_api::ncinput_shift_p].*
161    pub fn shift_p(&self) -> bool {
162        crate::c_api::ncinput_shift_p(self)
163    }
164
165    /// Returns true if the [`Alt`][crate::NcKeyMod::Alt] modifier is present.
166    ///
167    /// *C style function: [ncinput_alt_p()][crate::c_api::ncinput_alt_p].*
168    pub fn alt_p(&self) -> bool {
169        crate::c_api::ncinput_alt_p(self)
170    }
171
172    /// Returns true if the [`Ctrl`][crate::NcKeyMod::Ctrl] modifier is present.
173    ///
174    /// *C style function: [ncinput_ctrl_p()][crate::c_api::ncinput_ctrl_p].*
175    pub fn ctrl_p(&self) -> bool {
176        crate::c_api::ncinput_ctrl_p(self)
177    }
178
179    /// Returns true if the [`Meta`][crate::NcKeyMod::Meta] modifier is present.
180    ///
181    /// *C style function: [ncinput_meta_p()][crate::c_api::ncinput_meta_p].*
182    pub fn meta_p(&self) -> bool {
183        crate::c_api::ncinput_meta_p(self)
184    }
185
186    /// Returns true if the [`Super`][crate::NcKeyMod::Super] modifier is present.
187    ///
188    /// *C style function: [ncinput_super_p()][crate::c_api::ncinput_super_p].*
189    pub fn super_p(&self) -> bool {
190        crate::c_api::ncinput_super_p(self)
191    }
192
193    /// Returns true if the [`Hyper`][crate::NcKeyMod::Hyper] modifier is present.
194    ///
195    /// *C style function: [ncinput_hyper_p()][crate::c_api::ncinput_hyper_p].*
196    pub fn hyper_p(&self) -> bool {
197        crate::c_api::ncinput_hyper_p(self)
198    }
199
200    /// Returns true if the [`CapsLock`][crate::NcKeyMod::CapsLock] modifier is present.
201    ///
202    /// *C style function: [ncinput_capslock_p()][crate::c_api::ncinput_capslock_p].*
203    pub fn capslock_p(&self) -> bool {
204        crate::c_api::ncinput_capslock_p(self)
205    }
206
207    /// Returns true if the [`NumLock`][crate::NcKeyMod::NumLock] modifier is present.
208    ///
209    /// *C style function: [ncinput_numlock_p()][crate::c_api::ncinput_numlock_p].*
210    pub fn numlock_p(&self) -> bool {
211        crate::c_api::ncinput_numlock_p(self)
212    }
213
214    /// Returns true if both `NcInput`s are equal.
215    ///
216    /// *C style function: [ncinput_equal_p()][crate::c_api::ncinput_equal_p].*
217    pub fn equal_p(&self, other: &NcInput) -> bool {
218        crate::c_api::ncinput_equal_p(self, other)
219    }
220}
221
222pub(crate) mod c_api {
223    pub use super::input_type::c_api::*;
224    pub use super::mice_events::c_api::*;
225}