Updated vendor termbox

This commit is contained in:
MichaelS11 2018-02-08 17:05:23 -08:00
parent a8e9ca072c
commit f67b7198e6
7 changed files with 132 additions and 22 deletions

View File

@ -14,7 +14,7 @@ There are also some interesting projects using termbox-go:
- [sokoban-go](https://github.com/rn2dy/sokoban-go) is an implementation of sokoban game.
- [hecate](https://github.com/evanmiller/hecate) is a hex editor designed by Satan.
- [httopd](https://github.com/verdverm/httopd) is top for httpd logs.
- [mop](https://github.com/michaeldv/mop) is stock market tracker for hackers.
- [mop](https://github.com/mop-tracker/mop) is stock market tracker for hackers.
- [termui](https://github.com/gizak/termui) is a terminal dashboard.
- [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine.
- [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart.
@ -27,6 +27,13 @@ There are also some interesting projects using termbox-go:
- [lf](https://github.com/gokcehan/lf) is a terminal file manager
- [rat](https://github.com/ericfreese/rat) lets you compose shell commands to build terminal applications.
- [httplab](https://github.com/gchaincl/httplab) An interactive web server.
- [tetris](https://github.com/MichaelS11/tetris) Go Tetris with AI option
- [wot](https://github.com/kyu-suke/wot) Wait time during command is completed.
- [2048-go](https://github.com/1984weed/2048-go) is 2048 in Go
- [jv](https://github.com/maxzender/jv) helps you view JSON on the command-line.
- [pinger](https://github.com/hirose31/pinger) helps you to monitor numerous hosts using ICMP ECHO_REQUEST.
- [vixl44](https://github.com/sebashwa/vixl44) lets you create pixel art inside your terminal using vim movements
- [zterm](https://github.com/varunrau/zterm) is a typing game inspired by http://zty.pe/
### API reference
[godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go)

View File

@ -8,6 +8,7 @@ import "os"
import "os/signal"
import "syscall"
import "runtime"
import "time"
// public API
@ -253,8 +254,8 @@ func CellBuffer() []Cell {
// NOTE: This API is experimental and may change in future.
func ParseEvent(data []byte) Event {
event := Event{Type: EventKey}
ok := extract_event(data, &event)
if !ok {
status := extract_event(data, &event, false)
if status != event_extracted {
return Event{Type: EventNone, N: event.N}
}
return event
@ -303,34 +304,65 @@ func PollRawEvent(data []byte) Event {
// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
// Constant governing macOS specific behavior. See https://github.com/nsf/termbox-go/issues/132
// This is an arbitrary delay which hopefully will be enough time for any lagging
// partial escape sequences to come through.
const esc_wait_delay = 100 * time.Millisecond
var event Event
var esc_wait_timer *time.Timer
var esc_timeout <-chan time.Time
// try to extract event from input buffer, return on success
event.Type = EventKey
ok := extract_event(inbuf, &event)
status := extract_event(inbuf, &event, true)
if event.N != 0 {
copy(inbuf, inbuf[event.N:])
inbuf = inbuf[:len(inbuf)-event.N]
}
if ok {
if status == event_extracted {
return event
} else if status == esc_wait {
esc_wait_timer = time.NewTimer(esc_wait_delay)
esc_timeout = esc_wait_timer.C
}
for {
select {
case ev := <-input_comm:
if esc_wait_timer != nil {
if !esc_wait_timer.Stop() {
<-esc_wait_timer.C
}
esc_wait_timer = nil
}
if ev.err != nil {
return Event{Type: EventError, Err: ev.err}
}
inbuf = append(inbuf, ev.data...)
input_comm <- ev
ok := extract_event(inbuf, &event)
status := extract_event(inbuf, &event, true)
if event.N != 0 {
copy(inbuf, inbuf[event.N:])
inbuf = inbuf[:len(inbuf)-event.N]
}
if ok {
if status == event_extracted {
return event
} else if status == esc_wait {
esc_wait_timer = time.NewTimer(esc_wait_delay)
esc_timeout = esc_wait_timer.C
}
case <-esc_timeout:
esc_wait_timer = nil
status := extract_event(inbuf, &event, false)
if event.N != 0 {
copy(inbuf, inbuf[event.N:])
inbuf = inbuf[:len(inbuf)-event.N]
}
if status == event_extracted {
return event
}
case <-interrupt_comm:
@ -418,12 +450,12 @@ func SetInputMode(mode InputMode) InputMode {
//
// 3. Output216 => [1..216]
// This mode supports the 3rd range of the 256 mode only.
// But you dont need to provide an offset.
// But you don't need to provide an offset.
//
// 4. OutputGrayscale => [1..26]
// This mode supports the 4th range of the 256 mode
// and black and white colors from 3th range of the 256 mode
// But you dont need to provide an offset.
// But you don't need to provide an offset.
//
// In all modes, 0x00 represents the default color.
//

View File

@ -148,7 +148,7 @@ const (
// using bitwise OR ('|'). Although, colors cannot be combined. But you can
// combine attributes and a single color.
//
// It's worth mentioning that some platforms don't support certain attibutes.
// It's worth mentioning that some platforms don't support certain attributes.
// For example windows console doesn't support AttrUnderline. And on some
// terminals applying AttrBold to background may result in blinking text. Use
// them with caution and test your code on various terminals.

11
vendor/github.com/nsf/termbox-go/escwait.go generated vendored Normal file
View File

@ -0,0 +1,11 @@
// +build !darwin
package termbox
// On all systems other than macOS, disable behavior which will wait before
// deciding that the escape key was pressed, to account for partially send
// escape sequences, especially with regard to lengthy mouse sequences.
// See https://github.com/nsf/termbox-go/issues/132
func enable_wait_for_escape_sequence() bool {
return false
}

9
vendor/github.com/nsf/termbox-go/escwait_darwin.go generated vendored Normal file
View File

@ -0,0 +1,9 @@
package termbox
// On macOS, enable behavior which will wait before deciding that the escape
// key was pressed, to account for partially send escape sequences, especially
// with regard to lengthy mouse sequences.
// See https://github.com/nsf/termbox-go/issues/132
func enable_wait_for_escape_sequence() bool {
return true
}

View File

@ -41,6 +41,14 @@ type input_event struct {
err error
}
type extract_event_res int
const (
event_not_extracted extract_event_res = iota
event_extracted
esc_wait
)
var (
// term specific sequences
keys []string
@ -417,7 +425,7 @@ func parse_escape_sequence(event *Event, buf []byte) (int, bool) {
}
}
// if none of the keys match, let's try mouse seqences
// if none of the keys match, let's try mouse sequences
return parse_mouse_event(event, bufstr)
}
@ -440,17 +448,27 @@ func extract_raw_event(data []byte, event *Event) bool {
return true
}
func extract_event(inbuf []byte, event *Event) bool {
func extract_event(inbuf []byte, event *Event, allow_esc_wait bool) extract_event_res {
if len(inbuf) == 0 {
event.N = 0
return false
return event_not_extracted
}
if inbuf[0] == '\033' {
// possible escape sequence
if n, ok := parse_escape_sequence(event, inbuf); n != 0 {
event.N = n
return ok
if ok {
return event_extracted
} else {
return event_not_extracted
}
}
// possible partially read escape sequence; trigger a wait if appropriate
if enable_wait_for_escape_sequence() && allow_esc_wait {
event.N = 0
return esc_wait
}
// it's not escape sequence, then it's Alt or Esc, check input_mode
@ -461,17 +479,17 @@ func extract_event(inbuf []byte, event *Event) bool {
event.Key = KeyEsc
event.Mod = 0
event.N = 1
return true
return event_extracted
case input_mode&InputAlt != 0:
// if we're in alt mode, set Alt modifier to event and redo parsing
event.Mod = ModAlt
ok := extract_event(inbuf[1:], event)
if ok {
status := extract_event(inbuf[1:], event, false)
if status == event_extracted {
event.N++
} else {
event.N = 0
}
return ok
return status
default:
panic("unreachable")
}
@ -486,7 +504,7 @@ func extract_event(inbuf []byte, event *Event) bool {
event.Ch = 0
event.Key = Key(inbuf[0])
event.N = 1
return true
return event_extracted
}
// the only possible option is utf8 rune
@ -494,10 +512,10 @@ func extract_event(inbuf []byte, event *Event) bool {
event.Ch = r
event.Key = 0
event.N = n
return true
return event_extracted
}
return false
return event_not_extracted
}
func fcntl(fd int, cmd int, arg int) (val int, err error) {

View File

@ -63,6 +63,8 @@ const (
mouse_lmb = 0x1
mouse_rmb = 0x2
mouse_mmb = 0x4 | 0x8 | 0x10
SM_CXMIN = 28
SM_CYMIN = 29
)
func (this coord) uintptr() uintptr {
@ -70,6 +72,7 @@ func (this coord) uintptr() uintptr {
}
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var moduser32 = syscall.NewLazyDLL("user32.dll")
var is_cjk = runewidth.IsEastAsian()
var (
@ -91,6 +94,7 @@ var (
proc_create_event = kernel32.NewProc("CreateEventW")
proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects")
proc_set_event = kernel32.NewProc("SetEvent")
get_system_metrics = moduser32.NewProc("GetSystemMetrics")
)
func set_console_active_screen_buffer(h syscall.Handle) (err error) {
@ -397,15 +401,44 @@ func get_term_size(out syscall.Handle) coord {
return tmp_info.size
}
func get_win_min_size(out syscall.Handle) coord {
x, _, err := get_system_metrics.Call(SM_CXMIN)
y, _, err := get_system_metrics.Call(SM_CYMIN)
if x == 0 || y == 0 {
if err != nil {
panic(err)
}
}
return coord{
x: short(x),
y: short(y),
}
}
func get_win_size(out syscall.Handle) coord {
err := get_console_screen_buffer_info(out, &tmp_info)
if err != nil {
panic(err)
}
return coord{
min_size := get_win_min_size(out)
size := coord{
x: tmp_info.window.right - tmp_info.window.left + 1,
y: tmp_info.window.bottom - tmp_info.window.top + 1,
}
if size.x < min_size.x {
size.x = min_size.x
}
if size.y < min_size.y {
size.y = min_size.y
}
return size
}
func update_size_maybe() {