summaryrefslogtreecommitdiffstats
path: root/src/sc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sc.rs')
-rw-r--r--src/sc.rs134
1 files changed, 0 insertions, 134 deletions
diff --git a/src/sc.rs b/src/sc.rs
deleted file mode 100644
index cb20c68..0000000
--- a/src/sc.rs
+++ /dev/null
@@ -1,134 +0,0 @@
-use libc::{termios, winsize};
-use std::error::Error;
-use std::io::{stdin, stdout, Read, Write};
-use std::sync::mpsc::{Receiver, SyncSender, TryRecvError};
-
-pub fn move_cursor(row: u16, col: u16) -> Result<(), Box<dyn Error>> {
- write!(stdout(), "\x1b[{};{}H", row + 1, col + 1)?;
- Ok(())
-}
-
-pub fn clear() -> Result<(), Box<dyn Error>> {
- write!(stdout(), "\x1b[2J")?;
- Ok(())
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Key {
- Up,
- Down,
- Left,
- Right,
-}
-
-pub struct Screen {
- pub rows: u16,
- pub cols: u16,
- old_attr: termios,
- cancel: SyncSender<()>,
- keys: Receiver<Key>,
-}
-
-impl Screen {
- pub fn init() -> Result<Screen, Box<dyn Error>> {
- let mut size: winsize;
- unsafe {
- size = std::mem::zeroed();
- if libc::ioctl(1, libc::TIOCGWINSZ, &mut size) < 0 {
- return Err(Box::from("ioctl failed"));
- }
- }
- if size.ws_col > 60 {
- size.ws_col = 60;
- }
- if size.ws_row > 30 {
- size.ws_row = 30;
- }
-
- let mut attr;
- unsafe {
- attr = std::mem::zeroed();
- if libc::tcgetattr(1, &mut attr) < 0 {
- return Err(Box::from("tcgetattr failed"));
- }
- }
-
- unsafe {
- let mut raw = std::mem::zeroed();
- libc::cfmakeraw(&mut raw);
- raw.c_cc[libc::VMIN] = 0;
- raw.c_cc[libc::VTIME] = 1;
- if libc::tcsetattr(1, libc::TCSANOW, &raw) < 0 {
- return Err(Box::from("tcsetattr failed"));
- }
- }
-
- clear()?;
- move_cursor(0, 0)?;
- for _ in 0..size.ws_col {
- write!(stdout(), "-")?;
- }
- for i in 1..size.ws_row - 1 {
- move_cursor(i, 0)?;
- write!(stdout(), "|")?;
- move_cursor(i, size.ws_col - 1)?;
- write!(stdout(), "|")?;
- }
- move_cursor(size.ws_row - 1, 0)?;
- for _ in 0..size.ws_col {
- write!(stdout(), "-")?;
- }
-
- let (cancel_tx, cancel_rx) = std::sync::mpsc::sync_channel(0);
- let (key_tx, key_rx) = std::sync::mpsc::sync_channel(4);
- std::thread::spawn(move || {
- let mut buf = [0; 3];
- while let Err(TryRecvError::Empty) = cancel_rx.try_recv() {
- let Ok(n) = stdin().read(&mut buf) else {
- continue;
- };
- if n < 3 || buf[0] != 27 || buf[1] != b'[' {
- continue;
- }
- let key = match buf[2] {
- b'A' => Key::Up,
- b'B' => Key::Down,
- b'C' => Key::Right,
- b'D' => Key::Left,
- _ => {
- continue;
- }
- };
- let _ = key_tx.try_send(key);
- }
- });
-
- Ok(Screen {
- rows: size.ws_row,
- cols: size.ws_col,
- old_attr: attr,
- cancel: cancel_tx,
- keys: key_rx,
- })
- }
-
- pub fn read_key(&self) -> Option<Key> {
- if let Ok(key) = self.keys.try_recv() {
- return Some(key);
- }
- None
- }
-
- pub fn in_bounds(&self, row: u16, col: u16) -> bool {
- (1..self.rows - 1).contains(&row) && (1..self.cols - 1).contains(&col)
- }
-}
-
-impl Drop for Screen {
- fn drop(&mut self) {
- self.cancel.send(()).unwrap();
- unsafe {
- libc::tcsetattr(1, libc::TCSANOW, &self.old_attr);
- }
- }
-}