func (s *Screen) Init() error { var err error ttyIn, err = os.OpenFile("/dev/tty", os.O_RDWR, 0666) if err != nil { return err } ttyOut, err = os.OpenFile("/dev/tty", os.O_RDONLY, 0666) if err != nil { return err } orig = new(syscall.Termios) err = tcgetattr(ttyIn.Fd(), orig) if err != nil { return err } tios := new(syscall.Termios) *tios = *orig tios.Iflag &= ^uint32(syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG) tios.Iflag &= ^uint32(syscall.BRKINT | syscall.ICRNL | syscall.ISTRIP | syscall.IXON) tios.Cflag &= ^uint32(syscall.CSIZE | syscall.PARENB) tios.Cflag |= syscall.CS8 tios.Oflag &= ^uint32(syscall.OPOST) tios.Cc[syscall.VMIN] = 1 tios.Cc[syscall.VTIME] = 0 err = tcsetattr(ttyIn.Fd(), tios) if err != nil { return err } s.HideCursor() s.Clear() return nil }
func (i *iflagSetter) Set(pty *os.File, termios *syscall.Termios, value uint32) error { if value == 0 { termios.Iflag &^= i.Flag } else { termios.Iflag |= i.Flag } return SetAttr(pty, termios) }
// Cfmakeraw modifies attr for raw mode. func Cfmakeraw(attr *syscall.Termios) { attr.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON attr.Oflag &^= syscall.OPOST attr.Cflag &^= syscall.CSIZE | syscall.PARENB attr.Cflag |= syscall.CS8 attr.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG attr.Cc[syscall.VMIN] = 1 attr.Cc[syscall.VTIME] = 0 }
// returns non-canonical mode term for keybind func rawModeTerm(term syscall.Termios) syscall.Termios { term.Iflag &= syscall.IGNCR // ignore received CR term.Lflag ^= syscall.ICANON // disable canonical mode term.Lflag ^= syscall.ECHO // disable echo of input term.Lflag ^= syscall.ISIG // disable signal term.Cc[syscall.VMIN] = 1 // number of bytes to read() term.Cc[syscall.VTIME] = 0 // timeout of read() return term }
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error { switch parity { case PARITY_NONE: settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tc_CMSPAR) settings.Iflag &= ^termiosMask(syscall.INPCK) case PARITY_ODD: settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD) settings.Cflag &= ^termiosMask(tc_CMSPAR) settings.Iflag |= termiosMask(syscall.INPCK) case PARITY_EVEN: settings.Cflag &= ^termiosMask(syscall.PARODD | tc_CMSPAR) settings.Cflag |= termiosMask(syscall.PARENB) settings.Iflag |= termiosMask(syscall.INPCK) case PARITY_MARK: settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tc_CMSPAR) settings.Iflag |= termiosMask(syscall.INPCK) case PARITY_SPACE: settings.Cflag &= ^termiosMask(syscall.PARODD) settings.Cflag |= termiosMask(syscall.PARENB | tc_CMSPAR) settings.Iflag |= termiosMask(syscall.INPCK) } return nil }
func setRawMode(settings *syscall.Termios) { // Set local mode settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL) // Set raw mode settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN) settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK | syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | tcIUCLC) settings.Oflag &= ^termiosMask(syscall.OPOST) // Block reads until at least one char is available (no timeout) settings.Cc[syscall.VMIN] = 1 settings.Cc[syscall.VTIME] = 0 }
func setRawMode(settings *syscall.Termios, mode *Mode) { // Set local mode settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL) // Set raw mode settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN) settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK | syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | tc_IUCLC) settings.Oflag &= ^termiosMask(syscall.OPOST) if mode.Vmin == 0 && mode.Vtimeout == 0 { // Switch to default mode // Block reads until at least one char is available (no timeout) mode.Vmin = 1 } settings.Cc[syscall.VMIN] = mode.Vmin settings.Cc[syscall.VTIME] = mode.Vtimeout }
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error { switch parity { case NoParity: settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR) settings.Iflag &= ^termiosMask(syscall.INPCK) case OddParity: settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD) settings.Cflag &= ^termiosMask(tcCMSPAR) settings.Iflag |= termiosMask(syscall.INPCK) case EvenParity: settings.Cflag &= ^termiosMask(syscall.PARODD | tcCMSPAR) settings.Cflag |= termiosMask(syscall.PARENB) settings.Iflag |= termiosMask(syscall.INPCK) case MarkParity: settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR) settings.Iflag |= termiosMask(syscall.INPCK) case SpaceParity: settings.Cflag &= ^termiosMask(syscall.PARODD) settings.Cflag |= termiosMask(syscall.PARENB | tcCMSPAR) settings.Iflag |= termiosMask(syscall.INPCK) } return nil }