-
Notifications
You must be signed in to change notification settings - Fork 9
/
ncurses.go
310 lines (269 loc) · 7.75 KB
/
ncurses.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// goncurses - ncurses library for Go.
// Copyright 2011 Rob Thornton. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goncurses
// #cgo linux pkg-config: ncursesw
// #cgo windows CFLAGS: -DNCURSES_MOUSE_VERSION
// #cgo windows LDFLAGS: -lpdcurses
// #cgo darwin LDFLAGS: -lncurses
// #include <curses.h>
// #include <locale.h>
// #include "goncurses.h"
import "C"
import (
"errors"
"fmt"
"unsafe"
)
func init() {
setLocale(LC_ALL, "")
}
const (
LC_ALL = 0
LC_COLLATE = 1
LC_CTYPE = 2
LC_MONETARY = 3
LC_NUMERIC = 5
LC_TIME = 6
)
func setLocale(lc C.int, locale string) string {
param := C.CString(locale)
ret := C.setlocale(lc, param)
return C.GoString(ret)
}
// BaudRate returns the speed of the terminal in bits per second
func BaudRate() int {
return int(C.baudrate())
}
// Beep requests the terminal make an audible bell or, if not available,
// flashes the screen. Note that screen flashing doesn't work on all
// terminals
func Beep() {
C.beep()
}
// Turn on/off buffering; raw user signals are passed to the program for
// handling. Overrides raw mode
func CBreak(on bool) {
if on {
C.cbreak()
return
}
C.nocbreak()
}
// Test whether colour values can be changed
func CanChangeColor() bool {
return bool(C.bool(C.can_change_color()))
}
// Get RGB values for specified colour
func ColorContent(col int16) (int16, int16, int16) {
var r, g, b C.short
C.color_content(C.short(col), (*C.short)(&r), (*C.short)(&g),
(*C.short)(&b))
return int16(r), int16(g), int16(b)
}
// Return the value of a color pair which can be passed to functions which
// accept attributes like AddChar, AttrOn/Off and Background.
func ColorPair(pair int16) Char {
return Char(C.ncurses_COLOR_PAIR(C.int(pair)))
}
// CursesVersion returns the version of the ncurses library currently linked to
func CursesVersion() string {
return C.GoString(C.curses_version())
}
// Set the cursor visibility. Options are: 0 (invisible/hidden), 1 (normal)
// and 2 (extra-visible)
func Cursor(vis byte) error {
if C.curs_set(C.int(vis)) == C.ERR {
return errors.New("Failed to enable ")
}
return nil
}
// Echo turns on/off the printing of typed characters
func Echo(on bool) {
if on {
C.echo()
return
}
C.noecho()
}
// Must be called prior to exiting the program in order to make sure the
// terminal returns to normal operation
func End() {
C.endwin()
}
// Flash requests the terminal flashes the screen or, if not available,
// make an audible bell. Note that screen flashing doesn't work on all
// terminals
func Flash() {
C.flash()
}
// FlushInput flushes all input
func FlushInput() error {
if C.flushinp() == C.ERR {
return errors.New("Flush input failed")
}
return nil
}
// Behaves like cbreak() but also adds a timeout for input. If timeout is
// exceeded after a call to Getch() has been made then GetChar will return
// with an error.
func HalfDelay(delay int) error {
var cerr C.int
if delay > 0 {
cerr = C.halfdelay(C.int(delay))
}
if cerr == C.ERR {
return errors.New("Unable to set delay mode")
}
return nil
}
// HasColors returns true if terminal can display colors
func HasColors() bool {
return bool(C.has_colors())
}
// HasInsertChar return true if the terminal has insert and delete
// character capabilities
func HasInsertChar() bool {
return bool(C.has_ic())
}
// HasInsertLine returns true if the terminal has insert and delete line
// capabilities. See ncurses documentation for more details
func HasInsertLine() bool {
return bool(C.has_il())
}
// HasKey returns true if terminal recognized the given character
func HasKey(ch Key) bool {
if C.ncurses_has_key(C.int(ch)) == 1 {
return true
}
return false
}
// InitColor is used to set 'color' to the specified RGB values. Values may
// be between 0 and 1000.
func InitColor(col, r, g, b int16) error {
if C.init_color(C.short(col), C.short(r), C.short(g),
C.short(b)) == C.ERR {
return errors.New("Failed to set new color definition")
}
return nil
}
// InitPair sets a colour pair designated by 'pair' to fg and bg colors
func InitPair(pair, fg, bg int16) error {
if pair <= 0 || C.int(pair) > C.int(C.COLOR_PAIRS-1) {
return errors.New("Color pair out of range")
}
if C.init_pair(C.short(pair), C.short(fg), C.short(bg)) == C.ERR {
return errors.New("Failed to init color pair")
}
return nil
}
// Initialize the ncurses library. You must run this function prior to any
// other goncurses function in order for the library to work
func Init() (stdscr *Window, err error) {
stdscr = &Window{C.initscr()}
if unsafe.Pointer(stdscr.win) == nil {
err = errors.New("An error occurred initializing ncurses")
}
return
}
// IsEnd returns true if End() has been called, otherwise false
func IsEnd() bool {
return bool(C.isendwin())
}
// IsTermResized returns true if ResizeTerm would modify any current Windows
// if called with the given parameters
func IsTermResized(nlines, ncols int) bool {
return bool(C.is_term_resized(C.int(nlines), C.int(ncols)))
}
// Returns a string representing the value of input returned by Getch
func KeyString(k Key) string {
key, ok := keyList[k]
if !ok {
key = fmt.Sprintf("%c", int(k))
}
return key
}
// PairContent returns the current foreground and background colours
// associated with the given pair
func PairContent(pair int16) (fg int16, bg int16, err error) {
var f, b C.short
if C.pair_content(C.short(pair), &f, &b) == C.ERR {
return -1, -1, errors.New("Invalid color pair")
}
return int16(f), int16(b), nil
}
// Nap (sleep; halt execution) for 'ms' milliseconds
func Nap(ms int) {
C.napms(C.int(ms))
}
// NewLines turns newline translation on/off.
func NewLines(on bool) {
if on {
C.nl()
return
}
C.nonl()
}
// Raw turns on input buffering; user signals are disabled and the key strokes
// are passed directly to input. Set to false if you wish to turn this mode
// off
func Raw(on bool) {
if on {
C.raw()
return
}
C.noraw()
}
// ResizeTerm will attempt to resize the terminal. This only has an effect if
// the terminal is in an XWindows (GUI) environment.
func ResizeTerm(nlines, ncols int) error {
if C.resizeterm(C.int(nlines), C.int(ncols)) == C.ERR {
return errors.New("Failed to resize terminal")
}
return nil
}
// Enables colors to be displayed. Will return an error if terminal is not
// capable of displaying colors
func StartColor() error {
if C.has_colors() == C.bool(false) {
return errors.New("Terminal does not support colors")
}
if C.start_color() == C.ERR {
return errors.New("Failed to enable color mode")
}
return nil
}
// StdScr returns a Window for the underlying stdscr object which represents
// the physical screen. This is the same Window returned by Init and therefore
// not useful unless using NewTerm and other multi-screen related functions.
func StdScr() *Window {
return &Window{C.stdscr}
}
// UnGetChar places the character back into the input queue
func UnGetChar(ch Char) {
C.ncurses_ungetch(C.int(ch))
}
// Update the screen, refreshing all windows
func Update() error {
if C.doupdate() == C.ERR {
return errors.New("Failed to update")
}
return nil
}
// UseDefaultColors tells the curses library to assign the terminal's default
// foreground and background colors to color number -1. This will allow you to
// call InitPair(x, -1, -1) to set both the foreground and backgroun colours
// of pair x to the terminal's default. This function can fail if the terminal
// does not support certain ncurses features like orig_pair or initialize_pair.
func UseDefaultColors() error {
if C.use_default_colors() == C.ERR {
return errors.New("Failed to assume default colours.")
}
return nil
}
// UseEnvironment specifies whether the LINES and COLUMNS environmental
// variables should be used or not
func UseEnvironment(use bool) {
C.use_env(C.bool(use))
}