Skip to content

Commit c187a2e

Browse files
committed
Initial commit
0 parents  commit c187a2e

File tree

4 files changed

+137
-0
lines changed

4 files changed

+137
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target/
2+
**/*.rs.bk
3+
Cargo.lock

Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "festival"
3+
version = "0.1.0"
4+
authors = ["agatan <[email protected]>"]
5+
6+
[dependencies]
7+
nix = "*"
8+
term = "*"

examples/init.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
extern crate festival;
2+
3+
use festival::Festival;
4+
5+
fn main() {
6+
let mut f = Festival::new().unwrap();
7+
f.clear().unwrap();
8+
f.set_cursor(3, 3).unwrap();
9+
::std::thread::sleep(::std::time::Duration::from_millis(500));
10+
f.hide_cursor().unwrap();
11+
::std::thread::sleep(::std::time::Duration::from_millis(500));
12+
f.set_cursor(4, 4).unwrap();
13+
::std::thread::sleep(::std::time::Duration::from_millis(500));
14+
}

src/lib.rs

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
extern crate nix;
2+
extern crate term;
3+
4+
use std::io::prelude::*;
5+
use std::io;
6+
use std::fs::{File, OpenOptions};
7+
use std::ops::Drop;
8+
9+
use std::os::unix::io::AsRawFd;
10+
11+
use nix::sys::termios;
12+
use term::terminfo::TermInfo;
13+
14+
struct Cursor {
15+
x: isize,
16+
y: isize,
17+
}
18+
19+
pub struct Festival {
20+
ttyout: File,
21+
ttyin: File,
22+
terminfo: TermInfo,
23+
orig_tios: termios::Termios,
24+
cursor: Option<Cursor>,
25+
}
26+
27+
impl Festival {
28+
pub fn new() -> Result<Self, io::Error> {
29+
let ttyout = OpenOptions::new()
30+
.write(true)
31+
.read(false)
32+
.create(false)
33+
.open("/dev/tty")?;
34+
let ttyin = OpenOptions::new()
35+
.write(false)
36+
.read(true)
37+
.create(false)
38+
.open("/dev/tty")?;
39+
40+
nix::fcntl::fcntl(ttyin.as_raw_fd(),
41+
nix::fcntl::F_SETFL(nix::fcntl::O_NONBLOCK))
42+
.unwrap();
43+
let orig_tios = termios::tcgetattr(ttyout.as_raw_fd())?;
44+
let mut tios = orig_tios;
45+
tios.c_iflag &=
46+
!(termios::IGNBRK | termios::BRKINT | termios::PARMRK | termios::ISTRIP |
47+
termios::INLCR | termios::IGNCR | termios::ICRNL | termios::IXON);
48+
tios.c_lflag &= !(termios::ECHO | termios::ECHONL | termios::ICANON | termios::ISIG |
49+
termios::IEXTEN);
50+
tios.c_cflag &= !(termios::CSIZE | termios::PARENB);
51+
tios.c_cflag |= termios::CS8;
52+
tios.c_cc[termios::VMIN] = 1;
53+
tios.c_cc[termios::VTIME] = 0;
54+
termios::tcsetattr(ttyout.as_raw_fd(), termios::SetArg::TCSANOW, &tios)?;
55+
56+
let terminfo = TermInfo::from_env()?;
57+
58+
let mut fest = Festival {
59+
ttyout: ttyout,
60+
ttyin: ttyin,
61+
terminfo: terminfo,
62+
orig_tios: orig_tios,
63+
cursor: None,
64+
};
65+
66+
fest.enter_ca()?;
67+
68+
Ok(fest)
69+
}
70+
71+
fn enter_ca(&mut self) -> Result<(), io::Error> {
72+
let s = &self.terminfo.strings["smcup"];
73+
self.ttyout.write_all(&s)
74+
}
75+
76+
fn exit_ca(&mut self) -> Result<(), io::Error> {
77+
let s = &self.terminfo.strings["rmcup"];
78+
self.ttyout.write_all(&s)
79+
}
80+
81+
pub fn clear(&mut self) -> Result<(), io::Error> {
82+
self.ttyout.write_all(&self.terminfo.strings["clear"])
83+
}
84+
85+
pub fn set_cursor(&mut self, x: isize, y: isize) -> Result<(), io::Error> {
86+
if self.cursor.is_none() {
87+
self.show_cursor()?;
88+
}
89+
self.cursor = Some(Cursor { x: x, y: y });
90+
self.ttyout.write(&[0x1b])?;
91+
write!(self.ttyout, "[{};{}H", y + 1, x + 1)
92+
}
93+
94+
fn show_cursor(&mut self) -> Result<(), io::Error> {
95+
self.ttyout.write_all(&self.terminfo.strings["cnorm"])
96+
}
97+
98+
pub fn hide_cursor(&mut self) -> Result<(), io::Error> {
99+
self.cursor = None;
100+
self.ttyout.write_all(&self.terminfo.strings["civis"])
101+
}
102+
}
103+
104+
impl Drop for Festival {
105+
fn drop(&mut self) {
106+
self.exit_ca().unwrap();
107+
termios::tcsetattr(self.ttyout.as_raw_fd(),
108+
termios::SetArg::TCSANOW,
109+
&self.orig_tios)
110+
.unwrap();
111+
}
112+
}

0 commit comments

Comments
 (0)