diff --git a/tscreen_bsd.go b/tscreen_bsd.go deleted file mode 100644 index b10e2224..00000000 --- a/tscreen_bsd.go +++ /dev/null @@ -1,121 +0,0 @@ -// +build freebsd netbsd openbsd dragonfly - -// Copyright 2019 The TCell Authors -// -// 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" - "unsafe" -) - -type termiosPrivate syscall.Termios - -func (t *tScreen) termioInit() error { - var e error - var newtios termiosPrivate - var fd uintptr - var tios uintptr - var ioc uintptr - t.tiosp = &termiosPrivate{} - - 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 - } - - tios = uintptr(unsafe.Pointer(t.tiosp)) - ioc = uintptr(syscall.TIOCGETA) - fd = uintptr(t.out.(*os.File).Fd()) - if _, _, e1 := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioc, tios, 0, 0, 0); e1 != 0 { - e = e1 - goto failed - } - - newtios = *t.tiosp - newtios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | - syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | - syscall.ICRNL | syscall.IXON - newtios.Oflag &^= syscall.OPOST - newtios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | - syscall.ISIG | syscall.IEXTEN - newtios.Cflag &^= syscall.CSIZE | syscall.PARENB - newtios.Cflag |= syscall.CS8 - - tios = uintptr(unsafe.Pointer(&newtios)) - - ioc = uintptr(syscall.TIOCSETA) - if _, _, e1 := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioc, tios, 0, 0, 0); e1 != 0 { - e = e1 - goto failed - } - - signal.Notify(t.sigwinch, syscall.SIGWINCH) - - if w, h, e := t.getWinSize(); e == nil && w != 0 && h != 0 { - t.cells.Resize(w, h) - } - - return nil - -failed: - if t.in != nil { - t.in.(*os.File).Close() - } - if t.out != nil { - t.out.(*os.File).Close() - } - return e -} - -func (t *tScreen) termioFini() { - - signal.Stop(t.sigwinch) - - <-t.indoneq - - if t.out != nil { - fd := uintptr(t.out.(*os.File).Fd()) - ioc := uintptr(syscall.TIOCSETAF) - tios := uintptr(unsafe.Pointer(t.tiosp)) - syscall.Syscall6(syscall.SYS_IOCTL, fd, ioc, tios, 0, 0, 0) - t.out.(*os.File).Close() - } - if t.in != nil { - t.in.(*os.File).Close() - } -} - -func (t *tScreen) getWinSize() (int, int, error) { - - fd := uintptr(t.out.(*os.File).Fd()) - dim := [4]uint16{} - dimp := uintptr(unsafe.Pointer(&dim)) - ioc := uintptr(syscall.TIOCGWINSZ) - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, - fd, ioc, dimp, 0, 0, 0); err != 0 { - return -1, -1, err - } - return int(dim[1]), int(dim[0]), nil -} - -func (t *tScreen) Beep() error { - t.writeString(string(byte(7))) - return nil -} diff --git a/tscreen_darwin.go b/tscreen_darwin.go index d05479d3..3fd54ee8 100644 --- a/tscreen_darwin.go +++ b/tscreen_darwin.go @@ -38,20 +38,20 @@ package tcell import ( "os/signal" "syscall" - "unsafe" "github.com/zyedidia/poller" + + "golang.org/x/sys/unix" ) -type termiosPrivate syscall.Termios +type termiosPrivate struct { + tio *unix.Termios +} func (t *tScreen) termioInit() error { var e error - var newtios termiosPrivate - var fd uintptr - var tios uintptr - var ioc uintptr - t.tiosp = &termiosPrivate{} + var raw unix.Termios + var tio *unix.Termios if t.in, e = poller.Open("/dev/tty", poller.O_RO); e != nil { goto failed @@ -60,29 +60,24 @@ func (t *tScreen) termioInit() error { goto failed } - tios = uintptr(unsafe.Pointer(t.tiosp)) - ioc = uintptr(syscall.TIOCGETA) - fd = uintptr(t.out.(*poller.FD).Sysfd()) - if _, _, e1 := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioc, tios, 0, 0, 0); e1 != 0 { - e = e1 + tio, e = unix.IoctlGetTermios(int(t.out.(*poller.FD).Sysfd()), getTermios) + if e != nil { goto failed } - newtios = *t.tiosp - newtios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | - syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | - syscall.ICRNL | syscall.IXON - newtios.Oflag &^= syscall.OPOST - newtios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | - syscall.ISIG | syscall.IEXTEN - newtios.Cflag &^= syscall.CSIZE | syscall.PARENB - newtios.Cflag |= syscall.CS8 - - tios = uintptr(unsafe.Pointer(&newtios)) - - ioc = uintptr(syscall.TIOCSETA) - if _, _, e1 := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioc, tios, 0, 0, 0); e1 != 0 { - e = e1 + t.tiosp = &termiosPrivate{tio: tio} + + raw = *tio + raw.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | + 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 + + e = unix.IoctlSetTermios(int(t.out.(*poller.FD).Sysfd()), setTermios, &raw) + if e != nil { goto failed } @@ -110,11 +105,8 @@ func (t *tScreen) termioFini() { <-t.indoneq - if t.out != nil { - fd := uintptr(t.out.(*poller.FD).Sysfd()) - ioc := uintptr(syscall.TIOCSETAF) - tios := uintptr(unsafe.Pointer(t.tiosp)) - syscall.Syscall6(syscall.SYS_IOCTL, fd, ioc, tios, 0, 0, 0) + if t.out != nil && t.tiosp != nil { + unix.IoctlSetTermios(int(t.out.(*poller.FD).Sysfd()), flushTermios, t.tiosp.tio) t.out.(*poller.FD).Close() } @@ -124,16 +116,11 @@ func (t *tScreen) termioFini() { } func (t *tScreen) getWinSize() (int, int, error) { - - fd := uintptr(t.out.(*poller.FD).Sysfd()) - dim := [4]uint16{} - dimp := uintptr(unsafe.Pointer(&dim)) - ioc := uintptr(syscall.TIOCGWINSZ) - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, - fd, ioc, dimp, 0, 0, 0); err != 0 { + wsz, err := unix.IoctlGetWinsize(int(t.out.(*poller.FD).Sysfd()), unix.TIOCGWINSZ) + if err != nil { return -1, -1, err } - return int(dim[1]), int(dim[0]), nil + return int(wsz.Col), int(wsz.Row), nil } func (t *tScreen) Beep() error { diff --git a/tscreen_solaris.go b/tscreen_solaris.go deleted file mode 100644 index b0c7272f..00000000 --- a/tscreen_solaris.go +++ /dev/null @@ -1,122 +0,0 @@ -// +build solaris illumos - -// Copyright 2020 The TCell Authors -// -// 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" - - "golang.org/x/sys/unix" -) - -type termiosPrivate struct { - tio *unix.Termios -} - -func (t *tScreen) termioInit() error { - var e error - var raw *unix.Termios - var tio *unix.Termios - - 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 - } - - tio, e = unix.IoctlGetTermios(int(t.out.(*os.File).Fd()), unix.TCGETS) - if e != nil { - goto failed - } - - t.tiosp = &termiosPrivate{tio: 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 - - // 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. - raw.Cc[unix.VMIN] = 1 - raw.Cc[unix.VTIME] = 0 - - e = unix.IoctlSetTermios(int(t.out.(*os.File).Fd()), unix.TCSETS, raw) - if e != nil { - goto failed - } - - signal.Notify(t.sigwinch, syscall.SIGWINCH) - - if w, h, e := t.getWinSize(); e == nil && w != 0 && h != 0 { - t.cells.Resize(w, h) - } - - return nil - -failed: - if t.in != nil { - t.in.(*os.File).Close() - } - if t.out != nil { - t.out.(*os.File).Close() - } - return e -} - -func (t *tScreen) termioFini() { - - signal.Stop(t.sigwinch) - - <-t.indoneq - - if t.out != nil && t.tiosp != nil { - unix.IoctlSetTermios(int(t.out.(*os.File).Fd()), unix.TCSETSF, t.tiosp.tio) - t.out.(*os.File).Close() - } - if t.in != nil { - t.in.(*os.File).Close() - } -} - -func (t *tScreen) getWinSize() (int, int, error) { - wsz, err := unix.IoctlGetWinsize(int(t.out.(*os.File).Fd()), unix.TIOCGWINSZ) - if err != nil { - return -1, -1, err - } - return int(wsz.Col), int(wsz.Row), nil -} - -func (t *tScreen) Beep() error { - t.writeString(string(byte(7))) - return nil -} diff --git a/tscreen_linux.go b/tscreen_unix.go similarity index 87% rename from tscreen_linux.go rename to tscreen_unix.go index 63499a7c..b87ea6b8 100644 --- a/tscreen_linux.go +++ b/tscreen_unix.go @@ -1,4 +1,4 @@ -// +build linux +// +build linux solaris freebsd netbsd openbsd dragonfly // Copyright 2019 The TCell Authors // @@ -31,7 +31,7 @@ type termiosPrivate struct { func (t *tScreen) termioInit() error { var e error - var raw *unix.Termios + var raw unix.Termios var tio *unix.Termios if t.in, e = os.OpenFile("/dev/tty", os.O_RDONLY, 0); e != nil { @@ -41,21 +41,14 @@ func (t *tScreen) termioInit() error { goto failed } - tio, e = unix.IoctlGetTermios(int(t.out.(*os.File).Fd()), unix.TCGETS) + tio, e = unix.IoctlGetTermios(int(t.out.(*os.File).Fd()), getTermios) if e != nil { goto failed } t.tiosp = &termiosPrivate{tio: 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 = *tio raw.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) raw.Oflag &^= unix.OPOST @@ -71,7 +64,7 @@ func (t *tScreen) termioInit() error { raw.Cc[unix.VMIN] = 1 raw.Cc[unix.VTIME] = 0 - e = unix.IoctlSetTermios(int(t.out.(*os.File).Fd()), unix.TCSETS, raw) + e = unix.IoctlSetTermios(int(t.out.(*os.File).Fd()), setTermios, &raw) if e != nil { goto failed } @@ -101,7 +94,7 @@ func (t *tScreen) termioFini() { <-t.indoneq if t.out != nil && t.tiosp != nil { - unix.IoctlSetTermios(int(t.out.(*os.File).Fd()), unix.TCSETSF, t.tiosp.tio) + unix.IoctlSetTermios(int(t.out.(*os.File).Fd()), flushTermios, t.tiosp.tio) t.out.(*os.File).Close() } diff --git a/tscreen_unix_bsd.go b/tscreen_unix_bsd.go new file mode 100644 index 00000000..4890cbf9 --- /dev/null +++ b/tscreen_unix_bsd.go @@ -0,0 +1,11 @@ +// +build freebsd netbsd openbsd dragonfly darwin + +package tcell + +import "golang.org/x/sys/unix" + +const ( + getTermios = unix.TIOCGETA + setTermios = unix.TIOCSETA + flushTermios = unix.TIOCSETAF +) diff --git a/tscreen_unix_other.go b/tscreen_unix_other.go new file mode 100644 index 00000000..acda2cbb --- /dev/null +++ b/tscreen_unix_other.go @@ -0,0 +1,11 @@ +// +build linux solaris + +package tcell + +import "golang.org/x/sys/unix" + +const ( + getTermios = unix.TCGETS + setTermios = unix.TCSETS + flushTermios = unix.TCSETSF +)