mirror of
https://github.com/rocky-linux/peridot.git
synced 2024-11-25 14:41:26 +00:00
74 lines
2.1 KiB
Go
74 lines
2.1 KiB
Go
// +build windows
|
|
|
|
package cwriter
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
var kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
|
|
|
var (
|
|
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
|
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
|
)
|
|
|
|
func (w *Writer) clearLines() error {
|
|
if !w.isTerminal {
|
|
// hope it's cygwin or similar
|
|
return w.ansiCuuAndEd()
|
|
}
|
|
|
|
var info windows.ConsoleScreenBufferInfo
|
|
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(w.fd), &info); err != nil {
|
|
return err
|
|
}
|
|
|
|
info.CursorPosition.Y -= int16(w.lineCount)
|
|
if info.CursorPosition.Y < 0 {
|
|
info.CursorPosition.Y = 0
|
|
}
|
|
_, _, _ = procSetConsoleCursorPosition.Call(
|
|
uintptr(w.fd),
|
|
uintptr(uint32(uint16(info.CursorPosition.Y))<<16|uint32(uint16(info.CursorPosition.X))),
|
|
)
|
|
|
|
// clear the lines
|
|
cursor := &windows.Coord{
|
|
X: info.Window.Left,
|
|
Y: info.CursorPosition.Y,
|
|
}
|
|
count := uint32(info.Size.X) * uint32(w.lineCount)
|
|
_, _, _ = procFillConsoleOutputCharacter.Call(
|
|
uintptr(w.fd),
|
|
uintptr(' '),
|
|
uintptr(count),
|
|
*(*uintptr)(unsafe.Pointer(cursor)),
|
|
uintptr(unsafe.Pointer(new(uint32))),
|
|
)
|
|
return nil
|
|
}
|
|
|
|
// GetSize returns the visible dimensions of the given terminal.
|
|
//
|
|
// These dimensions don't include any scrollback buffer height.
|
|
func GetSize(fd int) (width, height int, err error) {
|
|
var info windows.ConsoleScreenBufferInfo
|
|
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
// terminal.GetSize from crypto/ssh adds "+ 1" to both width and height:
|
|
// https://go.googlesource.com/crypto/+/refs/heads/release-branch.go1.14/ssh/terminal/util_windows.go#75
|
|
// but looks like this is a root cause of issue #66, so removing both "+ 1" have fixed it.
|
|
return int(info.Window.Right - info.Window.Left), int(info.Window.Bottom - info.Window.Top), nil
|
|
}
|
|
|
|
// IsTerminal returns whether the given file descriptor is a terminal.
|
|
func IsTerminal(fd int) bool {
|
|
var st uint32
|
|
err := windows.GetConsoleMode(windows.Handle(fd), &st)
|
|
return err == nil
|
|
}
|