termion_temporary_zellij_fork/
raw.rs1use std::io::{self, Write};
26use std::ops;
27
28use sys::attr::{get_terminal_attr, raw_terminal_attr, set_terminal_attr};
29use sys::Termios;
30
31pub const CONTROL_SEQUENCE_TIMEOUT: u64 = 100;
33
34pub struct RawTerminal<W: Write> {
39 prev_ios: Termios,
40 output: W,
41}
42
43impl<W: Write> Drop for RawTerminal<W> {
44 fn drop(&mut self) {
45 set_terminal_attr(&self.prev_ios).unwrap();
46 }
47}
48
49impl<W: Write> ops::Deref for RawTerminal<W> {
50 type Target = W;
51
52 fn deref(&self) -> &W {
53 &self.output
54 }
55}
56
57impl<W: Write> ops::DerefMut for RawTerminal<W> {
58 fn deref_mut(&mut self) -> &mut W {
59 &mut self.output
60 }
61}
62
63impl<W: Write> Write for RawTerminal<W> {
64 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
65 self.output.write(buf)
66 }
67
68 fn flush(&mut self) -> io::Result<()> {
69 self.output.flush()
70 }
71}
72
73#[cfg(unix)]
74mod unix_impl {
75 use super::*;
76 use std::os::unix::io::{AsRawFd, RawFd};
77
78 impl<W: Write + AsRawFd> AsRawFd for RawTerminal<W> {
79 fn as_raw_fd(&self) -> RawFd {
80 self.output.as_raw_fd()
81 }
82 }
83}
84
85pub trait IntoRawMode: Write + Sized {
92 fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
98}
99
100impl<W: Write> IntoRawMode for W {
101 fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
102 let mut ios = get_terminal_attr()?;
103 let prev_ios = ios;
104
105 raw_terminal_attr(&mut ios);
106
107 set_terminal_attr(&ios)?;
108
109 Ok(RawTerminal {
110 prev_ios: prev_ios,
111 output: self,
112 })
113 }
114}
115
116impl<W: Write> RawTerminal<W> {
117 pub fn suspend_raw_mode(&self) -> io::Result<()> {
119 set_terminal_attr(&self.prev_ios)?;
120 Ok(())
121 }
122
123 pub fn activate_raw_mode(&self) -> io::Result<()> {
125 let mut ios = get_terminal_attr()?;
126 raw_terminal_attr(&mut ios);
127 set_terminal_attr(&ios)?;
128 Ok(())
129 }
130}
131
132#[cfg(test)]
133mod test {
134 use super::*;
135 use std::io::{stdout, Write};
136
137 #[test]
138 fn test_into_raw_mode() {
139 let mut out = stdout().into_raw_mode().unwrap();
140
141 out.write_all(b"this is a test, muahhahahah\r\n").unwrap();
142
143 drop(out);
144 }
145}