1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
extern crate ncurses;
#[macro_use] extern crate const_cstr;
use core::ops::{BitOr, BitAnd};
use core::convert::TryInto;
mod imp_ncurses;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Modifiers(u8);
impl BitOr for Modifiers {
type Output = Modifiers;
fn bitor(self, other: Modifiers) -> Modifiers {
Modifiers(self.0 | other.0)
}
}
impl BitAnd for Modifiers {
type Output = Modifiers;
fn bitand(self, other: Modifiers) -> Modifiers {
Modifiers(self.0 & other.0)
}
}
impl Modifiers {
pub const NONE: Modifiers = Modifiers(0);
pub const SHIFT: Modifiers = Modifiers(0b1);
pub const ALT: Modifiers = Modifiers(0b10);
pub const CTRL: Modifiers = Modifiers(0b100);
pub const fn remove(self, other: Modifiers) -> Modifiers {
Modifiers(self.0 & !other.0)
}
pub const fn bitor(self, other: Modifiers) -> Modifiers {
Modifiers(self.0 | other.0)
}
pub const fn bitand(self, other: Modifiers) -> Modifiers {
Modifiers(self.0 & other.0)
}
pub const fn eq(&self, other: &Modifiers) -> bool {
self.0 == other.0
}
}
#[derive(Copy, Clone, Debug)]
pub enum Event {
KeyPress {
modifiers: Modifiers,
key: KeyInput,
is_repeat: bool,
},
KeyRelease {
modifiers: Modifiers,
key: KeyInput,
},
Mouse {
device_id: u16,
modifiers: Modifiers,
buttons: ncurses::ll::mmask_t,
x: u32,
y: u32,
},
PasteBegin,
PasteEnd,
Resize {
width: u32,
height: u32
}
}
#[derive(Copy, Clone, Debug)]
pub enum KeyInput {
Codepoint(char),
Byte(u8),
Special(i32),
}
pub struct InputStream<'a> {
inner: imp_ncurses::InputStream,
screen: ncurses::ll::WINDOW,
_stdin_lock: std::io::StdinLock<'a>,
}
impl<'a> InputStream<'a> {
pub unsafe fn init_with_ncurses(data: std::io::StdinLock<'a>, screen: ncurses::ll::WINDOW) -> InputStream<'a> {
InputStream {
inner: imp_ncurses::InputStream::init(screen),
screen: screen,
_stdin_lock: data
}
}
pub fn next_event(&mut self) -> Result<Event, ()> {
self.inner.next_event(self.screen)
}
pub fn set_escdelay(&mut self, escdelay: core::time::Duration) {
unsafe {
ncurses::ll::set_escdelay(escdelay.as_millis().try_into().unwrap_or(i32::MAX));
}
}
}