2015-11-01 21:28:38 -08:00
|
|
|
// +build solaris
|
2015-09-26 23:37:54 -07:00
|
|
|
|
2017-09-23 23:25:24 -07:00
|
|
|
// Copyright 2017 The TCell Authors
|
2015-09-26 23:37:54 -07:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the license at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package tcell
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
|
|
|
|
2019-06-26 11:31:59 -07:00
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
)
|
2015-09-26 23:37:54 -07:00
|
|
|
|
2015-10-02 21:49:13 -07:00
|
|
|
type termiosPrivate struct {
|
2019-06-26 11:31:59 -07:00
|
|
|
tio *unix.Termios
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
// These are for missing CBAUDEXT and CIBAUDEXT.
|
|
|
|
// The values are fixed for Solaris and illumos, and cannot ever
|
|
|
|
// change without breaking applications.
|
|
|
|
cBaudExt = 0x200000
|
|
|
|
ciBaudExt = 0x400000
|
|
|
|
)
|
|
|
|
|
|
|
|
// getbaud is sort of cfgetospeed, but in Go.
|
|
|
|
func getbaud(tios *unix.Termios) int {
|
|
|
|
// First we mask off the rate by looking at the Cflag.
|
|
|
|
bval := tios.Cflag & unix.CBAUD
|
|
|
|
if (tios.Cflag & cBaudExt) != 0 {
|
|
|
|
bval += unix.CBAUD + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// This gives us the appropriate BXXX value, so convert
|
|
|
|
switch bval {
|
|
|
|
case unix.B0:
|
|
|
|
return 0
|
|
|
|
case unix.B50:
|
|
|
|
return 50
|
|
|
|
case unix.B75:
|
|
|
|
return 75
|
|
|
|
case unix.B110:
|
|
|
|
return 110
|
|
|
|
case unix.B134:
|
|
|
|
return 134
|
|
|
|
case unix.B150:
|
|
|
|
return 150
|
|
|
|
case unix.B200:
|
|
|
|
return 200
|
|
|
|
case unix.B300:
|
|
|
|
return 300
|
|
|
|
case unix.B600:
|
|
|
|
return 600
|
|
|
|
case unix.B1200:
|
|
|
|
return 1200
|
|
|
|
case unix.B1800:
|
|
|
|
return 1800
|
|
|
|
case unix.B2400:
|
|
|
|
return 2400
|
|
|
|
case unix.B4800:
|
|
|
|
return 4800
|
|
|
|
case unix.B9600:
|
|
|
|
return 9600
|
|
|
|
case unix.B19200:
|
|
|
|
return 19200
|
|
|
|
case unix.B38400:
|
|
|
|
return 38400
|
|
|
|
case unix.B57600:
|
|
|
|
return 57600
|
|
|
|
case unix.B76800:
|
|
|
|
return 76800
|
|
|
|
case unix.B115200:
|
|
|
|
return 115200
|
|
|
|
case unix.B153600:
|
|
|
|
return 153600
|
|
|
|
case unix.B230400:
|
|
|
|
return 230400
|
|
|
|
case unix.B307200:
|
|
|
|
return 307200
|
|
|
|
case unix.B460800:
|
|
|
|
return 460800
|
|
|
|
case unix.B921600:
|
|
|
|
return 921600
|
|
|
|
}
|
|
|
|
return 0
|
2015-09-26 23:37:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *tScreen) termioInit() error {
|
|
|
|
var e error
|
2019-06-26 11:31:59 -07:00
|
|
|
var raw *unix.Termios
|
|
|
|
var tio *unix.Termios
|
2015-09-26 23:37:54 -07:00
|
|
|
|
|
|
|
if t.in, e = os.OpenFile("/dev/tty", os.O_RDONLY, 0); e != nil {
|
|
|
|
goto failed
|
|
|
|
}
|
|
|
|
if t.out, e = os.OpenFile("/dev/tty", os.O_WRONLY, 0); e != nil {
|
|
|
|
goto failed
|
|
|
|
}
|
|
|
|
|
2019-06-26 11:31:59 -07:00
|
|
|
tio, e = unix.IoctlGetTermios(int(t.out.Fd()), unix.TCGETS)
|
|
|
|
if e != nil {
|
2015-09-26 23:37:54 -07:00
|
|
|
goto failed
|
|
|
|
}
|
2019-06-26 11:31:59 -07:00
|
|
|
|
2019-06-27 18:33:09 -07:00
|
|
|
t.tiosp = &termiosPrivate{tio: tio}
|
2019-06-26 11:31:59 -07:00
|
|
|
t.baud = getbaud(tio)
|
|
|
|
|
|
|
|
// make a local copy, to make it raw
|
|
|
|
raw = &unix.Termios{
|
|
|
|
Cflag: tio.Cflag,
|
|
|
|
Oflag: tio.Oflag,
|
|
|
|
Iflag: tio.Iflag,
|
|
|
|
Lflag: tio.Lflag,
|
|
|
|
Cc: tio.Cc,
|
|
|
|
}
|
|
|
|
|
|
|
|
raw.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.INLCR |
|
|
|
|
unix.IGNCR | unix.ICRNL | unix.IXON)
|
|
|
|
raw.Oflag &^= unix.OPOST
|
|
|
|
raw.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
|
|
|
|
raw.Cflag &^= (unix.CSIZE | unix.PARENB)
|
|
|
|
raw.Cflag |= unix.CS8
|
2015-09-26 23:37:54 -07:00
|
|
|
|
2017-09-23 23:25:24 -07:00
|
|
|
// This is setup for blocking reads. In the past we attempted to
|
|
|
|
// use non-blocking reads, but now a separate input loop and timer
|
|
|
|
// copes with the problems we had on some systems (BSD/Darwin)
|
|
|
|
// where close hung forever.
|
2019-06-26 11:31:59 -07:00
|
|
|
raw.Cc[unix.VMIN] = 1
|
|
|
|
raw.Cc[unix.VTIME] = 0
|
2015-09-26 23:37:54 -07:00
|
|
|
|
2019-06-26 11:31:59 -07:00
|
|
|
e = unix.IoctlSetTermios(int(t.out.Fd()), unix.TCSETS, raw)
|
|
|
|
if e != nil {
|
2015-09-26 23:37:54 -07:00
|
|
|
goto failed
|
2015-09-28 22:28:41 -07:00
|
|
|
}
|
2015-09-26 23:37:54 -07:00
|
|
|
|
|
|
|
signal.Notify(t.sigwinch, syscall.SIGWINCH)
|
|
|
|
|
|
|
|
if w, h, e := t.getWinSize(); e == nil && w != 0 && h != 0 {
|
2015-10-07 00:56:18 -07:00
|
|
|
t.cells.Resize(w, h)
|
2015-09-26 23:37:54 -07:00
|
|
|
}
|
|
|
|
|
2015-09-28 22:28:41 -07:00
|
|
|
return nil
|
2015-09-26 23:37:54 -07:00
|
|
|
|
|
|
|
failed:
|
|
|
|
if t.in != nil {
|
|
|
|
t.in.Close()
|
|
|
|
}
|
|
|
|
if t.out != nil {
|
|
|
|
t.out.Close()
|
|
|
|
}
|
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *tScreen) termioFini() {
|
|
|
|
|
|
|
|
signal.Stop(t.sigwinch)
|
|
|
|
|
2015-10-02 21:49:13 -07:00
|
|
|
<-t.indoneq
|
|
|
|
|
2019-06-26 11:31:59 -07:00
|
|
|
if t.out != nil && t.tiosp != nil {
|
|
|
|
unix.IoctlSetTermios(int(t.out.Fd()), unix.TCSETSF, t.tiosp.tio)
|
2015-09-26 23:37:54 -07:00
|
|
|
t.out.Close()
|
|
|
|
}
|
|
|
|
if t.in != nil {
|
|
|
|
t.in.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *tScreen) getWinSize() (int, int, error) {
|
2019-06-26 11:31:59 -07:00
|
|
|
wsz, err := unix.IoctlGetWinsize(int(t.out.Fd()), unix.TIOCGWINSZ)
|
|
|
|
if err != nil {
|
|
|
|
return -1, -1, err
|
2015-09-26 23:37:54 -07:00
|
|
|
}
|
2019-06-26 11:31:59 -07:00
|
|
|
return int(wsz.Col), int(wsz.Row), nil
|
2015-09-26 23:37:54 -07:00
|
|
|
}
|