Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/github.com/chzyer/readline/windows_api.go
2875 views
1
// +build windows
2
3
package readline
4
5
import (
6
"reflect"
7
"syscall"
8
"unsafe"
9
)
10
11
var (
12
kernel = NewKernel()
13
stdout = uintptr(syscall.Stdout)
14
stdin = uintptr(syscall.Stdin)
15
)
16
17
type Kernel struct {
18
SetConsoleCursorPosition,
19
SetConsoleTextAttribute,
20
FillConsoleOutputCharacterW,
21
FillConsoleOutputAttribute,
22
ReadConsoleInputW,
23
GetConsoleScreenBufferInfo,
24
GetConsoleCursorInfo,
25
GetStdHandle CallFunc
26
}
27
28
type short int16
29
type word uint16
30
type dword uint32
31
type wchar uint16
32
33
type _COORD struct {
34
x short
35
y short
36
}
37
38
func (c *_COORD) ptr() uintptr {
39
return uintptr(*(*int32)(unsafe.Pointer(c)))
40
}
41
42
const (
43
EVENT_KEY = 0x0001
44
EVENT_MOUSE = 0x0002
45
EVENT_WINDOW_BUFFER_SIZE = 0x0004
46
EVENT_MENU = 0x0008
47
EVENT_FOCUS = 0x0010
48
)
49
50
type _KEY_EVENT_RECORD struct {
51
bKeyDown int32
52
wRepeatCount word
53
wVirtualKeyCode word
54
wVirtualScanCode word
55
unicodeChar wchar
56
dwControlKeyState dword
57
}
58
59
// KEY_EVENT_RECORD KeyEvent;
60
// MOUSE_EVENT_RECORD MouseEvent;
61
// WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
62
// MENU_EVENT_RECORD MenuEvent;
63
// FOCUS_EVENT_RECORD FocusEvent;
64
type _INPUT_RECORD struct {
65
EventType word
66
Padding uint16
67
Event [16]byte
68
}
69
70
type _CONSOLE_SCREEN_BUFFER_INFO struct {
71
dwSize _COORD
72
dwCursorPosition _COORD
73
wAttributes word
74
srWindow _SMALL_RECT
75
dwMaximumWindowSize _COORD
76
}
77
78
type _SMALL_RECT struct {
79
left short
80
top short
81
right short
82
bottom short
83
}
84
85
type _CONSOLE_CURSOR_INFO struct {
86
dwSize dword
87
bVisible bool
88
}
89
90
type CallFunc func(u ...uintptr) error
91
92
func NewKernel() *Kernel {
93
k := &Kernel{}
94
kernel32 := syscall.NewLazyDLL("kernel32.dll")
95
v := reflect.ValueOf(k).Elem()
96
t := v.Type()
97
for i := 0; i < t.NumField(); i++ {
98
name := t.Field(i).Name
99
f := kernel32.NewProc(name)
100
v.Field(i).Set(reflect.ValueOf(k.Wrap(f)))
101
}
102
return k
103
}
104
105
func (k *Kernel) Wrap(p *syscall.LazyProc) CallFunc {
106
return func(args ...uintptr) error {
107
var r0 uintptr
108
var e1 syscall.Errno
109
size := uintptr(len(args))
110
if len(args) <= 3 {
111
buf := make([]uintptr, 3)
112
copy(buf, args)
113
r0, _, e1 = syscall.Syscall(p.Addr(), size,
114
buf[0], buf[1], buf[2])
115
} else {
116
buf := make([]uintptr, 6)
117
copy(buf, args)
118
r0, _, e1 = syscall.Syscall6(p.Addr(), size,
119
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
120
)
121
}
122
123
if int(r0) == 0 {
124
if e1 != 0 {
125
return error(e1)
126
} else {
127
return syscall.EINVAL
128
}
129
}
130
return nil
131
}
132
133
}
134
135
func GetConsoleScreenBufferInfo() (*_CONSOLE_SCREEN_BUFFER_INFO, error) {
136
t := new(_CONSOLE_SCREEN_BUFFER_INFO)
137
err := kernel.GetConsoleScreenBufferInfo(
138
stdout,
139
uintptr(unsafe.Pointer(t)),
140
)
141
return t, err
142
}
143
144
func GetConsoleCursorInfo() (*_CONSOLE_CURSOR_INFO, error) {
145
t := new(_CONSOLE_CURSOR_INFO)
146
err := kernel.GetConsoleCursorInfo(stdout, uintptr(unsafe.Pointer(t)))
147
return t, err
148
}
149
150
func SetConsoleCursorPosition(c *_COORD) error {
151
return kernel.SetConsoleCursorPosition(stdout, c.ptr())
152
}
153
154