1package liner
2
3import (
4	"unsafe"
5)
6
7type coord struct {
8	x, y int16
9}
10type smallRect struct {
11	left, top, right, bottom int16
12}
13
14type consoleScreenBufferInfo struct {
15	dwSize              coord
16	dwCursorPosition    coord
17	wAttributes         int16
18	srWindow            smallRect
19	dwMaximumWindowSize coord
20}
21
22func (s *State) cursorPos(x int) {
23	var sbi consoleScreenBufferInfo
24	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
25	procSetConsoleCursorPosition.Call(uintptr(s.hOut),
26		uintptr(int(x)&0xFFFF|int(sbi.dwCursorPosition.y)<<16))
27}
28
29func (s *State) eraseLine() {
30	var sbi consoleScreenBufferInfo
31	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
32	var numWritten uint32
33	procFillConsoleOutputCharacter.Call(uintptr(s.hOut), uintptr(' '),
34		uintptr(sbi.dwSize.x-sbi.dwCursorPosition.x),
35		uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|int(sbi.dwCursorPosition.y)<<16),
36		uintptr(unsafe.Pointer(&numWritten)))
37}
38
39func (s *State) eraseScreen() {
40	var sbi consoleScreenBufferInfo
41	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
42	var numWritten uint32
43	procFillConsoleOutputCharacter.Call(uintptr(s.hOut), uintptr(' '),
44		uintptr(sbi.dwSize.x)*uintptr(sbi.dwSize.y),
45		0,
46		uintptr(unsafe.Pointer(&numWritten)))
47	procSetConsoleCursorPosition.Call(uintptr(s.hOut), 0)
48}
49
50func (s *State) moveUp(lines int) {
51	var sbi consoleScreenBufferInfo
52	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
53	procSetConsoleCursorPosition.Call(uintptr(s.hOut),
54		uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|(int(sbi.dwCursorPosition.y)-lines)<<16))
55}
56
57func (s *State) moveDown(lines int) {
58	var sbi consoleScreenBufferInfo
59	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
60	procSetConsoleCursorPosition.Call(uintptr(s.hOut),
61		uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|(int(sbi.dwCursorPosition.y)+lines)<<16))
62}
63
64func (s *State) emitNewLine() {
65	// windows doesn't need to omit a new line
66}
67
68func (s *State) getColumns() {
69	var sbi consoleScreenBufferInfo
70	procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
71	s.columns = int(sbi.dwSize.x)
72}
73