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}