Codebase list golang-github-vbauerster-mpb / c2d0318
refactoring: use sys/windows rather than syscall directly Vladimir Bauer 5 years ago
1 changed file(s) with 35 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
22 package cwriter
33
44 import (
5 "syscall"
65 "unsafe"
76
87 "github.com/mattn/go-isatty"
8 "golang.org/x/sys/windows"
99 )
1010
11 var kernel32 = syscall.NewLazyDLL("kernel32.dll")
11 var kernel32 = windows.NewLazySystemDLL("kernel32.dll")
1212
1313 var (
14 procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
1514 procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
1615 procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
1716 )
1817
19 type coord struct {
20 x int16
21 y int16
22 }
23
24 type smallRect struct {
25 left int16
26 top int16
27 right int16
28 bottom int16
29 }
30
31 type consoleScreenBufferInfo struct {
32 size coord
33 cursorPosition coord
34 attributes uint16
35 window smallRect
36 maximumWindowSize coord
37 }
38
39 func (w *Writer) clearLines() {
18 func (w *Writer) clearLines() error {
4019 if !w.isTerminal && isatty.IsCygwinTerminal(w.fd) {
41 w.ansiCuuAndEd()
42 return
20 return w.ansiCuuAndEd()
4321 }
4422
45 info := new(consoleScreenBufferInfo)
46 procGetConsoleScreenBufferInfo.Call(w.fd, uintptr(unsafe.Pointer(info)))
23 var info windows.ConsoleScreenBufferInfo
24 if err := windows.GetConsoleScreenBufferInfo(windows.Handle(w.fd), &info); err != nil {
25 return err
26 }
4727
48 info.cursorPosition.y -= int16(w.lineCount)
49 if info.cursorPosition.y < 0 {
50 info.cursorPosition.y = 0
28 info.CursorPosition.Y -= int16(w.lineCount)
29 if info.CursorPosition.Y < 0 {
30 info.CursorPosition.Y = 0
5131 }
52 procSetConsoleCursorPosition.Call(w.fd, uintptr(uint32(uint16(info.cursorPosition.y))<<16|uint32(uint16(info.cursorPosition.x))))
32 _, _, _ = procSetConsoleCursorPosition.Call(
33 w.fd,
34 uintptr(uint32(uint16(info.CursorPosition.Y))<<16|uint32(uint16(info.CursorPosition.X))),
35 )
5336
5437 // clear the lines
55 cursor := &coord{
56 x: info.window.left,
57 y: info.cursorPosition.y,
38 cursor := &windows.Coord{
39 X: info.Window.Left,
40 Y: info.CursorPosition.Y,
5841 }
59 count := uint32(info.size.x) * uint32(w.lineCount)
60 procFillConsoleOutputCharacter.Call(w.fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(cursor)), uintptr(unsafe.Pointer(new(uint32))))
42 count := uint32(info.Size.X) * uint32(w.lineCount)
43 _, _, _ = procFillConsoleOutputCharacter.Call(
44 w.fd,
45 uintptr(' '),
46 uintptr(count),
47 *(*uintptr)(unsafe.Pointer(cursor)),
48 uintptr(unsafe.Pointer(new(uint32))),
49 )
50 return nil
6151 }
6252
6353 // GetSize returns the visible dimensions of the given terminal.
6454 //
6555 // These dimensions don't include any scrollback buffer height.
6656 func GetSize(fd uintptr) (width, height int, err error) {
67 info := new(consoleScreenBufferInfo)
68 procGetConsoleScreenBufferInfo.Call(fd, uintptr(unsafe.Pointer(info)))
69 return int(info.window.right - info.window.left), int(info.window.bottom - info.window.top), nil
57 var info windows.ConsoleScreenBufferInfo
58 if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
59 return 0, 0, err
60 }
61 // terminal.GetSize from crypto/ssh returns following line with both "+ 1",
62 // but looks like this causing issue #66. Removing both "+ 1" fixed the issue.
63 // return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
64 return int(info.Window.Right - info.Window.Left), int(info.Window.Bottom - info.Window.Top), nil
7065 }