// RawMode sets the terminal to something like the "raw" mode. Input is available // character by character, echoing is disabled, and all special processing of // terminal input and output characters is disabled. // // NOTE: in tty "raw mode", CR+LF is used for output and CR is used for input. func (t *Terminal) RawMode() error { // Input modes - no break, no CR to NL, no NL to CR, no carriage return, // no strip char, no start/stop output control, no parity check. t.lastState.Iflag &^= (sys.BRKINT | sys.IGNBRK | sys.ICRNL | sys.INLCR | sys.IGNCR | sys.ISTRIP | sys.IXON | sys.PARMRK) // Output modes - disable post processing. t.lastState.Oflag &^= sys.OPOST // Local modes - echoing off, canonical off, no extended functions, // no signal chars (^Z,^C). t.lastState.Lflag &^= (sys.ECHO | sys.ECHONL | sys.ICANON | sys.IEXTEN | sys.ISIG) // Control modes - set 8 bit chars. t.lastState.Cflag &^= (sys.CSIZE | sys.PARENB) t.lastState.Cflag |= sys.CS8 // Control chars - set return condition: min number of bytes and timer. // We want read to return every single byte, without timeout. t.lastState.Cc[sys.VMIN] = 1 // Read returns when one char is available. t.lastState.Cc[sys.VTIME] = 0 // Put the terminal in raw mode after flushing if err := sys.Setattr(t.fd, sys.TCSAFLUSH, &t.lastState); err != nil { return os.NewSyscallError("sys.Setattr", err) } t.mode |= RawMode return nil }
// SetMode sets the terminal attributes given by state. // Warning: The use of this function is not cross-system. func (t *Terminal) SetMode(state sys.Termios) error { if err := sys.Setattr(t.fd, sys.TCSANOW, &state); err != nil { return os.NewSyscallError("sys.Setattr", err) } t.lastState = state t.mode |= OtherMode return nil }
// Restore restores the original settings for the term. func (t *Terminal) Restore() error { if t.mode != 0 { if err := sys.Setattr(t.fd, sys.TCSANOW, &t.oldState); err != nil { return os.NewSyscallError("sys.Setattr", err) } t.lastState = t.oldState t.mode = 0 } return nil }
// CharMode sets the terminal to single-character mode. func (t *Terminal) CharMode() error { // Disable canonical mode, and set buffer size to 1 byte. t.lastState.Lflag &^= sys.ICANON t.lastState.Cc[sys.VTIME] = 0 t.lastState.Cc[sys.VMIN] = 1 if err := sys.Setattr(t.fd, sys.TCSANOW, &t.lastState); err != nil { return os.NewSyscallError("sys.Setattr", err) } t.mode |= CharMode return nil }
// EchoMode turns the echo mode. func (t *Terminal) EchoMode(echo bool) error { if !echo { //t.lastState.Lflag &^= (sys.ECHO | sys.ECHOE | sys.ECHOK | sys.ECHONL) t.lastState.Lflag &^= sys.ECHO } else { //t.lastState.Lflag |= (sys.ECHO | sys.ECHOE | sys.ECHOK | sys.ECHONL) t.lastState.Lflag |= sys.ECHO } if err := sys.Setattr(t.fd, sys.TCSANOW, &t.lastState); err != nil { return os.NewSyscallError("sys.Setattr", err) } if echo { t.mode |= EchoMode } else { t.mode &^= EchoMode } return nil }
// Restore restores the settings from State. func Restore(fd int, st State) error { if err := sys.Setattr(fd, sys.TCSANOW, &st.wrap); err != nil { return os.NewSyscallError("sys.Setattr", err) } return nil }