1 use libc::{termios, tcgetattr, tcsetattr};
6 #[derive(Clone,Copy,Debug,PartialEq)]
20 pub struct CmdLineState {
24 pub fn new() -> Self {
25 let mut orig_state: termios = unsafe { std::mem::uninitialized() };
26 unsafe { tcgetattr(0, &mut orig_state); }
27 let mut new_state = orig_state;
28 new_state.c_lflag &= !(libc::ECHO | libc::ICANON);
29 unsafe { tcsetattr(0, 0, &new_state); }
32 pub fn restore(&self) {
33 unsafe { tcsetattr(0, 0, &self.orig_state); }
37 pub fn start_reader() -> (thread::JoinHandle<()>, mpsc::Receiver<Command>) {
38 let (sender, cmd_receiver) = mpsc::sync_channel(100);
39 (thread::spawn(move || {
40 let stdin = std::io::stdin();
41 let mut file = stdin.lock();
42 let mut ch = [0u8; 8];
45 \e char -> alt-char (including alt-[)
46 \e [ char -> A - up B - down C - right D - left F - end H - home (or \e[OF/OH)
48 \e [ num ~ -> 5 - PgUp, 6 - PgDn, 15, 17-24 - F5,F6-F12
50 match file.read(&mut ch) {
53 b'\n' => { sender.send(Command::Next).unwrap(); },
54 b' ' => { sender.send(Command::Pause).unwrap(); },
55 b'q' | b'Q' | 0o33 => {
56 sender.send(Command::Quit).unwrap();
59 b'+' => { sender.send(Command::VolumeUp).unwrap(); },
60 b'-' => { sender.send(Command::VolumeDown).unwrap(); },
61 b'd' | b'D' => { sender.send(Command::Debug).unwrap(); },
62 b'm' | b'M' => { sender.send(Command::Mute).unwrap(); },
70 b'D' => { sender.send(Command::Back(1)).unwrap(); },
71 b'B' => { sender.send(Command::Back(2)).unwrap(); },
72 b'C' => { sender.send(Command::Forward(1)).unwrap(); },
73 b'A' => { sender.send(Command::Forward(2)).unwrap(); },
74 b'F' => { sender.send(Command::Repeat).unwrap(); },
75 b'H' => { sender.send(Command::Next).unwrap(); },
78 } else if ch[1] == b'O' {
80 b'F' => { sender.send(Command::Repeat).unwrap(); },
81 b'H' => { sender.send(Command::Next).unwrap(); },
88 if ch[0] == 0o33 && ch[1] == b'[' && ch[3] == b'~' {
90 b'5' => { sender.send(Command::Forward(3)).unwrap(); },
91 b'6' => { sender.send(Command::Back(3)).unwrap(); },