forked from sloum/bombadillo
Merge pull request 'Replace calls to `stty` with syscalls' (#158) from dancek/bombadillo:replace-stty into release-2.3.0
This commit is contained in:
commit
cf340edc36
20
client.go
20
client.go
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
@ -19,6 +18,7 @@ import (
|
|||
"tildegit.org/sloum/bombadillo/http"
|
||||
"tildegit.org/sloum/bombadillo/local"
|
||||
"tildegit.org/sloum/bombadillo/telnet"
|
||||
"tildegit.org/sloum/bombadillo/termios"
|
||||
)
|
||||
|
||||
//------------------------------------------------\\
|
||||
|
@ -43,14 +43,7 @@ type client struct {
|
|||
//--------------------------------------------------\\
|
||||
|
||||
func (c *client) GetSizeOnce() {
|
||||
cmd := exec.Command("stty", "size")
|
||||
cmd.Stdin = os.Stdin
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
cui.Exit(5, "Fatal error: Unable to retrieve terminal size")
|
||||
}
|
||||
var h, w int
|
||||
_, _ = fmt.Sscan(string(out), &h, &w)
|
||||
var w, h = termios.GetWindowSize()
|
||||
c.Height = h
|
||||
c.Width = w
|
||||
}
|
||||
|
@ -61,14 +54,7 @@ func (c *client) GetSize() {
|
|||
c.Draw()
|
||||
|
||||
for {
|
||||
cmd := exec.Command("stty", "size")
|
||||
cmd.Stdin = os.Stdin
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
cui.Exit(5, "Fatal error: Unable to retrieve terminal size")
|
||||
}
|
||||
var h, w int
|
||||
_, _ = fmt.Sscan(string(out), &h, &w)
|
||||
var w, h = termios.GetWindowSize()
|
||||
if h != c.Height || w != c.Width {
|
||||
c.Height = h
|
||||
c.Width = w
|
||||
|
|
37
cui/cui.go
37
cui/cui.go
|
@ -5,6 +5,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"tildegit.org/sloum/bombadillo/termios"
|
||||
)
|
||||
|
||||
var Shapes = map[string]string{
|
||||
|
@ -55,16 +57,17 @@ func Exit(exitCode int, msg string) {
|
|||
|
||||
// InitTerm sets the terminal modes appropriate for Bombadillo
|
||||
func InitTerm() {
|
||||
SetCharMode()
|
||||
Tput("smcup") // use alternate screen
|
||||
Tput("rmam") // turn off line wrapping
|
||||
termios.SetCharMode()
|
||||
Tput("smcup") // use alternate screen
|
||||
Tput("rmam") // turn off line wrapping
|
||||
fmt.Print("\033[?25l") // hide cursor
|
||||
}
|
||||
|
||||
// CleanupTerm reverts changs to terminal mode made by InitTerm
|
||||
func CleanupTerm() {
|
||||
moveCursorToward("down", 500)
|
||||
moveCursorToward("right", 500)
|
||||
SetLineMode()
|
||||
termios.SetLineMode()
|
||||
|
||||
fmt.Print("\n")
|
||||
fmt.Print("\033[?25h") // reenables cursor blinking
|
||||
|
@ -98,7 +101,7 @@ func Getch() rune {
|
|||
}
|
||||
|
||||
func GetLine(prefix string) (string, error) {
|
||||
SetLineMode()
|
||||
termios.SetLineMode()
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
fmt.Print(prefix)
|
||||
|
@ -107,32 +110,10 @@ func GetLine(prefix string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
SetCharMode()
|
||||
termios.SetCharMode()
|
||||
return text[:len(text)-1], nil
|
||||
}
|
||||
|
||||
func SetCharMode() {
|
||||
cmd := exec.Command("stty", "cbreak", "-echo")
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Print("\033[?25l")
|
||||
}
|
||||
|
||||
func SetLineMode() {
|
||||
cmd := exec.Command("stty", "-cbreak", "echo")
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Tput(opt string) {
|
||||
cmd := exec.Command("tput", opt)
|
||||
cmd.Stdin = os.Stdin
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// +build linux
|
||||
|
||||
package termios
|
||||
|
||||
import "syscall"
|
||||
|
||||
const (
|
||||
getTermiosIoctl = syscall.TCGETS
|
||||
setTermiosIoctl = syscall.TCSETS
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
// +build !linux
|
||||
|
||||
package termios
|
||||
|
||||
import "syscall"
|
||||
|
||||
const (
|
||||
getTermiosIoctl = syscall.TIOCGETA
|
||||
setTermiosIoctl = syscall.TIOCSETAF
|
||||
)
|
|
@ -0,0 +1,60 @@
|
|||
package termios
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type winsize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
Xpixel uint16
|
||||
Ypixel uint16
|
||||
}
|
||||
|
||||
var fd = os.Stdin.Fd()
|
||||
|
||||
func ioctl(fd, request, argp uintptr) error {
|
||||
if _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, request, argp); e != 0 {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetWindowSize() (int, int) {
|
||||
var value winsize
|
||||
ioctl(fd, syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&value)))
|
||||
return int(value.Col), int(value.Row)
|
||||
}
|
||||
|
||||
func getTermios() syscall.Termios {
|
||||
var value syscall.Termios
|
||||
err := ioctl(fd, getTermiosIoctl, uintptr(unsafe.Pointer(&value)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func setTermios(termios syscall.Termios) {
|
||||
err := ioctl(fd, setTermiosIoctl, uintptr(unsafe.Pointer(&termios)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
runtime.KeepAlive(termios)
|
||||
}
|
||||
|
||||
func SetCharMode() {
|
||||
t := getTermios()
|
||||
t.Lflag = t.Lflag ^ syscall.ICANON
|
||||
t.Lflag = t.Lflag ^ syscall.ECHO
|
||||
setTermios(t)
|
||||
}
|
||||
|
||||
func SetLineMode() {
|
||||
var t = getTermios()
|
||||
t.Lflag = t.Lflag | (syscall.ICANON | syscall.ECHO)
|
||||
setTermios(t)
|
||||
}
|
Loading…
Reference in New Issue