1
mirror of https://github.com/rclone/rclone synced 2024-11-26 04:07:22 +01:00

vendor: github.com/nsf/termbox-go and dependencies for rclone ncdu

This commit is contained in:
Nick Craig-Wood 2017-06-15 12:40:39 +01:00
parent e069fc439e
commit e31fc877e2
37 changed files with 6388 additions and 1 deletions

14
Gopkg.lock generated
View File

@ -97,6 +97,12 @@
packages = ["."]
revision = "2788f0dbd16903de03cb8186e5c7d97b69ad387b"
[[projects]]
name = "github.com/mattn/go-runewidth"
packages = ["."]
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
version = "v0.0.2"
[[projects]]
branch = "master"
name = "github.com/ncw/dropbox-sdk-go-unofficial"
@ -115,6 +121,12 @@
packages = ["."]
revision = "8e9b10220613abdbc2896808ee6b43e411a4fa6c"
[[projects]]
branch = "master"
name = "github.com/nsf/termbox-go"
packages = ["."]
revision = "4163cd39dda1c0dda883a713640bc01e08951c24"
[[projects]]
branch = "master"
name = "github.com/pkg/errors"
@ -250,6 +262,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "e0227ed773a9f6c56d1bfac9de1d87c2a74ce142e418b661b74931d2e2b20945"
inputs-digest = "0d9d9076ed37a1be89629d9d43c5291394ed374e91c775ce3993d354e1e74a25"
solver-name = "gps-cdcl"
solver-version = 1

8
vendor/github.com/mattn/go-runewidth/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,8 @@
language: go
go:
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL

21
vendor/github.com/mattn/go-runewidth/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Yasuhiro Matsumoto
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

27
vendor/github.com/mattn/go-runewidth/README.mkd generated vendored Normal file
View File

@ -0,0 +1,27 @@
go-runewidth
============
[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth)
[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD)
[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)
[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth)
Provides functions to get fixed width of the character or string.
Usage
-----
```go
runewidth.StringWidth("つのだ☆HIRO") == 12
```
Author
------
Yasuhiro Matsumoto
License
-------
under the MIT License: http://mattn.mit-license.org/2013

1223
vendor/github.com/mattn/go-runewidth/runewidth.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

8
vendor/github.com/mattn/go-runewidth/runewidth_js.go generated vendored Normal file
View File

@ -0,0 +1,8 @@
// +build js
package runewidth
func IsEastAsian() bool {
// TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
return false
}

View File

@ -0,0 +1,77 @@
// +build !windows,!js
package runewidth
import (
"os"
"regexp"
"strings"
)
var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
var mblenTable = map[string]int{
"utf-8": 6,
"utf8": 6,
"jis": 8,
"eucjp": 3,
"euckr": 2,
"euccn": 2,
"sjis": 2,
"cp932": 2,
"cp51932": 2,
"cp936": 2,
"cp949": 2,
"cp950": 2,
"big5": 2,
"gbk": 2,
"gb2312": 2,
}
func isEastAsian(locale string) bool {
charset := strings.ToLower(locale)
r := reLoc.FindStringSubmatch(locale)
if len(r) == 2 {
charset = strings.ToLower(r[1])
}
if strings.HasSuffix(charset, "@cjk_narrow") {
return false
}
for pos, b := range []byte(charset) {
if b == '@' {
charset = charset[:pos]
break
}
}
max := 1
if m, ok := mblenTable[charset]; ok {
max = m
}
if max > 1 && (charset[0] != 'u' ||
strings.HasPrefix(locale, "ja") ||
strings.HasPrefix(locale, "ko") ||
strings.HasPrefix(locale, "zh")) {
return true
}
return false
}
// IsEastAsian return true if the current locale is CJK
func IsEastAsian() bool {
locale := os.Getenv("LC_CTYPE")
if locale == "" {
locale = os.Getenv("LANG")
}
// ignore C locale
if locale == "POSIX" || locale == "C" {
return false
}
if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
return false
}
return isEastAsian(locale)
}

275
vendor/github.com/mattn/go-runewidth/runewidth_test.go generated vendored Normal file
View File

@ -0,0 +1,275 @@
package runewidth
import (
"sort"
"testing"
)
var _ sort.Interface = (*table)(nil)
func (t table) Len() int {
return len(t)
}
func (t table) Less(i, j int) bool {
return t[i].first < t[j].first
}
func (t *table) Swap(i, j int) {
(*t)[i], (*t)[j] = (*t)[j], (*t)[i]
}
var tables = []table{
private,
nonprint,
combining,
doublewidth,
ambiguous,
emoji,
notassigned,
neutral,
}
func TestSorted(t *testing.T) {
for _, tbl := range tables {
if !sort.IsSorted(&tbl) {
t.Errorf("not sorted")
}
}
}
var runewidthtests = []struct {
in rune
out int
eaout int
}{
{'世', 2, 2},
{'界', 2, 2},
{'セ', 1, 1},
{'カ', 1, 1},
{'イ', 1, 1},
{'☆', 1, 2}, // double width in ambiguous
{'\x00', 0, 0},
{'\x01', 0, 0},
{'\u0300', 0, 0},
}
func TestRuneWidth(t *testing.T) {
c := NewCondition()
for _, tt := range runewidthtests {
if out := c.RuneWidth(tt.in); out != tt.out {
t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.out)
}
}
c.EastAsianWidth = true
for _, tt := range runewidthtests {
if out := c.RuneWidth(tt.in); out != tt.eaout {
t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.eaout)
}
}
}
var isambiguouswidthtests = []struct {
in rune
out bool
}{
{'世', false},
{'■', true},
{'界', false},
{'○', true},
{'㈱', false},
{'①', true},
{'②', true},
{'③', true},
{'④', true},
{'⑤', true},
{'⑥', true},
{'⑦', true},
{'⑧', true},
{'⑨', true},
{'⑩', true},
{'⑪', true},
{'⑫', true},
{'⑬', true},
{'⑭', true},
{'⑮', true},
{'⑯', true},
{'⑰', true},
{'⑱', true},
{'⑲', true},
{'⑳', true},
{'☆', true},
}
func TestIsAmbiguousWidth(t *testing.T) {
for _, tt := range isambiguouswidthtests {
if out := IsAmbiguousWidth(tt.in); out != tt.out {
t.Errorf("IsAmbiguousWidth(%q) = %v, want %v", tt.in, out, tt.out)
}
}
}
var stringwidthtests = []struct {
in string
out int
eaout int
}{
{"■㈱の世界①", 10, 12},
{"スター☆", 7, 8},
{"つのだ☆HIRO", 11, 12},
}
func TestStringWidth(t *testing.T) {
c := NewCondition()
for _, tt := range stringwidthtests {
if out := c.StringWidth(tt.in); out != tt.out {
t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.out)
}
}
c.EastAsianWidth = true
for _, tt := range stringwidthtests {
if out := c.StringWidth(tt.in); out != tt.eaout {
t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.eaout)
}
}
}
func TestStringWidthInvalid(t *testing.T) {
s := "こんにちわ\x00世界"
if out := StringWidth(s); out != 14 {
t.Errorf("StringWidth(%q) = %q, want %q", s, out, 14)
}
}
func TestTruncateSmaller(t *testing.T) {
s := "あいうえお"
expected := "あいうえお"
if out := Truncate(s, 10, "..."); out != expected {
t.Errorf("Truncate(%q) = %q, want %q", s, out, expected)
}
}
func TestTruncate(t *testing.T) {
s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお"
expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..."
out := Truncate(s, 80, "...")
if out != expected {
t.Errorf("Truncate(%q) = %q, want %q", s, out, expected)
}
width := StringWidth(out)
if width != 79 {
t.Errorf("width of Truncate(%q) should be %d, but %d", s, 79, width)
}
}
func TestTruncateFit(t *testing.T) {
s := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお"
expected := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..."
out := Truncate(s, 80, "...")
if out != expected {
t.Errorf("Truncate(%q) = %q, want %q", s, out, expected)
}
width := StringWidth(out)
if width != 80 {
t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width)
}
}
func TestTruncateJustFit(t *testing.T) {
s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお"
expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお"
out := Truncate(s, 80, "...")
if out != expected {
t.Errorf("Truncate(%q) = %q, want %q", s, out, expected)
}
width := StringWidth(out)
if width != 80 {
t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width)
}
}
func TestWrap(t *testing.T) {
s := `東京特許許可局局長はよく柿喰う客だ/東京特許許可局局長はよく柿喰う客だ
123456789012345678901234567890
END`
expected := `東京特許許可局局長はよく柿喰う
客だ/東京特許許可局局長はよく
柿喰う客だ
123456789012345678901234567890
END`
if out := Wrap(s, 30); out != expected {
t.Errorf("Wrap(%q) = %q, want %q", s, out, expected)
}
}
func TestTruncateNoNeeded(t *testing.T) {
s := "あいうえおあい"
expected := "あいうえおあい"
if out := Truncate(s, 80, "..."); out != expected {
t.Errorf("Truncate(%q) = %q, want %q", s, out, expected)
}
}
var isneutralwidthtests = []struct {
in rune
out bool
}{
{'→', false},
{'┊', false},
{'┈', false},
{'', false},
{'└', false},
{'⣀', true},
{'⣀', true},
}
func TestIsNeutralWidth(t *testing.T) {
for _, tt := range isneutralwidthtests {
if out := IsNeutralWidth(tt.in); out != tt.out {
t.Errorf("IsNeutralWidth(%q) = %v, want %v", tt.in, out, tt.out)
}
}
}
func TestFillLeft(t *testing.T) {
s := "あxいうえお"
expected := " あxいうえお"
if out := FillLeft(s, 15); out != expected {
t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected)
}
}
func TestFillLeftFit(t *testing.T) {
s := "あいうえお"
expected := "あいうえお"
if out := FillLeft(s, 10); out != expected {
t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected)
}
}
func TestFillRight(t *testing.T) {
s := "あxいうえお"
expected := "あxいうえお "
if out := FillRight(s, 15); out != expected {
t.Errorf("FillRight(%q) = %q, want %q", s, out, expected)
}
}
func TestFillRightFit(t *testing.T) {
s := "あいうえお"
expected := "あいうえお"
if out := FillRight(s, 10); out != expected {
t.Errorf("FillRight(%q) = %q, want %q", s, out, expected)
}
}

View File

@ -0,0 +1,25 @@
package runewidth
import (
"syscall"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32")
procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
)
// IsEastAsian return true if the current locale is CJK
func IsEastAsian() bool {
r1, _, _ := procGetConsoleOutputCP.Call()
if r1 == 0 {
return false
}
switch int(r1) {
case 932, 51932, 936, 949, 950:
return true
}
return false
}

4
vendor/github.com/nsf/termbox-go/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,4 @@
# Please keep this file sorted.
Georg Reinke <guelfey@googlemail.com>
nsf <no.smile.face@gmail.com>

19
vendor/github.com/nsf/termbox-go/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (C) 2012 termbox-go authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

35
vendor/github.com/nsf/termbox-go/README.md generated vendored Normal file
View File

@ -0,0 +1,35 @@
## Termbox
Termbox is a library that provides a minimalistic API which allows the programmer to write text-based user interfaces. The library is crossplatform and has both terminal-based implementations on *nix operating systems and a winapi console based implementation for windows operating systems. The basic idea is an abstraction of the greatest common subset of features available on all major terminals and other terminal-like APIs in a minimalistic fashion. Small API means it is easy to implement, test, maintain and learn it, that's what makes the termbox a distinct library in its area.
### Installation
Install and update this go package with `go get -u github.com/nsf/termbox-go`
### Examples
For examples of what can be done take a look at demos in the _demos directory. You can try them with go run: `go run _demos/keyboard.go`
There are also some interesting projects using termbox-go:
- [godit](https://github.com/nsf/godit) is an emacsish lightweight text editor written using termbox.
- [gomatrix](https://github.com/GeertJohan/gomatrix) connects to The Matrix and displays its data streams in your terminal.
- [gotetris](https://github.com/jjinux/gotetris) is an implementation of Tetris.
- [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.
- [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.
- [gocui](https://github.com/jroimartin/gocui) is a minimalist Go library aimed at creating console user interfaces.
- [dry](https://github.com/moncho/dry) is an interactive cli to manage Docker containers.
- [pxl](https://github.com/ichinaski/pxl) displays images in the terminal.
- [snake-game](https://github.com/DyegoCosta/snake-game) is an implementation of the Snake game.
- [gone](https://github.com/guillaumebreton/gone) is a CLI pomodoro® timer.
- [Spoof.go](https://github.com/sabey/spoofgo) controllable movement spoofing from the cli
- [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
### API reference
[godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go)

300
vendor/github.com/nsf/termbox-go/_demos/editbox.go generated vendored Normal file
View File

@ -0,0 +1,300 @@
package main
import (
"github.com/mattn/go-runewidth"
"github.com/nsf/termbox-go"
"unicode/utf8"
)
func tbprint(x, y int, fg, bg termbox.Attribute, msg string) {
for _, c := range msg {
termbox.SetCell(x, y, c, fg, bg)
x += runewidth.RuneWidth(c)
}
}
func fill(x, y, w, h int, cell termbox.Cell) {
for ly := 0; ly < h; ly++ {
for lx := 0; lx < w; lx++ {
termbox.SetCell(x+lx, y+ly, cell.Ch, cell.Fg, cell.Bg)
}
}
}
func rune_advance_len(r rune, pos int) int {
if r == '\t' {
return tabstop_length - pos%tabstop_length
}
return runewidth.RuneWidth(r)
}
func voffset_coffset(text []byte, boffset int) (voffset, coffset int) {
text = text[:boffset]
for len(text) > 0 {
r, size := utf8.DecodeRune(text)
text = text[size:]
coffset += 1
voffset += rune_advance_len(r, voffset)
}
return
}
func byte_slice_grow(s []byte, desired_cap int) []byte {
if cap(s) < desired_cap {
ns := make([]byte, len(s), desired_cap)
copy(ns, s)
return ns
}
return s
}
func byte_slice_remove(text []byte, from, to int) []byte {
size := to - from
copy(text[from:], text[to:])
text = text[:len(text)-size]
return text
}
func byte_slice_insert(text []byte, offset int, what []byte) []byte {
n := len(text) + len(what)
text = byte_slice_grow(text, n)
text = text[:n]
copy(text[offset+len(what):], text[offset:])
copy(text[offset:], what)
return text
}
const preferred_horizontal_threshold = 5
const tabstop_length = 8
type EditBox struct {
text []byte
line_voffset int
cursor_boffset int // cursor offset in bytes
cursor_voffset int // visual cursor offset in termbox cells
cursor_coffset int // cursor offset in unicode code points
}
// Draws the EditBox in the given location, 'h' is not used at the moment
func (eb *EditBox) Draw(x, y, w, h int) {
eb.AdjustVOffset(w)
const coldef = termbox.ColorDefault
fill(x, y, w, h, termbox.Cell{Ch: ' '})
t := eb.text
lx := 0
tabstop := 0
for {
rx := lx - eb.line_voffset
if len(t) == 0 {
break
}
if lx == tabstop {
tabstop += tabstop_length
}
if rx >= w {
termbox.SetCell(x+w-1, y, '→',
coldef, coldef)
break
}
r, size := utf8.DecodeRune(t)
if r == '\t' {
for ; lx < tabstop; lx++ {
rx = lx - eb.line_voffset
if rx >= w {
goto next
}
if rx >= 0 {
termbox.SetCell(x+rx, y, ' ', coldef, coldef)
}
}
} else {
if rx >= 0 {
termbox.SetCell(x+rx, y, r, coldef, coldef)
}
lx += runewidth.RuneWidth(r)
}
next:
t = t[size:]
}
if eb.line_voffset != 0 {
termbox.SetCell(x, y, '←', coldef, coldef)
}
}
// Adjusts line visual offset to a proper value depending on width
func (eb *EditBox) AdjustVOffset(width int) {
ht := preferred_horizontal_threshold
max_h_threshold := (width - 1) / 2
if ht > max_h_threshold {
ht = max_h_threshold
}
threshold := width - 1
if eb.line_voffset != 0 {
threshold = width - ht
}
if eb.cursor_voffset-eb.line_voffset >= threshold {
eb.line_voffset = eb.cursor_voffset + (ht - width + 1)
}
if eb.line_voffset != 0 && eb.cursor_voffset-eb.line_voffset < ht {
eb.line_voffset = eb.cursor_voffset - ht
if eb.line_voffset < 0 {
eb.line_voffset = 0
}
}
}
func (eb *EditBox) MoveCursorTo(boffset int) {
eb.cursor_boffset = boffset
eb.cursor_voffset, eb.cursor_coffset = voffset_coffset(eb.text, boffset)
}
func (eb *EditBox) RuneUnderCursor() (rune, int) {
return utf8.DecodeRune(eb.text[eb.cursor_boffset:])
}
func (eb *EditBox) RuneBeforeCursor() (rune, int) {
return utf8.DecodeLastRune(eb.text[:eb.cursor_boffset])
}
func (eb *EditBox) MoveCursorOneRuneBackward() {
if eb.cursor_boffset == 0 {
return
}
_, size := eb.RuneBeforeCursor()
eb.MoveCursorTo(eb.cursor_boffset - size)
}
func (eb *EditBox) MoveCursorOneRuneForward() {
if eb.cursor_boffset == len(eb.text) {
return
}
_, size := eb.RuneUnderCursor()
eb.MoveCursorTo(eb.cursor_boffset + size)
}
func (eb *EditBox) MoveCursorToBeginningOfTheLine() {
eb.MoveCursorTo(0)
}
func (eb *EditBox) MoveCursorToEndOfTheLine() {
eb.MoveCursorTo(len(eb.text))
}
func (eb *EditBox) DeleteRuneBackward() {
if eb.cursor_boffset == 0 {
return
}
eb.MoveCursorOneRuneBackward()
_, size := eb.RuneUnderCursor()
eb.text = byte_slice_remove(eb.text, eb.cursor_boffset, eb.cursor_boffset+size)
}
func (eb *EditBox) DeleteRuneForward() {
if eb.cursor_boffset == len(eb.text) {
return
}
_, size := eb.RuneUnderCursor()
eb.text = byte_slice_remove(eb.text, eb.cursor_boffset, eb.cursor_boffset+size)
}
func (eb *EditBox) DeleteTheRestOfTheLine() {
eb.text = eb.text[:eb.cursor_boffset]
}
func (eb *EditBox) InsertRune(r rune) {
var buf [utf8.UTFMax]byte
n := utf8.EncodeRune(buf[:], r)
eb.text = byte_slice_insert(eb.text, eb.cursor_boffset, buf[:n])
eb.MoveCursorOneRuneForward()
}
// Please, keep in mind that cursor depends on the value of line_voffset, which
// is being set on Draw() call, so.. call this method after Draw() one.
func (eb *EditBox) CursorX() int {
return eb.cursor_voffset - eb.line_voffset
}
var edit_box EditBox
const edit_box_width = 30
func redraw_all() {
const coldef = termbox.ColorDefault
termbox.Clear(coldef, coldef)
w, h := termbox.Size()
midy := h / 2
midx := (w - edit_box_width) / 2
// unicode box drawing chars around the edit box
termbox.SetCell(midx-1, midy, '│', coldef, coldef)
termbox.SetCell(midx+edit_box_width, midy, '│', coldef, coldef)
termbox.SetCell(midx-1, midy-1, '┌', coldef, coldef)
termbox.SetCell(midx-1, midy+1, '└', coldef, coldef)
termbox.SetCell(midx+edit_box_width, midy-1, '┐', coldef, coldef)
termbox.SetCell(midx+edit_box_width, midy+1, '┘', coldef, coldef)
fill(midx, midy-1, edit_box_width, 1, termbox.Cell{Ch: '─'})
fill(midx, midy+1, edit_box_width, 1, termbox.Cell{Ch: '─'})
edit_box.Draw(midx, midy, edit_box_width, 1)
termbox.SetCursor(midx+edit_box.CursorX(), midy)
tbprint(midx+6, midy+3, coldef, coldef, "Press ESC to quit")
termbox.Flush()
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
termbox.SetInputMode(termbox.InputEsc)
redraw_all()
mainloop:
for {
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
switch ev.Key {
case termbox.KeyEsc:
break mainloop
case termbox.KeyArrowLeft, termbox.KeyCtrlB:
edit_box.MoveCursorOneRuneBackward()
case termbox.KeyArrowRight, termbox.KeyCtrlF:
edit_box.MoveCursorOneRuneForward()
case termbox.KeyBackspace, termbox.KeyBackspace2:
edit_box.DeleteRuneBackward()
case termbox.KeyDelete, termbox.KeyCtrlD:
edit_box.DeleteRuneForward()
case termbox.KeyTab:
edit_box.InsertRune('\t')
case termbox.KeySpace:
edit_box.InsertRune(' ')
case termbox.KeyCtrlK:
edit_box.DeleteTheRestOfTheLine()
case termbox.KeyHome, termbox.KeyCtrlA:
edit_box.MoveCursorToBeginningOfTheLine()
case termbox.KeyEnd, termbox.KeyCtrlE:
edit_box.MoveCursorToEndOfTheLine()
default:
if ev.Ch != 0 {
edit_box.InsertRune(ev.Ch)
}
}
case termbox.EventError:
panic(ev.Err)
}
redraw_all()
}
}

69
vendor/github.com/nsf/termbox-go/_demos/interrupt.go generated vendored Normal file
View File

@ -0,0 +1,69 @@
package main
import (
"fmt"
"github.com/nsf/termbox-go"
"time"
)
func tbPrint(x, y int, fg, bg termbox.Attribute, msg string) {
for _, c := range msg {
termbox.SetCell(x, y, c, fg, bg)
x++
}
}
func draw(i int) {
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
defer termbox.Flush()
w, h := termbox.Size()
s := fmt.Sprintf("count = %d", i)
tbPrint((w/2)-(len(s)/2), h/2, termbox.ColorRed, termbox.ColorDefault, s)
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
termbox.SetInputMode(termbox.InputEsc)
go func() {
time.Sleep(5 * time.Second)
termbox.Interrupt()
// This should never run - the Interrupt(), above, should cause the event
// loop below to exit, which then exits the process. If something goes
// wrong, this panic will trigger and show what happened.
time.Sleep(1 * time.Second)
panic("this should never run")
}()
var count int
draw(count)
mainloop:
for {
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
if ev.Ch == '+' {
count++
} else if ev.Ch == '-' {
count--
}
case termbox.EventError:
panic(ev.Err)
case termbox.EventInterrupt:
break mainloop
}
draw(count)
}
termbox.Close()
fmt.Println("Finished")
}

722
vendor/github.com/nsf/termbox-go/_demos/keyboard.go generated vendored Normal file
View File

@ -0,0 +1,722 @@
package main
import "github.com/nsf/termbox-go"
import "fmt"
type key struct {
x int
y int
ch rune
}
var K_ESC = []key{{1, 1, 'E'}, {2, 1, 'S'}, {3, 1, 'C'}}
var K_F1 = []key{{6, 1, 'F'}, {7, 1, '1'}}
var K_F2 = []key{{9, 1, 'F'}, {10, 1, '2'}}
var K_F3 = []key{{12, 1, 'F'}, {13, 1, '3'}}
var K_F4 = []key{{15, 1, 'F'}, {16, 1, '4'}}
var K_F5 = []key{{19, 1, 'F'}, {20, 1, '5'}}
var K_F6 = []key{{22, 1, 'F'}, {23, 1, '6'}}
var K_F7 = []key{{25, 1, 'F'}, {26, 1, '7'}}
var K_F8 = []key{{28, 1, 'F'}, {29, 1, '8'}}
var K_F9 = []key{{33, 1, 'F'}, {34, 1, '9'}}
var K_F10 = []key{{36, 1, 'F'}, {37, 1, '1'}, {38, 1, '0'}}
var K_F11 = []key{{40, 1, 'F'}, {41, 1, '1'}, {42, 1, '1'}}
var K_F12 = []key{{44, 1, 'F'}, {45, 1, '1'}, {46, 1, '2'}}
var K_PRN = []key{{50, 1, 'P'}, {51, 1, 'R'}, {52, 1, 'N'}}
var K_SCR = []key{{54, 1, 'S'}, {55, 1, 'C'}, {56, 1, 'R'}}
var K_BRK = []key{{58, 1, 'B'}, {59, 1, 'R'}, {60, 1, 'K'}}
var K_LED1 = []key{{66, 1, '-'}}
var K_LED2 = []key{{70, 1, '-'}}
var K_LED3 = []key{{74, 1, '-'}}
var K_TILDE = []key{{1, 4, '`'}}
var K_TILDE_SHIFT = []key{{1, 4, '~'}}
var K_1 = []key{{4, 4, '1'}}
var K_1_SHIFT = []key{{4, 4, '!'}}
var K_2 = []key{{7, 4, '2'}}
var K_2_SHIFT = []key{{7, 4, '@'}}
var K_3 = []key{{10, 4, '3'}}
var K_3_SHIFT = []key{{10, 4, '#'}}
var K_4 = []key{{13, 4, '4'}}
var K_4_SHIFT = []key{{13, 4, '$'}}
var K_5 = []key{{16, 4, '5'}}
var K_5_SHIFT = []key{{16, 4, '%'}}
var K_6 = []key{{19, 4, '6'}}
var K_6_SHIFT = []key{{19, 4, '^'}}
var K_7 = []key{{22, 4, '7'}}
var K_7_SHIFT = []key{{22, 4, '&'}}
var K_8 = []key{{25, 4, '8'}}
var K_8_SHIFT = []key{{25, 4, '*'}}
var K_9 = []key{{28, 4, '9'}}
var K_9_SHIFT = []key{{28, 4, '('}}
var K_0 = []key{{31, 4, '0'}}
var K_0_SHIFT = []key{{31, 4, ')'}}
var K_MINUS = []key{{34, 4, '-'}}
var K_MINUS_SHIFT = []key{{34, 4, '_'}}
var K_EQUALS = []key{{37, 4, '='}}
var K_EQUALS_SHIFT = []key{{37, 4, '+'}}
var K_BACKSLASH = []key{{40, 4, '\\'}}
var K_BACKSLASH_SHIFT = []key{{40, 4, '|'}}
var K_BACKSPACE = []key{{44, 4, 0x2190}, {45, 4, 0x2500}, {46, 4, 0x2500}}
var K_INS = []key{{50, 4, 'I'}, {51, 4, 'N'}, {52, 4, 'S'}}
var K_HOM = []key{{54, 4, 'H'}, {55, 4, 'O'}, {56, 4, 'M'}}
var K_PGU = []key{{58, 4, 'P'}, {59, 4, 'G'}, {60, 4, 'U'}}
var K_K_NUMLOCK = []key{{65, 4, 'N'}}
var K_K_SLASH = []key{{68, 4, '/'}}
var K_K_STAR = []key{{71, 4, '*'}}
var K_K_MINUS = []key{{74, 4, '-'}}
var K_TAB = []key{{1, 6, 'T'}, {2, 6, 'A'}, {3, 6, 'B'}}
var K_q = []key{{6, 6, 'q'}}
var K_Q = []key{{6, 6, 'Q'}}
var K_w = []key{{9, 6, 'w'}}
var K_W = []key{{9, 6, 'W'}}
var K_e = []key{{12, 6, 'e'}}
var K_E = []key{{12, 6, 'E'}}
var K_r = []key{{15, 6, 'r'}}
var K_R = []key{{15, 6, 'R'}}
var K_t = []key{{18, 6, 't'}}
var K_T = []key{{18, 6, 'T'}}
var K_y = []key{{21, 6, 'y'}}
var K_Y = []key{{21, 6, 'Y'}}
var K_u = []key{{24, 6, 'u'}}
var K_U = []key{{24, 6, 'U'}}
var K_i = []key{{27, 6, 'i'}}
var K_I = []key{{27, 6, 'I'}}
var K_o = []key{{30, 6, 'o'}}
var K_O = []key{{30, 6, 'O'}}
var K_p = []key{{33, 6, 'p'}}
var K_P = []key{{33, 6, 'P'}}
var K_LSQB = []key{{36, 6, '['}}
var K_LCUB = []key{{36, 6, '{'}}
var K_RSQB = []key{{39, 6, ']'}}
var K_RCUB = []key{{39, 6, '}'}}
var K_ENTER = []key{
{43, 6, 0x2591}, {44, 6, 0x2591}, {45, 6, 0x2591}, {46, 6, 0x2591},
{43, 7, 0x2591}, {44, 7, 0x2591}, {45, 7, 0x21B5}, {46, 7, 0x2591},
{41, 8, 0x2591}, {42, 8, 0x2591}, {43, 8, 0x2591}, {44, 8, 0x2591},
{45, 8, 0x2591}, {46, 8, 0x2591},
}
var K_DEL = []key{{50, 6, 'D'}, {51, 6, 'E'}, {52, 6, 'L'}}
var K_END = []key{{54, 6, 'E'}, {55, 6, 'N'}, {56, 6, 'D'}}
var K_PGD = []key{{58, 6, 'P'}, {59, 6, 'G'}, {60, 6, 'D'}}
var K_K_7 = []key{{65, 6, '7'}}
var K_K_8 = []key{{68, 6, '8'}}
var K_K_9 = []key{{71, 6, '9'}}
var K_K_PLUS = []key{{74, 6, ' '}, {74, 7, '+'}, {74, 8, ' '}}
var K_CAPS = []key{{1, 8, 'C'}, {2, 8, 'A'}, {3, 8, 'P'}, {4, 8, 'S'}}
var K_a = []key{{7, 8, 'a'}}
var K_A = []key{{7, 8, 'A'}}
var K_s = []key{{10, 8, 's'}}
var K_S = []key{{10, 8, 'S'}}
var K_d = []key{{13, 8, 'd'}}
var K_D = []key{{13, 8, 'D'}}
var K_f = []key{{16, 8, 'f'}}
var K_F = []key{{16, 8, 'F'}}
var K_g = []key{{19, 8, 'g'}}
var K_G = []key{{19, 8, 'G'}}
var K_h = []key{{22, 8, 'h'}}
var K_H = []key{{22, 8, 'H'}}
var K_j = []key{{25, 8, 'j'}}
var K_J = []key{{25, 8, 'J'}}
var K_k = []key{{28, 8, 'k'}}
var K_K = []key{{28, 8, 'K'}}
var K_l = []key{{31, 8, 'l'}}
var K_L = []key{{31, 8, 'L'}}
var K_SEMICOLON = []key{{34, 8, ';'}}
var K_PARENTHESIS = []key{{34, 8, ':'}}
var K_QUOTE = []key{{37, 8, '\''}}
var K_DOUBLEQUOTE = []key{{37, 8, '"'}}
var K_K_4 = []key{{65, 8, '4'}}
var K_K_5 = []key{{68, 8, '5'}}
var K_K_6 = []key{{71, 8, '6'}}
var K_LSHIFT = []key{{1, 10, 'S'}, {2, 10, 'H'}, {3, 10, 'I'}, {4, 10, 'F'}, {5, 10, 'T'}}
var K_z = []key{{9, 10, 'z'}}
var K_Z = []key{{9, 10, 'Z'}}
var K_x = []key{{12, 10, 'x'}}
var K_X = []key{{12, 10, 'X'}}
var K_c = []key{{15, 10, 'c'}}
var K_C = []key{{15, 10, 'C'}}
var K_v = []key{{18, 10, 'v'}}
var K_V = []key{{18, 10, 'V'}}
var K_b = []key{{21, 10, 'b'}}
var K_B = []key{{21, 10, 'B'}}
var K_n = []key{{24, 10, 'n'}}
var K_N = []key{{24, 10, 'N'}}
var K_m = []key{{27, 10, 'm'}}
var K_M = []key{{27, 10, 'M'}}
var K_COMMA = []key{{30, 10, ','}}
var K_LANB = []key{{30, 10, '<'}}
var K_PERIOD = []key{{33, 10, '.'}}
var K_RANB = []key{{33, 10, '>'}}
var K_SLASH = []key{{36, 10, '/'}}
var K_QUESTION = []key{{36, 10, '?'}}
var K_RSHIFT = []key{{42, 10, 'S'}, {43, 10, 'H'}, {44, 10, 'I'}, {45, 10, 'F'}, {46, 10, 'T'}}
var K_ARROW_UP = []key{{54, 10, '('}, {55, 10, 0x2191}, {56, 10, ')'}}
var K_K_1 = []key{{65, 10, '1'}}
var K_K_2 = []key{{68, 10, '2'}}
var K_K_3 = []key{{71, 10, '3'}}
var K_K_ENTER = []key{{74, 10, 0x2591}, {74, 11, 0x2591}, {74, 12, 0x2591}}
var K_LCTRL = []key{{1, 12, 'C'}, {2, 12, 'T'}, {3, 12, 'R'}, {4, 12, 'L'}}
var K_LWIN = []key{{6, 12, 'W'}, {7, 12, 'I'}, {8, 12, 'N'}}
var K_LALT = []key{{10, 12, 'A'}, {11, 12, 'L'}, {12, 12, 'T'}}
var K_SPACE = []key{
{14, 12, ' '}, {15, 12, ' '}, {16, 12, ' '}, {17, 12, ' '}, {18, 12, ' '},
{19, 12, 'S'}, {20, 12, 'P'}, {21, 12, 'A'}, {22, 12, 'C'}, {23, 12, 'E'},
{24, 12, ' '}, {25, 12, ' '}, {26, 12, ' '}, {27, 12, ' '}, {28, 12, ' '},
}
var K_RALT = []key{{30, 12, 'A'}, {31, 12, 'L'}, {32, 12, 'T'}}
var K_RWIN = []key{{34, 12, 'W'}, {35, 12, 'I'}, {36, 12, 'N'}}
var K_RPROP = []key{{38, 12, 'P'}, {39, 12, 'R'}, {40, 12, 'O'}, {41, 12, 'P'}}
var K_RCTRL = []key{{43, 12, 'C'}, {44, 12, 'T'}, {45, 12, 'R'}, {46, 12, 'L'}}
var K_ARROW_LEFT = []key{{50, 12, '('}, {51, 12, 0x2190}, {52, 12, ')'}}
var K_ARROW_DOWN = []key{{54, 12, '('}, {55, 12, 0x2193}, {56, 12, ')'}}
var K_ARROW_RIGHT = []key{{58, 12, '('}, {59, 12, 0x2192}, {60, 12, ')'}}
var K_K_0 = []key{{65, 12, ' '}, {66, 12, '0'}, {67, 12, ' '}, {68, 12, ' '}}
var K_K_PERIOD = []key{{71, 12, '.'}}
type combo struct {
keys [][]key
}
var combos = []combo{
{[][]key{K_TILDE, K_2, K_SPACE, K_LCTRL, K_RCTRL}},
{[][]key{K_A, K_LCTRL, K_RCTRL}},
{[][]key{K_B, K_LCTRL, K_RCTRL}},
{[][]key{K_C, K_LCTRL, K_RCTRL}},
{[][]key{K_D, K_LCTRL, K_RCTRL}},
{[][]key{K_E, K_LCTRL, K_RCTRL}},
{[][]key{K_F, K_LCTRL, K_RCTRL}},
{[][]key{K_G, K_LCTRL, K_RCTRL}},
{[][]key{K_H, K_BACKSPACE, K_LCTRL, K_RCTRL}},
{[][]key{K_I, K_TAB, K_LCTRL, K_RCTRL}},
{[][]key{K_J, K_LCTRL, K_RCTRL}},
{[][]key{K_K, K_LCTRL, K_RCTRL}},
{[][]key{K_L, K_LCTRL, K_RCTRL}},
{[][]key{K_M, K_ENTER, K_K_ENTER, K_LCTRL, K_RCTRL}},
{[][]key{K_N, K_LCTRL, K_RCTRL}},
{[][]key{K_O, K_LCTRL, K_RCTRL}},
{[][]key{K_P, K_LCTRL, K_RCTRL}},
{[][]key{K_Q, K_LCTRL, K_RCTRL}},
{[][]key{K_R, K_LCTRL, K_RCTRL}},
{[][]key{K_S, K_LCTRL, K_RCTRL}},
{[][]key{K_T, K_LCTRL, K_RCTRL}},
{[][]key{K_U, K_LCTRL, K_RCTRL}},
{[][]key{K_V, K_LCTRL, K_RCTRL}},
{[][]key{K_W, K_LCTRL, K_RCTRL}},
{[][]key{K_X, K_LCTRL, K_RCTRL}},
{[][]key{K_Y, K_LCTRL, K_RCTRL}},
{[][]key{K_Z, K_LCTRL, K_RCTRL}},
{[][]key{K_LSQB, K_ESC, K_3, K_LCTRL, K_RCTRL}},
{[][]key{K_4, K_BACKSLASH, K_LCTRL, K_RCTRL}},
{[][]key{K_RSQB, K_5, K_LCTRL, K_RCTRL}},
{[][]key{K_6, K_LCTRL, K_RCTRL}},
{[][]key{K_7, K_SLASH, K_MINUS_SHIFT, K_LCTRL, K_RCTRL}},
{[][]key{K_SPACE}},
{[][]key{K_1_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_DOUBLEQUOTE, K_LSHIFT, K_RSHIFT}},
{[][]key{K_3_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_4_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_5_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_7_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_QUOTE}},
{[][]key{K_9_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_0_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_8_SHIFT, K_K_STAR, K_LSHIFT, K_RSHIFT}},
{[][]key{K_EQUALS_SHIFT, K_K_PLUS, K_LSHIFT, K_RSHIFT}},
{[][]key{K_COMMA}},
{[][]key{K_MINUS, K_K_MINUS}},
{[][]key{K_PERIOD, K_K_PERIOD}},
{[][]key{K_SLASH, K_K_SLASH}},
{[][]key{K_0, K_K_0}},
{[][]key{K_1, K_K_1}},
{[][]key{K_2, K_K_2}},
{[][]key{K_3, K_K_3}},
{[][]key{K_4, K_K_4}},
{[][]key{K_5, K_K_5}},
{[][]key{K_6, K_K_6}},
{[][]key{K_7, K_K_7}},
{[][]key{K_8, K_K_8}},
{[][]key{K_9, K_K_9}},
{[][]key{K_PARENTHESIS, K_LSHIFT, K_RSHIFT}},
{[][]key{K_SEMICOLON}},
{[][]key{K_LANB, K_LSHIFT, K_RSHIFT}},
{[][]key{K_EQUALS}},
{[][]key{K_RANB, K_LSHIFT, K_RSHIFT}},
{[][]key{K_QUESTION, K_LSHIFT, K_RSHIFT}},
{[][]key{K_2_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_A, K_LSHIFT, K_RSHIFT}},
{[][]key{K_B, K_LSHIFT, K_RSHIFT}},
{[][]key{K_C, K_LSHIFT, K_RSHIFT}},
{[][]key{K_D, K_LSHIFT, K_RSHIFT}},
{[][]key{K_E, K_LSHIFT, K_RSHIFT}},
{[][]key{K_F, K_LSHIFT, K_RSHIFT}},
{[][]key{K_G, K_LSHIFT, K_RSHIFT}},
{[][]key{K_H, K_LSHIFT, K_RSHIFT}},
{[][]key{K_I, K_LSHIFT, K_RSHIFT}},
{[][]key{K_J, K_LSHIFT, K_RSHIFT}},
{[][]key{K_K, K_LSHIFT, K_RSHIFT}},
{[][]key{K_L, K_LSHIFT, K_RSHIFT}},
{[][]key{K_M, K_LSHIFT, K_RSHIFT}},
{[][]key{K_N, K_LSHIFT, K_RSHIFT}},
{[][]key{K_O, K_LSHIFT, K_RSHIFT}},
{[][]key{K_P, K_LSHIFT, K_RSHIFT}},
{[][]key{K_Q, K_LSHIFT, K_RSHIFT}},
{[][]key{K_R, K_LSHIFT, K_RSHIFT}},
{[][]key{K_S, K_LSHIFT, K_RSHIFT}},
{[][]key{K_T, K_LSHIFT, K_RSHIFT}},
{[][]key{K_U, K_LSHIFT, K_RSHIFT}},
{[][]key{K_V, K_LSHIFT, K_RSHIFT}},
{[][]key{K_W, K_LSHIFT, K_RSHIFT}},
{[][]key{K_X, K_LSHIFT, K_RSHIFT}},
{[][]key{K_Y, K_LSHIFT, K_RSHIFT}},
{[][]key{K_Z, K_LSHIFT, K_RSHIFT}},
{[][]key{K_LSQB}},
{[][]key{K_BACKSLASH}},
{[][]key{K_RSQB}},
{[][]key{K_6_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_MINUS_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_TILDE}},
{[][]key{K_a}},
{[][]key{K_b}},
{[][]key{K_c}},
{[][]key{K_d}},
{[][]key{K_e}},
{[][]key{K_f}},
{[][]key{K_g}},
{[][]key{K_h}},
{[][]key{K_i}},
{[][]key{K_j}},
{[][]key{K_k}},
{[][]key{K_l}},
{[][]key{K_m}},
{[][]key{K_n}},
{[][]key{K_o}},
{[][]key{K_p}},
{[][]key{K_q}},
{[][]key{K_r}},
{[][]key{K_s}},
{[][]key{K_t}},
{[][]key{K_u}},
{[][]key{K_v}},
{[][]key{K_w}},
{[][]key{K_x}},
{[][]key{K_y}},
{[][]key{K_z}},
{[][]key{K_LCUB, K_LSHIFT, K_RSHIFT}},
{[][]key{K_BACKSLASH_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_RCUB, K_LSHIFT, K_RSHIFT}},
{[][]key{K_TILDE_SHIFT, K_LSHIFT, K_RSHIFT}},
{[][]key{K_8, K_BACKSPACE, K_LCTRL, K_RCTRL}},
}
var func_combos = []combo{
{[][]key{K_F1}},
{[][]key{K_F2}},
{[][]key{K_F3}},
{[][]key{K_F4}},
{[][]key{K_F5}},
{[][]key{K_F6}},
{[][]key{K_F7}},
{[][]key{K_F8}},
{[][]key{K_F9}},
{[][]key{K_F10}},
{[][]key{K_F11}},
{[][]key{K_F12}},
{[][]key{K_INS}},
{[][]key{K_DEL}},
{[][]key{K_HOM}},
{[][]key{K_END}},
{[][]key{K_PGU}},
{[][]key{K_PGD}},
{[][]key{K_ARROW_UP}},
{[][]key{K_ARROW_DOWN}},
{[][]key{K_ARROW_LEFT}},
{[][]key{K_ARROW_RIGHT}},
}
func print_tb(x, y int, fg, bg termbox.Attribute, msg string) {
for _, c := range msg {
termbox.SetCell(x, y, c, fg, bg)
x++
}
}
func printf_tb(x, y int, fg, bg termbox.Attribute, format string, args ...interface{}) {
s := fmt.Sprintf(format, args...)
print_tb(x, y, fg, bg, s)
}
func draw_key(k []key, fg, bg termbox.Attribute) {
for _, k := range k {
termbox.SetCell(k.x+2, k.y+4, k.ch, fg, bg)
}
}
func draw_keyboard() {
termbox.SetCell(0, 0, 0x250C, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(79, 0, 0x2510, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(0, 23, 0x2514, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(79, 23, 0x2518, termbox.ColorWhite, termbox.ColorBlack)
for i := 1; i < 79; i++ {
termbox.SetCell(i, 0, 0x2500, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(i, 23, 0x2500, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(i, 17, 0x2500, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(i, 4, 0x2500, termbox.ColorWhite, termbox.ColorBlack)
}
for i := 1; i < 23; i++ {
termbox.SetCell(0, i, 0x2502, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(79, i, 0x2502, termbox.ColorWhite, termbox.ColorBlack)
}
termbox.SetCell(0, 17, 0x251C, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(79, 17, 0x2524, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(0, 4, 0x251C, termbox.ColorWhite, termbox.ColorBlack)
termbox.SetCell(79, 4, 0x2524, termbox.ColorWhite, termbox.ColorBlack)
for i := 5; i < 17; i++ {
termbox.SetCell(1, i, 0x2588, termbox.ColorYellow, termbox.ColorYellow)
termbox.SetCell(78, i, 0x2588, termbox.ColorYellow, termbox.ColorYellow)
}
draw_key(K_ESC, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F1, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F2, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F3, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F4, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F5, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F6, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F7, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F8, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F9, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F10, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F11, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_F12, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_PRN, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_SCR, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_BRK, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LED1, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LED2, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LED3, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_TILDE, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_1, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_2, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_3, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_4, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_5, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_6, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_7, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_8, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_9, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_0, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_MINUS, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_EQUALS, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_BACKSLASH, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_BACKSPACE, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_INS, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_HOM, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_PGU, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_NUMLOCK, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_SLASH, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_STAR, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_MINUS, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_TAB, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_q, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_w, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_e, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_r, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_t, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_y, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_u, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_i, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_o, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_p, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LSQB, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_RSQB, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_ENTER, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_DEL, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_END, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_PGD, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_7, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_8, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_9, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_PLUS, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_CAPS, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_a, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_s, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_d, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_f, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_g, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_h, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_j, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_k, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_l, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_SEMICOLON, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_QUOTE, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_4, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_5, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_6, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LSHIFT, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_z, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_x, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_c, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_v, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_b, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_n, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_m, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_COMMA, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_PERIOD, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_SLASH, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_RSHIFT, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_ARROW_UP, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_1, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_2, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_3, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_ENTER, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LCTRL, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LWIN, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_LALT, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_SPACE, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_RCTRL, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_RPROP, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_RWIN, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_RALT, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_ARROW_LEFT, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_ARROW_DOWN, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_ARROW_RIGHT, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_0, termbox.ColorWhite, termbox.ColorBlue)
draw_key(K_K_PERIOD, termbox.ColorWhite, termbox.ColorBlue)
printf_tb(33, 1, termbox.ColorMagenta|termbox.AttrBold, termbox.ColorBlack, "Keyboard demo!")
printf_tb(21, 2, termbox.ColorMagenta, termbox.ColorBlack, "(press CTRL+X and then CTRL+Q to exit)")
printf_tb(15, 3, termbox.ColorMagenta, termbox.ColorBlack, "(press CTRL+X and then CTRL+C to change input mode)")
inputmode := termbox.SetInputMode(termbox.InputCurrent)
inputmode_str := ""
switch {
case inputmode&termbox.InputEsc != 0:
inputmode_str = "termbox.InputEsc"
case inputmode&termbox.InputAlt != 0:
inputmode_str = "termbox.InputAlt"
}
if inputmode&termbox.InputMouse != 0 {
inputmode_str += " | termbox.InputMouse"
}
printf_tb(3, 18, termbox.ColorWhite, termbox.ColorBlack, "Input mode: %s", inputmode_str)
}
var fcmap = []string{
"CTRL+2, CTRL+~",
"CTRL+A",
"CTRL+B",
"CTRL+C",
"CTRL+D",
"CTRL+E",
"CTRL+F",
"CTRL+G",
"CTRL+H, BACKSPACE",
"CTRL+I, TAB",
"CTRL+J",
"CTRL+K",
"CTRL+L",
"CTRL+M, ENTER",
"CTRL+N",
"CTRL+O",
"CTRL+P",
"CTRL+Q",
"CTRL+R",
"CTRL+S",
"CTRL+T",
"CTRL+U",
"CTRL+V",
"CTRL+W",
"CTRL+X",
"CTRL+Y",
"CTRL+Z",
"CTRL+3, ESC, CTRL+[",
"CTRL+4, CTRL+\\",
"CTRL+5, CTRL+]",
"CTRL+6",
"CTRL+7, CTRL+/, CTRL+_",
"SPACE",
}
var fkmap = []string{
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"INSERT",
"DELETE",
"HOME",
"END",
"PGUP",
"PGDN",
"ARROW UP",
"ARROW DOWN",
"ARROW LEFT",
"ARROW RIGHT",
}
func funckeymap(k termbox.Key) string {
if k == termbox.KeyCtrl8 {
return "CTRL+8, BACKSPACE 2" /* 0x7F */
} else if k >= termbox.KeyArrowRight && k <= 0xFFFF {
return fkmap[0xFFFF-k]
} else if k <= termbox.KeySpace {
return fcmap[k]
}
return "UNKNOWN"
}
func pretty_print_press(ev *termbox.Event) {
printf_tb(3, 19, termbox.ColorWhite, termbox.ColorBlack, "Key: ")
printf_tb(8, 19, termbox.ColorYellow, termbox.ColorBlack, "decimal: %d", ev.Key)
printf_tb(8, 20, termbox.ColorGreen, termbox.ColorBlack, "hex: 0x%X", ev.Key)
printf_tb(8, 21, termbox.ColorCyan, termbox.ColorBlack, "octal: 0%o", ev.Key)
printf_tb(8, 22, termbox.ColorRed, termbox.ColorBlack, "string: %s", funckeymap(ev.Key))
printf_tb(54, 19, termbox.ColorWhite, termbox.ColorBlack, "Char: ")
printf_tb(60, 19, termbox.ColorYellow, termbox.ColorBlack, "decimal: %d", ev.Ch)
printf_tb(60, 20, termbox.ColorGreen, termbox.ColorBlack, "hex: 0x%X", ev.Ch)
printf_tb(60, 21, termbox.ColorCyan, termbox.ColorBlack, "octal: 0%o", ev.Ch)
printf_tb(60, 22, termbox.ColorRed, termbox.ColorBlack, "string: %s", string(ev.Ch))
modifier := "none"
if ev.Mod != 0 {
modifier = "termbox.ModAlt"
}
printf_tb(54, 18, termbox.ColorWhite, termbox.ColorBlack, "Modifier: %s", modifier)
}
func pretty_print_resize(ev *termbox.Event) {
printf_tb(3, 19, termbox.ColorWhite, termbox.ColorBlack, "Resize event: %d x %d", ev.Width, ev.Height)
}
var counter = 0
func pretty_print_mouse(ev *termbox.Event) {
printf_tb(3, 19, termbox.ColorWhite, termbox.ColorBlack, "Mouse event: %d x %d", ev.MouseX, ev.MouseY)
button := ""
switch ev.Key {
case termbox.MouseLeft:
button = "MouseLeft: %d"
case termbox.MouseMiddle:
button = "MouseMiddle: %d"
case termbox.MouseRight:
button = "MouseRight: %d"
case termbox.MouseWheelUp:
button = "MouseWheelUp: %d"
case termbox.MouseWheelDown:
button = "MouseWheelDown: %d"
case termbox.MouseRelease:
button = "MouseRelease: %d"
}
if ev.Mod&termbox.ModMotion != 0 {
button += "*"
}
counter++
printf_tb(43, 19, termbox.ColorWhite, termbox.ColorBlack, "Key: ")
printf_tb(48, 19, termbox.ColorYellow, termbox.ColorBlack, button, counter)
}
func dispatch_press(ev *termbox.Event) {
if ev.Mod&termbox.ModAlt != 0 {
draw_key(K_LALT, termbox.ColorWhite, termbox.ColorRed)
draw_key(K_RALT, termbox.ColorWhite, termbox.ColorRed)
}
var k *combo
if ev.Key >= termbox.KeyArrowRight {
k = &func_combos[0xFFFF-ev.Key]
} else if ev.Ch < 128 {
if ev.Ch == 0 && ev.Key < 128 {
k = &combos[ev.Key]
} else {
k = &combos[ev.Ch]
}
}
if k == nil {
return
}
keys := k.keys
for _, k := range keys {
draw_key(k, termbox.ColorWhite, termbox.ColorRed)
}
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
termbox.SetInputMode(termbox.InputEsc | termbox.InputMouse)
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
draw_keyboard()
termbox.Flush()
inputmode := 0
ctrlxpressed := false
loop:
for {
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
if ev.Key == termbox.KeyCtrlS && ctrlxpressed {
termbox.Sync()
}
if ev.Key == termbox.KeyCtrlQ && ctrlxpressed {
break loop
}
if ev.Key == termbox.KeyCtrlC && ctrlxpressed {
chmap := []termbox.InputMode{
termbox.InputEsc | termbox.InputMouse,
termbox.InputAlt | termbox.InputMouse,
termbox.InputEsc,
termbox.InputAlt,
}
inputmode++
if inputmode >= len(chmap) {
inputmode = 0
}
termbox.SetInputMode(chmap[inputmode])
}
if ev.Key == termbox.KeyCtrlX {
ctrlxpressed = true
} else {
ctrlxpressed = false
}
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
draw_keyboard()
dispatch_press(&ev)
pretty_print_press(&ev)
termbox.Flush()
case termbox.EventResize:
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
draw_keyboard()
pretty_print_resize(&ev)
termbox.Flush()
case termbox.EventMouse:
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
draw_keyboard()
pretty_print_mouse(&ev)
termbox.Flush()
case termbox.EventError:
panic(ev.Err)
}
}
}

228
vendor/github.com/nsf/termbox-go/_demos/output.go generated vendored Normal file
View File

@ -0,0 +1,228 @@
package main
import "github.com/mattn/go-runewidth"
import "github.com/nsf/termbox-go"
const chars = "nnnnnnnnnbbbbbbbbbuuuuuuuuuBBBBBBBBB"
var output_mode = termbox.OutputNormal
func next_char(current int) int {
current++
if current >= len(chars) {
return 0
}
return current
}
func print_combinations_table(sx, sy int, attrs []termbox.Attribute) {
var bg termbox.Attribute
current_char := 0
y := sy
all_attrs := []termbox.Attribute{
0,
termbox.AttrBold,
termbox.AttrUnderline,
termbox.AttrBold | termbox.AttrUnderline,
}
draw_line := func() {
x := sx
for _, a := range all_attrs {
for c := termbox.ColorDefault; c <= termbox.ColorWhite; c++ {
fg := a | c
termbox.SetCell(x, y, rune(chars[current_char]), fg, bg)
current_char = next_char(current_char)
x++
}
}
}
for _, a := range attrs {
for c := termbox.ColorDefault; c <= termbox.ColorWhite; c++ {
bg = a | c
draw_line()
y++
}
}
}
func print_wide(x, y int, s string) {
red := false
for _, r := range s {
c := termbox.ColorDefault
if red {
c = termbox.ColorRed
}
termbox.SetCell(x, y, r, termbox.ColorDefault, c)
w := runewidth.RuneWidth(r)
if w == 0 || (w == 2 && runewidth.IsAmbiguousWidth(r)) {
w = 1
}
x += w
red = !red
}
}
const hello_world = "こんにちは世界"
func draw_all() {
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
switch output_mode {
case termbox.OutputNormal:
print_combinations_table(1, 1, []termbox.Attribute{
0,
termbox.AttrBold,
})
print_combinations_table(2+len(chars), 1, []termbox.Attribute{
termbox.AttrReverse,
})
print_wide(2+len(chars), 11, hello_world)
case termbox.OutputGrayscale:
for y := 0; y < 26; y++ {
for x := 0; x < 26; x++ {
termbox.SetCell(x, y, 'n',
termbox.Attribute(x+1),
termbox.Attribute(y+1))
termbox.SetCell(x+27, y, 'b',
termbox.Attribute(x+1)|termbox.AttrBold,
termbox.Attribute(26-y))
termbox.SetCell(x+54, y, 'u',
termbox.Attribute(x+1)|termbox.AttrUnderline,
termbox.Attribute(y+1))
}
termbox.SetCell(82, y, 'd',
termbox.Attribute(y+1),
termbox.ColorDefault)
termbox.SetCell(83, y, 'd',
termbox.ColorDefault,
termbox.Attribute(26-y))
}
case termbox.Output216:
for r := 0; r < 6; r++ {
for g := 0; g < 6; g++ {
for b := 0; b < 6; b++ {
y := r
x := g + 6*b
c1 := termbox.Attribute(1 + r*36 + g*6 + b)
bg := termbox.Attribute(1 + g*36 + b*6 + r)
c2 := termbox.Attribute(1 + b*36 + r*6 + g)
bc1 := c1 | termbox.AttrBold
uc1 := c1 | termbox.AttrUnderline
bc2 := c2 | termbox.AttrBold
uc2 := c2 | termbox.AttrUnderline
termbox.SetCell(x, y, 'n', c1, bg)
termbox.SetCell(x, y+6, 'b', bc1, bg)
termbox.SetCell(x, y+12, 'u', uc1, bg)
termbox.SetCell(x, y+18, 'B', bc1|uc1, bg)
termbox.SetCell(x+37, y, 'n', c2, bg)
termbox.SetCell(x+37, y+6, 'b', bc2, bg)
termbox.SetCell(x+37, y+12, 'u', uc2, bg)
termbox.SetCell(x+37, y+18, 'B', bc2|uc2, bg)
}
c1 := termbox.Attribute(1 + g*6 + r*36)
c2 := termbox.Attribute(6 + g*6 + r*36)
termbox.SetCell(74+g, r, 'd', c1, termbox.ColorDefault)
termbox.SetCell(74+g, r+6, 'd', c2, termbox.ColorDefault)
termbox.SetCell(74+g, r+12, 'd', termbox.ColorDefault, c1)
termbox.SetCell(74+g, r+18, 'd', termbox.ColorDefault, c2)
}
}
case termbox.Output256:
for y := 0; y < 4; y++ {
for x := 0; x < 8; x++ {
for z := 0; z < 8; z++ {
bg := termbox.Attribute(1 + y*64 + x*8 + z)
c1 := termbox.Attribute(256 - y*64 - x*8 - z)
c2 := termbox.Attribute(1 + y*64 + z*8 + x)
c3 := termbox.Attribute(256 - y*64 - z*8 - x)
c4 := termbox.Attribute(1 + y*64 + x*4 + z*4)
bold := c2 | termbox.AttrBold
under := c3 | termbox.AttrUnderline
both := c1 | termbox.AttrBold | termbox.AttrUnderline
termbox.SetCell(z+8*x, y, ' ', 0, bg)
termbox.SetCell(z+8*x, y+5, 'n', c4, bg)
termbox.SetCell(z+8*x, y+10, 'b', bold, bg)
termbox.SetCell(z+8*x, y+15, 'u', under, bg)
termbox.SetCell(z+8*x, y+20, 'B', both, bg)
}
}
}
for x := 0; x < 12; x++ {
for y := 0; y < 2; y++ {
c1 := termbox.Attribute(233 + y*12 + x)
termbox.SetCell(66+x, y, 'd', c1, termbox.ColorDefault)
termbox.SetCell(66+x, 2+y, 'd', termbox.ColorDefault, c1)
}
}
for x := 0; x < 6; x++ {
for y := 0; y < 6; y++ {
c1 := termbox.Attribute(17 + x*6 + y*36)
c2 := termbox.Attribute(17 + 5 + x*6 + y*36)
termbox.SetCell(66+x, 6+y, 'd', c1, termbox.ColorDefault)
termbox.SetCell(66+x, 12+y, 'd', c2, termbox.ColorDefault)
termbox.SetCell(72+x, 6+y, 'd', termbox.ColorDefault, c1)
termbox.SetCell(72+x, 12+y, 'd', termbox.ColorDefault, c2)
}
}
}
termbox.Flush()
}
var available_modes = []termbox.OutputMode{
termbox.OutputNormal,
termbox.OutputGrayscale,
termbox.Output216,
termbox.Output256,
}
var output_mode_index = 0
func switch_output_mode(direction int) {
output_mode_index += direction
if output_mode_index < 0 {
output_mode_index = len(available_modes) - 1
} else if output_mode_index >= len(available_modes) {
output_mode_index = 0
}
output_mode = termbox.SetOutputMode(available_modes[output_mode_index])
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
termbox.Sync()
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
draw_all()
loop:
for {
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
switch ev.Key {
case termbox.KeyEsc:
break loop
case termbox.KeyArrowUp, termbox.KeyArrowRight:
switch_output_mode(1)
draw_all()
case termbox.KeyArrowDown, termbox.KeyArrowLeft:
switch_output_mode(-1)
draw_all()
}
case termbox.EventResize:
draw_all()
}
}
}

105
vendor/github.com/nsf/termbox-go/_demos/paint.go generated vendored Normal file
View File

@ -0,0 +1,105 @@
package main
import (
"github.com/nsf/termbox-go"
)
var curCol = 0
var curRune = 0
var backbuf []termbox.Cell
var bbw, bbh int
var runes = []rune{' ', '░', '▒', '▓', '█'}
var colors = []termbox.Attribute{
termbox.ColorBlack,
termbox.ColorRed,
termbox.ColorGreen,
termbox.ColorYellow,
termbox.ColorBlue,
termbox.ColorMagenta,
termbox.ColorCyan,
termbox.ColorWhite,
}
type attrFunc func(int) (rune, termbox.Attribute, termbox.Attribute)
func updateAndDrawButtons(current *int, x, y int, mx, my int, n int, attrf attrFunc) {
lx, ly := x, y
for i := 0; i < n; i++ {
if lx <= mx && mx <= lx+3 && ly <= my && my <= ly+1 {
*current = i
}
r, fg, bg := attrf(i)
termbox.SetCell(lx+0, ly+0, r, fg, bg)
termbox.SetCell(lx+1, ly+0, r, fg, bg)
termbox.SetCell(lx+2, ly+0, r, fg, bg)
termbox.SetCell(lx+3, ly+0, r, fg, bg)
termbox.SetCell(lx+0, ly+1, r, fg, bg)
termbox.SetCell(lx+1, ly+1, r, fg, bg)
termbox.SetCell(lx+2, ly+1, r, fg, bg)
termbox.SetCell(lx+3, ly+1, r, fg, bg)
lx += 4
}
lx, ly = x, y
for i := 0; i < n; i++ {
if *current == i {
fg := termbox.ColorRed | termbox.AttrBold
bg := termbox.ColorDefault
termbox.SetCell(lx+0, ly+2, '^', fg, bg)
termbox.SetCell(lx+1, ly+2, '^', fg, bg)
termbox.SetCell(lx+2, ly+2, '^', fg, bg)
termbox.SetCell(lx+3, ly+2, '^', fg, bg)
}
lx += 4
}
}
func update_and_redraw_all(mx, my int) {
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
if mx != -1 && my != -1 {
backbuf[bbw*my+mx] = termbox.Cell{Ch: runes[curRune], Fg: colors[curCol]}
}
copy(termbox.CellBuffer(), backbuf)
_, h := termbox.Size()
updateAndDrawButtons(&curRune, 0, 0, mx, my, len(runes), func(i int) (rune, termbox.Attribute, termbox.Attribute) {
return runes[i], termbox.ColorDefault, termbox.ColorDefault
})
updateAndDrawButtons(&curCol, 0, h-3, mx, my, len(colors), func(i int) (rune, termbox.Attribute, termbox.Attribute) {
return ' ', termbox.ColorDefault, colors[i]
})
termbox.Flush()
}
func reallocBackBuffer(w, h int) {
bbw, bbh = w, h
backbuf = make([]termbox.Cell, w*h)
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
termbox.SetInputMode(termbox.InputEsc | termbox.InputMouse)
reallocBackBuffer(termbox.Size())
update_and_redraw_all(-1, -1)
mainloop:
for {
mx, my := -1, -1
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
if ev.Key == termbox.KeyEsc {
break mainloop
}
case termbox.EventMouse:
if ev.Key == termbox.MouseLeft {
mx, my = ev.MouseX, ev.MouseY
}
case termbox.EventResize:
reallocBackBuffer(ev.Width, ev.Height)
}
update_and_redraw_all(mx, my)
}
}

View File

@ -0,0 +1,46 @@
package main
import "github.com/nsf/termbox-go"
import "math/rand"
import "time"
func draw() {
w, h := termbox.Size()
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
termbox.SetCell(x, y, ' ', termbox.ColorDefault,
termbox.Attribute(rand.Int()%8)+1)
}
}
termbox.Flush()
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
event_queue := make(chan termbox.Event)
go func() {
for {
event_queue <- termbox.PollEvent()
}
}()
draw()
loop:
for {
select {
case ev := <-event_queue:
if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEsc {
break loop
}
default:
draw()
time.Sleep(10 * time.Millisecond)
}
}
}

109
vendor/github.com/nsf/termbox-go/_demos/raw_input.go generated vendored Normal file
View File

@ -0,0 +1,109 @@
package main
import (
"fmt"
"github.com/nsf/termbox-go"
"strings"
)
func tbprint(x, y int, fg, bg termbox.Attribute, msg string) {
for _, c := range msg {
termbox.SetCell(x, y, c, fg, bg)
x++
}
}
var current string
var curev termbox.Event
func mouse_button_str(k termbox.Key) string {
switch k {
case termbox.MouseLeft:
return "MouseLeft"
case termbox.MouseMiddle:
return "MouseMiddle"
case termbox.MouseRight:
return "MouseRight"
case termbox.MouseRelease:
return "MouseRelease"
case termbox.MouseWheelUp:
return "MouseWheelUp"
case termbox.MouseWheelDown:
return "MouseWheelDown"
}
return "Key"
}
func mod_str(m termbox.Modifier) string {
var out []string
if m&termbox.ModAlt != 0 {
out = append(out, "ModAlt")
}
if m&termbox.ModMotion != 0 {
out = append(out, "ModMotion")
}
return strings.Join(out, " | ")
}
func redraw_all() {
const coldef = termbox.ColorDefault
termbox.Clear(coldef, coldef)
tbprint(0, 0, termbox.ColorMagenta, coldef, "Press 'q' to quit")
tbprint(0, 1, coldef, coldef, current)
switch curev.Type {
case termbox.EventKey:
tbprint(0, 2, coldef, coldef,
fmt.Sprintf("EventKey: k: %d, c: %c, mod: %s", curev.Key, curev.Ch, mod_str(curev.Mod)))
case termbox.EventMouse:
tbprint(0, 2, coldef, coldef,
fmt.Sprintf("EventMouse: x: %d, y: %d, b: %s, mod: %s",
curev.MouseX, curev.MouseY, mouse_button_str(curev.Key), mod_str(curev.Mod)))
case termbox.EventNone:
tbprint(0, 2, coldef, coldef, "EventNone")
}
tbprint(0, 3, coldef, coldef, fmt.Sprintf("%d", curev.N))
termbox.Flush()
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
termbox.SetInputMode(termbox.InputAlt | termbox.InputMouse)
redraw_all()
data := make([]byte, 0, 64)
mainloop:
for {
if cap(data)-len(data) < 32 {
newdata := make([]byte, len(data), len(data)+32)
copy(newdata, data)
data = newdata
}
beg := len(data)
d := data[beg : beg+32]
switch ev := termbox.PollRawEvent(d); ev.Type {
case termbox.EventRaw:
data = data[:beg+ev.N]
current = fmt.Sprintf("%q", data)
if current == `"q"` {
break mainloop
}
for {
ev := termbox.ParseEvent(data)
if ev.N == 0 {
break
}
curev = ev
copy(data, data[curev.N:])
data = data[:len(data)-curev.N]
}
case termbox.EventError:
panic(ev.Err)
}
redraw_all()
}
}

457
vendor/github.com/nsf/termbox-go/api.go generated vendored Normal file
View File

@ -0,0 +1,457 @@
// +build !windows
package termbox
import "github.com/mattn/go-runewidth"
import "fmt"
import "os"
import "os/signal"
import "syscall"
import "runtime"
// public API
// Initializes termbox library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
// err := termbox.Init()
// if err != nil {
// panic(err)
// }
// defer termbox.Close()
func Init() error {
var err error
out, err = os.OpenFile("/dev/tty", syscall.O_WRONLY, 0)
if err != nil {
return err
}
in, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0)
if err != nil {
return err
}
err = setup_term()
if err != nil {
return fmt.Errorf("termbox: error while reading terminfo data: %v", err)
}
signal.Notify(sigwinch, syscall.SIGWINCH)
signal.Notify(sigio, syscall.SIGIO)
_, err = fcntl(in, syscall.F_SETFL, syscall.O_ASYNC|syscall.O_NONBLOCK)
if err != nil {
return err
}
_, err = fcntl(in, syscall.F_SETOWN, syscall.Getpid())
if runtime.GOOS != "darwin" && err != nil {
return err
}
err = tcgetattr(out.Fd(), &orig_tios)
if err != nil {
return err
}
tios := orig_tios
tios.Iflag &^= syscall_IGNBRK | syscall_BRKINT | syscall_PARMRK |
syscall_ISTRIP | syscall_INLCR | syscall_IGNCR |
syscall_ICRNL | syscall_IXON
tios.Lflag &^= syscall_ECHO | syscall_ECHONL | syscall_ICANON |
syscall_ISIG | syscall_IEXTEN
tios.Cflag &^= syscall_CSIZE | syscall_PARENB
tios.Cflag |= syscall_CS8
tios.Cc[syscall_VMIN] = 1
tios.Cc[syscall_VTIME] = 0
err = tcsetattr(out.Fd(), &tios)
if err != nil {
return err
}
out.WriteString(funcs[t_enter_ca])
out.WriteString(funcs[t_enter_keypad])
out.WriteString(funcs[t_hide_cursor])
out.WriteString(funcs[t_clear_screen])
termw, termh = get_term_size(out.Fd())
back_buffer.init(termw, termh)
front_buffer.init(termw, termh)
back_buffer.clear()
front_buffer.clear()
go func() {
buf := make([]byte, 128)
for {
select {
case <-sigio:
for {
n, err := syscall.Read(in, buf)
if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK {
break
}
select {
case input_comm <- input_event{buf[:n], err}:
ie := <-input_comm
buf = ie.data[:128]
case <-quit:
return
}
}
case <-quit:
return
}
}
}()
IsInit = true
return nil
}
// Interrupt an in-progress call to PollEvent by causing it to return
// EventInterrupt. Note that this function will block until the PollEvent
// function has successfully been interrupted.
func Interrupt() {
interrupt_comm <- struct{}{}
}
// Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
quit <- 1
out.WriteString(funcs[t_show_cursor])
out.WriteString(funcs[t_sgr0])
out.WriteString(funcs[t_clear_screen])
out.WriteString(funcs[t_exit_ca])
out.WriteString(funcs[t_exit_keypad])
out.WriteString(funcs[t_exit_mouse])
tcsetattr(out.Fd(), &orig_tios)
out.Close()
syscall.Close(in)
// reset the state, so that on next Init() it will work again
termw = 0
termh = 0
input_mode = InputEsc
out = nil
in = 0
lastfg = attr_invalid
lastbg = attr_invalid
lastx = coord_invalid
lasty = coord_invalid
cursor_x = cursor_hidden
cursor_y = cursor_hidden
foreground = ColorDefault
background = ColorDefault
IsInit = false
}
// Synchronizes the internal back buffer with the terminal.
func Flush() error {
// invalidate cursor position
lastx = coord_invalid
lasty = coord_invalid
update_size_maybe()
for y := 0; y < front_buffer.height; y++ {
line_offset := y * front_buffer.width
for x := 0; x < front_buffer.width; {
cell_offset := line_offset + x
back := &back_buffer.cells[cell_offset]
front := &front_buffer.cells[cell_offset]
if back.Ch < ' ' {
back.Ch = ' '
}
w := runewidth.RuneWidth(back.Ch)
if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) {
w = 1
}
if *back == *front {
x += w
continue
}
*front = *back
send_attr(back.Fg, back.Bg)
if w == 2 && x == front_buffer.width-1 {
// there's not enough space for 2-cells rune,
// let's just put a space in there
send_char(x, y, ' ')
} else {
send_char(x, y, back.Ch)
if w == 2 {
next := cell_offset + 1
front_buffer.cells[next] = Cell{
Ch: 0,
Fg: back.Fg,
Bg: back.Bg,
}
}
}
x += w
}
}
if !is_cursor_hidden(cursor_x, cursor_y) {
write_cursor(cursor_x, cursor_y)
}
return flush()
}
// Sets the position of the cursor. See also HideCursor().
func SetCursor(x, y int) {
if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
outbuf.WriteString(funcs[t_show_cursor])
}
if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
outbuf.WriteString(funcs[t_hide_cursor])
}
cursor_x, cursor_y = x, y
if !is_cursor_hidden(cursor_x, cursor_y) {
write_cursor(cursor_x, cursor_y)
}
}
// The shortcut for SetCursor(-1, -1).
func HideCursor() {
SetCursor(cursor_hidden, cursor_hidden)
}
// Changes cell's parameters in the internal back buffer at the specified
// position.
func SetCell(x, y int, ch rune, fg, bg Attribute) {
if x < 0 || x >= back_buffer.width {
return
}
if y < 0 || y >= back_buffer.height {
return
}
back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
}
// Returns a slice into the termbox's back buffer. You can get its dimensions
// using 'Size' function. The slice remains valid as long as no 'Clear' or
// 'Flush' function calls were made after call to this function.
func CellBuffer() []Cell {
return back_buffer.cells
}
// After getting a raw event from PollRawEvent function call, you can parse it
// again into an ordinary one using termbox logic. That is parse an event as
// termbox would do it. Returned event in addition to usual Event struct fields
// sets N field to the amount of bytes used within 'data' slice. If the length
// of 'data' slice is zero or event cannot be parsed for some other reason, the
// function will return a special event type: EventNone.
//
// IMPORTANT: EventNone may contain a non-zero N, which means you should skip
// these bytes, because termbox cannot recognize them.
//
// 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 {
return Event{Type: EventNone, N: event.N}
}
return event
}
// Wait for an event and return it. This is a blocking function call. Instead
// of EventKey and EventMouse it returns EventRaw events. Raw event is written
// into `data` slice and Event's N field is set to the amount of bytes written.
// The minimum required length of the 'data' slice is 1. This requirement may
// vary on different platforms.
//
// NOTE: This API is experimental and may change in future.
func PollRawEvent(data []byte) Event {
if len(data) == 0 {
panic("len(data) >= 1 is a requirement")
}
var event Event
if extract_raw_event(data, &event) {
return event
}
for {
select {
case ev := <-input_comm:
if ev.err != nil {
return Event{Type: EventError, Err: ev.err}
}
inbuf = append(inbuf, ev.data...)
input_comm <- ev
if extract_raw_event(data, &event) {
return event
}
case <-interrupt_comm:
event.Type = EventInterrupt
return event
case <-sigwinch:
event.Type = EventResize
event.Width, event.Height = get_term_size(out.Fd())
return event
}
}
}
// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
var event Event
// try to extract event from input buffer, return on success
event.Type = EventKey
ok := extract_event(inbuf, &event)
if event.N != 0 {
copy(inbuf, inbuf[event.N:])
inbuf = inbuf[:len(inbuf)-event.N]
}
if ok {
return event
}
for {
select {
case ev := <-input_comm:
if ev.err != nil {
return Event{Type: EventError, Err: ev.err}
}
inbuf = append(inbuf, ev.data...)
input_comm <- ev
ok := extract_event(inbuf, &event)
if event.N != 0 {
copy(inbuf, inbuf[event.N:])
inbuf = inbuf[:len(inbuf)-event.N]
}
if ok {
return event
}
case <-interrupt_comm:
event.Type = EventInterrupt
return event
case <-sigwinch:
event.Type = EventResize
event.Width, event.Height = get_term_size(out.Fd())
return event
}
}
}
// Returns the size of the internal back buffer (which is mostly the same as
// terminal's window size in characters). But it doesn't always match the size
// of the terminal window, after the terminal size has changed, the internal
// back buffer will get in sync only after Clear or Flush function calls.
func Size() (width int, height int) {
return termw, termh
}
// Clears the internal back buffer.
func Clear(fg, bg Attribute) error {
foreground, background = fg, bg
err := update_size_maybe()
back_buffer.clear()
return err
}
// Sets termbox input mode. Termbox has two input modes:
//
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC means KeyEsc. This is the default input mode.
//
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
//
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
// enable mouse button press/release and drag events.
//
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
// constants.
func SetInputMode(mode InputMode) InputMode {
if mode == InputCurrent {
return input_mode
}
if mode&(InputEsc|InputAlt) == 0 {
mode |= InputEsc
}
if mode&(InputEsc|InputAlt) == InputEsc|InputAlt {
mode &^= InputAlt
}
if mode&InputMouse != 0 {
out.WriteString(funcs[t_enter_mouse])
} else {
out.WriteString(funcs[t_exit_mouse])
}
input_mode = mode
return input_mode
}
// Sets the termbox output mode. Termbox has four output options:
//
// 1. OutputNormal => [1..8]
// This mode provides 8 different colors:
// black, red, green, yellow, blue, magenta, cyan, white
// Shortcut: ColorBlack, ColorRed, ...
// Attributes: AttrBold, AttrUnderline, AttrReverse
//
// Example usage:
// SetCell(x, y, '@', ColorBlack | AttrBold, ColorRed);
//
// 2. Output256 => [1..256]
// In this mode you can leverage the 256 terminal mode:
// 0x01 - 0x08: the 8 colors as in OutputNormal
// 0x09 - 0x10: Color* | AttrBold
// 0x11 - 0xe8: 216 different colors
// 0xe9 - 0x1ff: 24 different shades of grey
//
// Example usage:
// SetCell(x, y, '@', 184, 240);
// SetCell(x, y, '@', 0xb8, 0xf0);
//
// 3. Output216 => [1..216]
// This mode supports the 3rd range of the 256 mode only.
// But you dont 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.
//
// In all modes, 0x00 represents the default color.
//
// `go run _demos/output.go` to see its impact on your terminal.
//
// If 'mode' is OutputCurrent, it returns the current output mode.
//
// Note that this may return a different OutputMode than the one requested,
// as the requested mode may not be available on the target platform.
func SetOutputMode(mode OutputMode) OutputMode {
if mode == OutputCurrent {
return output_mode
}
output_mode = mode
return output_mode
}
// Sync comes handy when something causes desync between termbox's understanding
// of a terminal buffer and the reality. Such as a third party process. Sync
// forces a complete resync between the termbox and a terminal, it may not be
// visually pretty though.
func Sync() error {
front_buffer.clear()
err := send_clear()
if err != nil {
return err
}
return Flush()
}

187
vendor/github.com/nsf/termbox-go/api_common.go generated vendored Normal file
View File

@ -0,0 +1,187 @@
// termbox is a library for creating cross-platform text-based interfaces
package termbox
// public API, common OS agnostic part
type (
InputMode int
OutputMode int
EventType uint8
Modifier uint8
Key uint16
Attribute uint16
)
// This type represents a termbox event. The 'Mod', 'Key' and 'Ch' fields are
// valid if 'Type' is EventKey. The 'Width' and 'Height' fields are valid if
// 'Type' is EventResize. The 'Err' field is valid if 'Type' is EventError.
type Event struct {
Type EventType // one of Event* constants
Mod Modifier // one of Mod* constants or 0
Key Key // one of Key* constants, invalid if 'Ch' is not 0
Ch rune // a unicode character
Width int // width of the screen
Height int // height of the screen
Err error // error in case if input failed
MouseX int // x coord of mouse
MouseY int // y coord of mouse
N int // number of bytes written when getting a raw event
}
// A cell, single conceptual entity on the screen. The screen is basically a 2d
// array of cells. 'Ch' is a unicode character, 'Fg' and 'Bg' are foreground
// and background attributes respectively.
type Cell struct {
Ch rune
Fg Attribute
Bg Attribute
}
// To know if termbox has been initialized or not
var (
IsInit bool = false
)
// Key constants, see Event.Key field.
const (
KeyF1 Key = 0xFFFF - iota
KeyF2
KeyF3
KeyF4
KeyF5
KeyF6
KeyF7
KeyF8
KeyF9
KeyF10
KeyF11
KeyF12
KeyInsert
KeyDelete
KeyHome
KeyEnd
KeyPgup
KeyPgdn
KeyArrowUp
KeyArrowDown
KeyArrowLeft
KeyArrowRight
key_min // see terminfo
MouseLeft
MouseMiddle
MouseRight
MouseRelease
MouseWheelUp
MouseWheelDown
)
const (
KeyCtrlTilde Key = 0x00
KeyCtrl2 Key = 0x00
KeyCtrlSpace Key = 0x00
KeyCtrlA Key = 0x01
KeyCtrlB Key = 0x02
KeyCtrlC Key = 0x03
KeyCtrlD Key = 0x04
KeyCtrlE Key = 0x05
KeyCtrlF Key = 0x06
KeyCtrlG Key = 0x07
KeyBackspace Key = 0x08
KeyCtrlH Key = 0x08
KeyTab Key = 0x09
KeyCtrlI Key = 0x09
KeyCtrlJ Key = 0x0A
KeyCtrlK Key = 0x0B
KeyCtrlL Key = 0x0C
KeyEnter Key = 0x0D
KeyCtrlM Key = 0x0D
KeyCtrlN Key = 0x0E
KeyCtrlO Key = 0x0F
KeyCtrlP Key = 0x10
KeyCtrlQ Key = 0x11
KeyCtrlR Key = 0x12
KeyCtrlS Key = 0x13
KeyCtrlT Key = 0x14
KeyCtrlU Key = 0x15
KeyCtrlV Key = 0x16
KeyCtrlW Key = 0x17
KeyCtrlX Key = 0x18
KeyCtrlY Key = 0x19
KeyCtrlZ Key = 0x1A
KeyEsc Key = 0x1B
KeyCtrlLsqBracket Key = 0x1B
KeyCtrl3 Key = 0x1B
KeyCtrl4 Key = 0x1C
KeyCtrlBackslash Key = 0x1C
KeyCtrl5 Key = 0x1D
KeyCtrlRsqBracket Key = 0x1D
KeyCtrl6 Key = 0x1E
KeyCtrl7 Key = 0x1F
KeyCtrlSlash Key = 0x1F
KeyCtrlUnderscore Key = 0x1F
KeySpace Key = 0x20
KeyBackspace2 Key = 0x7F
KeyCtrl8 Key = 0x7F
)
// Alt modifier constant, see Event.Mod field and SetInputMode function.
const (
ModAlt Modifier = 1 << iota
ModMotion
)
// Cell colors, you can combine a color with multiple attributes using bitwise
// OR ('|').
const (
ColorDefault Attribute = iota
ColorBlack
ColorRed
ColorGreen
ColorYellow
ColorBlue
ColorMagenta
ColorCyan
ColorWhite
)
// Cell attributes, it is possible to use multiple attributes by combining them
// 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.
// 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.
const (
AttrBold Attribute = 1 << (iota + 9)
AttrUnderline
AttrReverse
)
// Input mode. See SetInputMode function.
const (
InputEsc InputMode = 1 << iota
InputAlt
InputMouse
InputCurrent InputMode = 0
)
// Output mode. See SetOutputMode function.
const (
OutputCurrent OutputMode = iota
OutputNormal
Output256
Output216
OutputGrayscale
)
// Event type. See Event.Type field.
const (
EventKey EventType = iota
EventResize
EventMouse
EventError
EventInterrupt
EventRaw
EventNone
)

239
vendor/github.com/nsf/termbox-go/api_windows.go generated vendored Normal file
View File

@ -0,0 +1,239 @@
package termbox
import (
"syscall"
)
// public API
// Initializes termbox library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
// err := termbox.Init()
// if err != nil {
// panic(err)
// }
// defer termbox.Close()
func Init() error {
var err error
interrupt, err = create_event()
if err != nil {
return err
}
in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0)
if err != nil {
return err
}
out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0)
if err != nil {
return err
}
err = get_console_mode(in, &orig_mode)
if err != nil {
return err
}
err = set_console_mode(in, enable_window_input)
if err != nil {
return err
}
orig_size = get_term_size(out)
win_size := get_win_size(out)
err = set_console_screen_buffer_size(out, win_size)
if err != nil {
return err
}
err = get_console_cursor_info(out, &orig_cursor_info)
if err != nil {
return err
}
show_cursor(false)
term_size = get_term_size(out)
back_buffer.init(int(term_size.x), int(term_size.y))
front_buffer.init(int(term_size.x), int(term_size.y))
back_buffer.clear()
front_buffer.clear()
clear()
diffbuf = make([]diff_msg, 0, 32)
go input_event_producer()
IsInit = true
return nil
}
// Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
// we ignore errors here, because we can't really do anything about them
Clear(0, 0)
Flush()
// stop event producer
cancel_comm <- true
set_event(interrupt)
select {
case <-input_comm:
default:
}
<-cancel_done_comm
set_console_cursor_info(out, &orig_cursor_info)
set_console_cursor_position(out, coord{})
set_console_screen_buffer_size(out, orig_size)
set_console_mode(in, orig_mode)
syscall.Close(in)
syscall.Close(out)
syscall.Close(interrupt)
IsInit = false
}
// Interrupt an in-progress call to PollEvent by causing it to return
// EventInterrupt. Note that this function will block until the PollEvent
// function has successfully been interrupted.
func Interrupt() {
interrupt_comm <- struct{}{}
}
// Synchronizes the internal back buffer with the terminal.
func Flush() error {
update_size_maybe()
prepare_diff_messages()
for _, diff := range diffbuf {
r := small_rect{
left: 0,
top: diff.pos,
right: term_size.x - 1,
bottom: diff.pos + diff.lines - 1,
}
write_console_output(out, diff.chars, r)
}
if !is_cursor_hidden(cursor_x, cursor_y) {
move_cursor(cursor_x, cursor_y)
}
return nil
}
// Sets the position of the cursor. See also HideCursor().
func SetCursor(x, y int) {
if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
show_cursor(true)
}
if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
show_cursor(false)
}
cursor_x, cursor_y = x, y
if !is_cursor_hidden(cursor_x, cursor_y) {
move_cursor(cursor_x, cursor_y)
}
}
// The shortcut for SetCursor(-1, -1).
func HideCursor() {
SetCursor(cursor_hidden, cursor_hidden)
}
// Changes cell's parameters in the internal back buffer at the specified
// position.
func SetCell(x, y int, ch rune, fg, bg Attribute) {
if x < 0 || x >= back_buffer.width {
return
}
if y < 0 || y >= back_buffer.height {
return
}
back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
}
// Returns a slice into the termbox's back buffer. You can get its dimensions
// using 'Size' function. The slice remains valid as long as no 'Clear' or
// 'Flush' function calls were made after call to this function.
func CellBuffer() []Cell {
return back_buffer.cells
}
// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
select {
case ev := <-input_comm:
return ev
case <-interrupt_comm:
return Event{Type: EventInterrupt}
}
}
// Returns the size of the internal back buffer (which is mostly the same as
// console's window size in characters). But it doesn't always match the size
// of the console window, after the console size has changed, the internal back
// buffer will get in sync only after Clear or Flush function calls.
func Size() (int, int) {
return int(term_size.x), int(term_size.y)
}
// Clears the internal back buffer.
func Clear(fg, bg Attribute) error {
foreground, background = fg, bg
update_size_maybe()
back_buffer.clear()
return nil
}
// Sets termbox input mode. Termbox has two input modes:
//
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC means KeyEsc. This is the default input mode.
//
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
//
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
// enable mouse button press/release and drag events.
//
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
// constants.
func SetInputMode(mode InputMode) InputMode {
if mode == InputCurrent {
return input_mode
}
if mode&InputMouse != 0 {
err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags)
if err != nil {
panic(err)
}
} else {
err := set_console_mode(in, enable_window_input)
if err != nil {
panic(err)
}
}
input_mode = mode
return input_mode
}
// Sets the termbox output mode.
//
// Windows console does not support extra colour modes,
// so this will always set and return OutputNormal.
func SetOutputMode(mode OutputMode) OutputMode {
return OutputNormal
}
// Sync comes handy when something causes desync between termbox's understanding
// of a terminal buffer and the reality. Such as a third party process. Sync
// forces a complete resync between the termbox and a terminal, it may not be
// visually pretty though. At the moment on Windows it does nothing.
func Sync() error {
return nil
}

110
vendor/github.com/nsf/termbox-go/collect_terminfo.py generated vendored Executable file
View File

@ -0,0 +1,110 @@
#!/usr/bin/env python
import sys, os, subprocess
def escaped(s):
return repr(s)[1:-1]
def tput(term, name):
try:
return subprocess.check_output(['tput', '-T%s' % term, name]).decode()
except subprocess.CalledProcessError as e:
return e.output.decode()
def w(s):
if s == None:
return
sys.stdout.write(s)
terminals = {
'xterm' : 'xterm',
'rxvt-256color' : 'rxvt_256color',
'rxvt-unicode' : 'rxvt_unicode',
'linux' : 'linux',
'Eterm' : 'eterm',
'screen' : 'screen'
}
keys = [
"F1", "kf1",
"F2", "kf2",
"F3", "kf3",
"F4", "kf4",
"F5", "kf5",
"F6", "kf6",
"F7", "kf7",
"F8", "kf8",
"F9", "kf9",
"F10", "kf10",
"F11", "kf11",
"F12", "kf12",
"INSERT", "kich1",
"DELETE", "kdch1",
"HOME", "khome",
"END", "kend",
"PGUP", "kpp",
"PGDN", "knp",
"KEY_UP", "kcuu1",
"KEY_DOWN", "kcud1",
"KEY_LEFT", "kcub1",
"KEY_RIGHT", "kcuf1"
]
funcs = [
"T_ENTER_CA", "smcup",
"T_EXIT_CA", "rmcup",
"T_SHOW_CURSOR", "cnorm",
"T_HIDE_CURSOR", "civis",
"T_CLEAR_SCREEN", "clear",
"T_SGR0", "sgr0",
"T_UNDERLINE", "smul",
"T_BOLD", "bold",
"T_BLINK", "blink",
"T_REVERSE", "rev",
"T_ENTER_KEYPAD", "smkx",
"T_EXIT_KEYPAD", "rmkx"
]
def iter_pairs(iterable):
iterable = iter(iterable)
while True:
yield (next(iterable), next(iterable))
def do_term(term, nick):
w("// %s\n" % term)
w("var %s_keys = []string{\n\t" % nick)
for k, v in iter_pairs(keys):
w('"')
w(escaped(tput(term, v)))
w('",')
w("\n}\n")
w("var %s_funcs = []string{\n\t" % nick)
for k,v in iter_pairs(funcs):
w('"')
if v == "sgr":
w("\\033[3%d;4%dm")
elif v == "cup":
w("\\033[%d;%dH")
else:
w(escaped(tput(term, v)))
w('", ')
w("\n}\n\n")
def do_terms(d):
w("var terms = []struct {\n")
w("\tname string\n")
w("\tkeys []string\n")
w("\tfuncs []string\n")
w("}{\n")
for k, v in d.items():
w('\t{"%s", %s_keys, %s_funcs},\n' % (k, v, v))
w("}\n\n")
w("// +build !windows\n\npackage termbox\n\n")
for k,v in terminals.items():
do_term(k, v)
do_terms(terminals)

39
vendor/github.com/nsf/termbox-go/syscalls.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// +build ignore
package termbox
/*
#include <termios.h>
#include <sys/ioctl.h>
*/
import "C"
type syscall_Termios C.struct_termios
const (
syscall_IGNBRK = C.IGNBRK
syscall_BRKINT = C.BRKINT
syscall_PARMRK = C.PARMRK
syscall_ISTRIP = C.ISTRIP
syscall_INLCR = C.INLCR
syscall_IGNCR = C.IGNCR
syscall_ICRNL = C.ICRNL
syscall_IXON = C.IXON
syscall_OPOST = C.OPOST
syscall_ECHO = C.ECHO
syscall_ECHONL = C.ECHONL
syscall_ICANON = C.ICANON
syscall_ISIG = C.ISIG
syscall_IEXTEN = C.IEXTEN
syscall_CSIZE = C.CSIZE
syscall_PARENB = C.PARENB
syscall_CS8 = C.CS8
syscall_VMIN = C.VMIN
syscall_VTIME = C.VTIME
// on darwin change these to (on *bsd too?):
// C.TIOCGETA
// C.TIOCSETA
syscall_TCGETS = C.TCGETS
syscall_TCSETS = C.TCSETS
)

41
vendor/github.com/nsf/termbox-go/syscalls_darwin.go generated vendored Normal file
View File

@ -0,0 +1,41 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
// +build !amd64
package termbox
type syscall_Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed uint32
Ospeed uint32
}
const (
syscall_IGNBRK = 0x1
syscall_BRKINT = 0x2
syscall_PARMRK = 0x8
syscall_ISTRIP = 0x20
syscall_INLCR = 0x40
syscall_IGNCR = 0x80
syscall_ICRNL = 0x100
syscall_IXON = 0x200
syscall_OPOST = 0x1
syscall_ECHO = 0x8
syscall_ECHONL = 0x10
syscall_ICANON = 0x100
syscall_ISIG = 0x80
syscall_IEXTEN = 0x400
syscall_CSIZE = 0x300
syscall_PARENB = 0x1000
syscall_CS8 = 0x300
syscall_VMIN = 0x10
syscall_VTIME = 0x11
syscall_TCGETS = 0x402c7413
syscall_TCSETS = 0x802c7414
)

View File

@ -0,0 +1,40 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
package termbox
type syscall_Termios struct {
Iflag uint64
Oflag uint64
Cflag uint64
Lflag uint64
Cc [20]uint8
Pad_cgo_0 [4]byte
Ispeed uint64
Ospeed uint64
}
const (
syscall_IGNBRK = 0x1
syscall_BRKINT = 0x2
syscall_PARMRK = 0x8
syscall_ISTRIP = 0x20
syscall_INLCR = 0x40
syscall_IGNCR = 0x80
syscall_ICRNL = 0x100
syscall_IXON = 0x200
syscall_OPOST = 0x1
syscall_ECHO = 0x8
syscall_ECHONL = 0x10
syscall_ICANON = 0x100
syscall_ISIG = 0x80
syscall_IEXTEN = 0x400
syscall_CSIZE = 0x300
syscall_PARENB = 0x1000
syscall_CS8 = 0x300
syscall_VMIN = 0x10
syscall_VTIME = 0x11
syscall_TCGETS = 0x40487413
syscall_TCSETS = 0x80487414
)

39
vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
package termbox
type syscall_Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed uint32
Ospeed uint32
}
const (
syscall_IGNBRK = 0x1
syscall_BRKINT = 0x2
syscall_PARMRK = 0x8
syscall_ISTRIP = 0x20
syscall_INLCR = 0x40
syscall_IGNCR = 0x80
syscall_ICRNL = 0x100
syscall_IXON = 0x200
syscall_OPOST = 0x1
syscall_ECHO = 0x8
syscall_ECHONL = 0x10
syscall_ICANON = 0x100
syscall_ISIG = 0x80
syscall_IEXTEN = 0x400
syscall_CSIZE = 0x300
syscall_PARENB = 0x1000
syscall_CS8 = 0x300
syscall_VMIN = 0x10
syscall_VTIME = 0x11
syscall_TCGETS = 0x402c7413
syscall_TCSETS = 0x802c7414
)

39
vendor/github.com/nsf/termbox-go/syscalls_freebsd.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
package termbox
type syscall_Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed uint32
Ospeed uint32
}
const (
syscall_IGNBRK = 0x1
syscall_BRKINT = 0x2
syscall_PARMRK = 0x8
syscall_ISTRIP = 0x20
syscall_INLCR = 0x40
syscall_IGNCR = 0x80
syscall_ICRNL = 0x100
syscall_IXON = 0x200
syscall_OPOST = 0x1
syscall_ECHO = 0x8
syscall_ECHONL = 0x10
syscall_ICANON = 0x100
syscall_ISIG = 0x80
syscall_IEXTEN = 0x400
syscall_CSIZE = 0x300
syscall_PARENB = 0x1000
syscall_CS8 = 0x300
syscall_VMIN = 0x10
syscall_VTIME = 0x11
syscall_TCGETS = 0x402c7413
syscall_TCSETS = 0x802c7414
)

33
vendor/github.com/nsf/termbox-go/syscalls_linux.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
package termbox
import "syscall"
type syscall_Termios syscall.Termios
const (
syscall_IGNBRK = syscall.IGNBRK
syscall_BRKINT = syscall.BRKINT
syscall_PARMRK = syscall.PARMRK
syscall_ISTRIP = syscall.ISTRIP
syscall_INLCR = syscall.INLCR
syscall_IGNCR = syscall.IGNCR
syscall_ICRNL = syscall.ICRNL
syscall_IXON = syscall.IXON
syscall_OPOST = syscall.OPOST
syscall_ECHO = syscall.ECHO
syscall_ECHONL = syscall.ECHONL
syscall_ICANON = syscall.ICANON
syscall_ISIG = syscall.ISIG
syscall_IEXTEN = syscall.IEXTEN
syscall_CSIZE = syscall.CSIZE
syscall_PARENB = syscall.PARENB
syscall_CS8 = syscall.CS8
syscall_VMIN = syscall.VMIN
syscall_VTIME = syscall.VTIME
syscall_TCGETS = syscall.TCGETS
syscall_TCSETS = syscall.TCSETS
)

39
vendor/github.com/nsf/termbox-go/syscalls_netbsd.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
package termbox
type syscall_Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed int32
Ospeed int32
}
const (
syscall_IGNBRK = 0x1
syscall_BRKINT = 0x2
syscall_PARMRK = 0x8
syscall_ISTRIP = 0x20
syscall_INLCR = 0x40
syscall_IGNCR = 0x80
syscall_ICRNL = 0x100
syscall_IXON = 0x200
syscall_OPOST = 0x1
syscall_ECHO = 0x8
syscall_ECHONL = 0x10
syscall_ICANON = 0x100
syscall_ISIG = 0x80
syscall_IEXTEN = 0x400
syscall_CSIZE = 0x300
syscall_PARENB = 0x1000
syscall_CS8 = 0x300
syscall_VMIN = 0x10
syscall_VTIME = 0x11
syscall_TCGETS = 0x402c7413
syscall_TCSETS = 0x802c7414
)

39
vendor/github.com/nsf/termbox-go/syscalls_openbsd.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs syscalls.go
package termbox
type syscall_Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed int32
Ospeed int32
}
const (
syscall_IGNBRK = 0x1
syscall_BRKINT = 0x2
syscall_PARMRK = 0x8
syscall_ISTRIP = 0x20
syscall_INLCR = 0x40
syscall_IGNCR = 0x80
syscall_ICRNL = 0x100
syscall_IXON = 0x200
syscall_OPOST = 0x1
syscall_ECHO = 0x8
syscall_ECHONL = 0x10
syscall_ICANON = 0x100
syscall_ISIG = 0x80
syscall_IEXTEN = 0x400
syscall_CSIZE = 0x300
syscall_PARENB = 0x1000
syscall_CS8 = 0x300
syscall_VMIN = 0x10
syscall_VTIME = 0x11
syscall_TCGETS = 0x402c7413
syscall_TCSETS = 0x802c7414
)

61
vendor/github.com/nsf/termbox-go/syscalls_windows.go generated vendored Normal file
View File

@ -0,0 +1,61 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs -- -DUNICODE syscalls.go
package termbox
const (
foreground_blue = 0x1
foreground_green = 0x2
foreground_red = 0x4
foreground_intensity = 0x8
background_blue = 0x10
background_green = 0x20
background_red = 0x40
background_intensity = 0x80
std_input_handle = -0xa
std_output_handle = -0xb
key_event = 0x1
mouse_event = 0x2
window_buffer_size_event = 0x4
enable_window_input = 0x8
enable_mouse_input = 0x10
enable_extended_flags = 0x80
vk_f1 = 0x70
vk_f2 = 0x71
vk_f3 = 0x72
vk_f4 = 0x73
vk_f5 = 0x74
vk_f6 = 0x75
vk_f7 = 0x76
vk_f8 = 0x77
vk_f9 = 0x78
vk_f10 = 0x79
vk_f11 = 0x7a
vk_f12 = 0x7b
vk_insert = 0x2d
vk_delete = 0x2e
vk_home = 0x24
vk_end = 0x23
vk_pgup = 0x21
vk_pgdn = 0x22
vk_arrow_up = 0x26
vk_arrow_down = 0x28
vk_arrow_left = 0x25
vk_arrow_right = 0x27
vk_backspace = 0x8
vk_tab = 0x9
vk_enter = 0xd
vk_esc = 0x1b
vk_space = 0x20
left_alt_pressed = 0x2
left_ctrl_pressed = 0x8
right_alt_pressed = 0x1
right_ctrl_pressed = 0x4
shift_pressed = 0x10
generic_read = 0x80000000
generic_write = 0x40000000
console_textmode_buffer = 0x1
)

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

@ -0,0 +1,511 @@
// +build !windows
package termbox
import "unicode/utf8"
import "bytes"
import "syscall"
import "unsafe"
import "strings"
import "strconv"
import "os"
import "io"
// private API
const (
t_enter_ca = iota
t_exit_ca
t_show_cursor
t_hide_cursor
t_clear_screen
t_sgr0
t_underline
t_bold
t_blink
t_reverse
t_enter_keypad
t_exit_keypad
t_enter_mouse
t_exit_mouse
t_max_funcs
)
const (
coord_invalid = -2
attr_invalid = Attribute(0xFFFF)
)
type input_event struct {
data []byte
err error
}
var (
// term specific sequences
keys []string
funcs []string
// termbox inner state
orig_tios syscall_Termios
back_buffer cellbuf
front_buffer cellbuf
termw int
termh int
input_mode = InputEsc
output_mode = OutputNormal
out *os.File
in int
lastfg = attr_invalid
lastbg = attr_invalid
lastx = coord_invalid
lasty = coord_invalid
cursor_x = cursor_hidden
cursor_y = cursor_hidden
foreground = ColorDefault
background = ColorDefault
inbuf = make([]byte, 0, 64)
outbuf bytes.Buffer
sigwinch = make(chan os.Signal, 1)
sigio = make(chan os.Signal, 1)
quit = make(chan int)
input_comm = make(chan input_event)
interrupt_comm = make(chan struct{})
intbuf = make([]byte, 0, 16)
// grayscale indexes
grayscale = []Attribute{
0, 17, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 232,
}
)
func write_cursor(x, y int) {
outbuf.WriteString("\033[")
outbuf.Write(strconv.AppendUint(intbuf, uint64(y+1), 10))
outbuf.WriteString(";")
outbuf.Write(strconv.AppendUint(intbuf, uint64(x+1), 10))
outbuf.WriteString("H")
}
func write_sgr_fg(a Attribute) {
switch output_mode {
case Output256, Output216, OutputGrayscale:
outbuf.WriteString("\033[38;5;")
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
outbuf.WriteString("m")
default:
outbuf.WriteString("\033[3")
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
outbuf.WriteString("m")
}
}
func write_sgr_bg(a Attribute) {
switch output_mode {
case Output256, Output216, OutputGrayscale:
outbuf.WriteString("\033[48;5;")
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
outbuf.WriteString("m")
default:
outbuf.WriteString("\033[4")
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
outbuf.WriteString("m")
}
}
func write_sgr(fg, bg Attribute) {
switch output_mode {
case Output256, Output216, OutputGrayscale:
outbuf.WriteString("\033[38;5;")
outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10))
outbuf.WriteString("m")
outbuf.WriteString("\033[48;5;")
outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10))
outbuf.WriteString("m")
default:
outbuf.WriteString("\033[3")
outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10))
outbuf.WriteString(";4")
outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10))
outbuf.WriteString("m")
}
}
type winsize struct {
rows uint16
cols uint16
xpixels uint16
ypixels uint16
}
func get_term_size(fd uintptr) (int, int) {
var sz winsize
_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
return int(sz.cols), int(sz.rows)
}
func send_attr(fg, bg Attribute) {
if fg == lastfg && bg == lastbg {
return
}
outbuf.WriteString(funcs[t_sgr0])
var fgcol, bgcol Attribute
switch output_mode {
case Output256:
fgcol = fg & 0x1FF
bgcol = bg & 0x1FF
case Output216:
fgcol = fg & 0xFF
bgcol = bg & 0xFF
if fgcol > 216 {
fgcol = ColorDefault
}
if bgcol > 216 {
bgcol = ColorDefault
}
if fgcol != ColorDefault {
fgcol += 0x10
}
if bgcol != ColorDefault {
bgcol += 0x10
}
case OutputGrayscale:
fgcol = fg & 0x1F
bgcol = bg & 0x1F
if fgcol > 26 {
fgcol = ColorDefault
}
if bgcol > 26 {
bgcol = ColorDefault
}
if fgcol != ColorDefault {
fgcol = grayscale[fgcol]
}
if bgcol != ColorDefault {
bgcol = grayscale[bgcol]
}
default:
fgcol = fg & 0x0F
bgcol = bg & 0x0F
}
if fgcol != ColorDefault {
if bgcol != ColorDefault {
write_sgr(fgcol, bgcol)
} else {
write_sgr_fg(fgcol)
}
} else if bgcol != ColorDefault {
write_sgr_bg(bgcol)
}
if fg&AttrBold != 0 {
outbuf.WriteString(funcs[t_bold])
}
if bg&AttrBold != 0 {
outbuf.WriteString(funcs[t_blink])
}
if fg&AttrUnderline != 0 {
outbuf.WriteString(funcs[t_underline])
}
if fg&AttrReverse|bg&AttrReverse != 0 {
outbuf.WriteString(funcs[t_reverse])
}
lastfg, lastbg = fg, bg
}
func send_char(x, y int, ch rune) {
var buf [8]byte
n := utf8.EncodeRune(buf[:], ch)
if x-1 != lastx || y != lasty {
write_cursor(x, y)
}
lastx, lasty = x, y
outbuf.Write(buf[:n])
}
func flush() error {
_, err := io.Copy(out, &outbuf)
outbuf.Reset()
return err
}
func send_clear() error {
send_attr(foreground, background)
outbuf.WriteString(funcs[t_clear_screen])
if !is_cursor_hidden(cursor_x, cursor_y) {
write_cursor(cursor_x, cursor_y)
}
// we need to invalidate cursor position too and these two vars are
// used only for simple cursor positioning optimization, cursor
// actually may be in the correct place, but we simply discard
// optimization once and it gives us simple solution for the case when
// cursor moved
lastx = coord_invalid
lasty = coord_invalid
return flush()
}
func update_size_maybe() error {
w, h := get_term_size(out.Fd())
if w != termw || h != termh {
termw, termh = w, h
back_buffer.resize(termw, termh)
front_buffer.resize(termw, termh)
front_buffer.clear()
return send_clear()
}
return nil
}
func tcsetattr(fd uintptr, termios *syscall_Termios) error {
r, _, e := syscall.Syscall(syscall.SYS_IOCTL,
fd, uintptr(syscall_TCSETS), uintptr(unsafe.Pointer(termios)))
if r != 0 {
return os.NewSyscallError("SYS_IOCTL", e)
}
return nil
}
func tcgetattr(fd uintptr, termios *syscall_Termios) error {
r, _, e := syscall.Syscall(syscall.SYS_IOCTL,
fd, uintptr(syscall_TCGETS), uintptr(unsafe.Pointer(termios)))
if r != 0 {
return os.NewSyscallError("SYS_IOCTL", e)
}
return nil
}
func parse_mouse_event(event *Event, buf string) (int, bool) {
if strings.HasPrefix(buf, "\033[M") && len(buf) >= 6 {
// X10 mouse encoding, the simplest one
// \033 [ M Cb Cx Cy
b := buf[3] - 32
switch b & 3 {
case 0:
if b&64 != 0 {
event.Key = MouseWheelUp
} else {
event.Key = MouseLeft
}
case 1:
if b&64 != 0 {
event.Key = MouseWheelDown
} else {
event.Key = MouseMiddle
}
case 2:
event.Key = MouseRight
case 3:
event.Key = MouseRelease
default:
return 6, false
}
event.Type = EventMouse // KeyEvent by default
if b&32 != 0 {
event.Mod |= ModMotion
}
// the coord is 1,1 for upper left
event.MouseX = int(buf[4]) - 1 - 32
event.MouseY = int(buf[5]) - 1 - 32
return 6, true
} else if strings.HasPrefix(buf, "\033[<") || strings.HasPrefix(buf, "\033[") {
// xterm 1006 extended mode or urxvt 1015 extended mode
// xterm: \033 [ < Cb ; Cx ; Cy (M or m)
// urxvt: \033 [ Cb ; Cx ; Cy M
// find the first M or m, that's where we stop
mi := strings.IndexAny(buf, "Mm")
if mi == -1 {
return 0, false
}
// whether it's a capital M or not
isM := buf[mi] == 'M'
// whether it's urxvt or not
isU := false
// buf[2] is safe here, because having M or m found means we have at
// least 3 bytes in a string
if buf[2] == '<' {
buf = buf[3:mi]
} else {
isU = true
buf = buf[2:mi]
}
s1 := strings.Index(buf, ";")
s2 := strings.LastIndex(buf, ";")
// not found or only one ';'
if s1 == -1 || s2 == -1 || s1 == s2 {
return 0, false
}
n1, err := strconv.ParseInt(buf[0:s1], 10, 64)
if err != nil {
return 0, false
}
n2, err := strconv.ParseInt(buf[s1+1:s2], 10, 64)
if err != nil {
return 0, false
}
n3, err := strconv.ParseInt(buf[s2+1:], 10, 64)
if err != nil {
return 0, false
}
// on urxvt, first number is encoded exactly as in X10, but we need to
// make it zero-based, on xterm it is zero-based already
if isU {
n1 -= 32
}
switch n1 & 3 {
case 0:
if n1&64 != 0 {
event.Key = MouseWheelUp
} else {
event.Key = MouseLeft
}
case 1:
if n1&64 != 0 {
event.Key = MouseWheelDown
} else {
event.Key = MouseMiddle
}
case 2:
event.Key = MouseRight
case 3:
event.Key = MouseRelease
default:
return mi + 1, false
}
if !isM {
// on xterm mouse release is signaled by lowercase m
event.Key = MouseRelease
}
event.Type = EventMouse // KeyEvent by default
if n1&32 != 0 {
event.Mod |= ModMotion
}
event.MouseX = int(n2) - 1
event.MouseY = int(n3) - 1
return mi + 1, true
}
return 0, false
}
func parse_escape_sequence(event *Event, buf []byte) (int, bool) {
bufstr := string(buf)
for i, key := range keys {
if strings.HasPrefix(bufstr, key) {
event.Ch = 0
event.Key = Key(0xFFFF - i)
return len(key), true
}
}
// if none of the keys match, let's try mouse seqences
return parse_mouse_event(event, bufstr)
}
func extract_raw_event(data []byte, event *Event) bool {
if len(inbuf) == 0 {
return false
}
n := len(data)
if n == 0 {
return false
}
n = copy(data, inbuf)
copy(inbuf, inbuf[n:])
inbuf = inbuf[:len(inbuf)-n]
event.N = n
event.Type = EventRaw
return true
}
func extract_event(inbuf []byte, event *Event) bool {
if len(inbuf) == 0 {
event.N = 0
return false
}
if inbuf[0] == '\033' {
// possible escape sequence
if n, ok := parse_escape_sequence(event, inbuf); n != 0 {
event.N = n
return ok
}
// it's not escape sequence, then it's Alt or Esc, check input_mode
switch {
case input_mode&InputEsc != 0:
// if we're in escape mode, fill Esc event, pop buffer, return success
event.Ch = 0
event.Key = KeyEsc
event.Mod = 0
event.N = 1
return true
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 {
event.N++
} else {
event.N = 0
}
return ok
default:
panic("unreachable")
}
}
// if we're here, this is not an escape sequence and not an alt sequence
// so, it's a FUNCTIONAL KEY or a UNICODE character
// first of all check if it's a functional key
if Key(inbuf[0]) <= KeySpace || Key(inbuf[0]) == KeyBackspace2 {
// fill event, pop buffer, return success
event.Ch = 0
event.Key = Key(inbuf[0])
event.N = 1
return true
}
// the only possible option is utf8 rune
if r, n := utf8.DecodeRune(inbuf); r != utf8.RuneError {
event.Ch = r
event.Key = 0
event.N = n
return true
}
return false
}
func fcntl(fd int, cmd int, arg int) (val int, err error) {
r, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd),
uintptr(arg))
val = int(r)
if e != 0 {
err = e
}
return
}

59
vendor/github.com/nsf/termbox-go/termbox_common.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
package termbox
// private API, common OS agnostic part
type cellbuf struct {
width int
height int
cells []Cell
}
func (this *cellbuf) init(width, height int) {
this.width = width
this.height = height
this.cells = make([]Cell, width*height)
}
func (this *cellbuf) resize(width, height int) {
if this.width == width && this.height == height {
return
}
oldw := this.width
oldh := this.height
oldcells := this.cells
this.init(width, height)
this.clear()
minw, minh := oldw, oldh
if width < minw {
minw = width
}
if height < minh {
minh = height
}
for i := 0; i < minh; i++ {
srco, dsto := i*oldw, i*width
src := oldcells[srco : srco+minw]
dst := this.cells[dsto : dsto+minw]
copy(dst, src)
}
}
func (this *cellbuf) clear() {
for i := range this.cells {
c := &this.cells[i]
c.Ch = ' '
c.Fg = foreground
c.Bg = background
}
}
const cursor_hidden = -1
func is_cursor_hidden(x, y int) bool {
return x == cursor_hidden || y == cursor_hidden
}

856
vendor/github.com/nsf/termbox-go/termbox_windows.go generated vendored Normal file
View File

@ -0,0 +1,856 @@
package termbox
import "syscall"
import "unsafe"
import "unicode/utf16"
import "github.com/mattn/go-runewidth"
type (
wchar uint16
short int16
dword uint32
word uint16
char_info struct {
char wchar
attr word
}
coord struct {
x short
y short
}
small_rect struct {
left short
top short
right short
bottom short
}
console_screen_buffer_info struct {
size coord
cursor_position coord
attributes word
window small_rect
maximum_window_size coord
}
console_cursor_info struct {
size dword
visible int32
}
input_record struct {
event_type word
_ [2]byte
event [16]byte
}
key_event_record struct {
key_down int32
repeat_count word
virtual_key_code word
virtual_scan_code word
unicode_char wchar
control_key_state dword
}
window_buffer_size_record struct {
size coord
}
mouse_event_record struct {
mouse_pos coord
button_state dword
control_key_state dword
event_flags dword
}
)
const (
mouse_lmb = 0x1
mouse_rmb = 0x2
mouse_mmb = 0x4 | 0x8 | 0x10
)
func (this coord) uintptr() uintptr {
return uintptr(*(*int32)(unsafe.Pointer(&this)))
}
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var is_cjk = runewidth.IsEastAsian()
var (
proc_set_console_active_screen_buffer = kernel32.NewProc("SetConsoleActiveScreenBuffer")
proc_set_console_screen_buffer_size = kernel32.NewProc("SetConsoleScreenBufferSize")
proc_create_console_screen_buffer = kernel32.NewProc("CreateConsoleScreenBuffer")
proc_get_console_screen_buffer_info = kernel32.NewProc("GetConsoleScreenBufferInfo")
proc_write_console_output = kernel32.NewProc("WriteConsoleOutputW")
proc_write_console_output_character = kernel32.NewProc("WriteConsoleOutputCharacterW")
proc_write_console_output_attribute = kernel32.NewProc("WriteConsoleOutputAttribute")
proc_set_console_cursor_info = kernel32.NewProc("SetConsoleCursorInfo")
proc_set_console_cursor_position = kernel32.NewProc("SetConsoleCursorPosition")
proc_get_console_cursor_info = kernel32.NewProc("GetConsoleCursorInfo")
proc_read_console_input = kernel32.NewProc("ReadConsoleInputW")
proc_get_console_mode = kernel32.NewProc("GetConsoleMode")
proc_set_console_mode = kernel32.NewProc("SetConsoleMode")
proc_fill_console_output_character = kernel32.NewProc("FillConsoleOutputCharacterW")
proc_fill_console_output_attribute = kernel32.NewProc("FillConsoleOutputAttribute")
proc_create_event = kernel32.NewProc("CreateEventW")
proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects")
proc_set_event = kernel32.NewProc("SetEvent")
)
func set_console_active_screen_buffer(h syscall.Handle) (err error) {
r0, _, e1 := syscall.Syscall(proc_set_console_active_screen_buffer.Addr(),
1, uintptr(h), 0, 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func set_console_screen_buffer_size(h syscall.Handle, size coord) (err error) {
r0, _, e1 := syscall.Syscall(proc_set_console_screen_buffer_size.Addr(),
2, uintptr(h), size.uintptr(), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func create_console_screen_buffer() (h syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall6(proc_create_console_screen_buffer.Addr(),
5, uintptr(generic_read|generic_write), 0, 0, console_textmode_buffer, 0, 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return syscall.Handle(r0), err
}
func get_console_screen_buffer_info(h syscall.Handle, info *console_screen_buffer_info) (err error) {
r0, _, e1 := syscall.Syscall(proc_get_console_screen_buffer_info.Addr(),
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func write_console_output(h syscall.Handle, chars []char_info, dst small_rect) (err error) {
tmp_coord = coord{dst.right - dst.left + 1, dst.bottom - dst.top + 1}
tmp_rect = dst
r0, _, e1 := syscall.Syscall6(proc_write_console_output.Addr(),
5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), tmp_coord.uintptr(),
tmp_coord0.uintptr(), uintptr(unsafe.Pointer(&tmp_rect)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func write_console_output_character(h syscall.Handle, chars []wchar, pos coord) (err error) {
r0, _, e1 := syscall.Syscall6(proc_write_console_output_character.Addr(),
5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), uintptr(len(chars)),
pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func write_console_output_attribute(h syscall.Handle, attrs []word, pos coord) (err error) {
r0, _, e1 := syscall.Syscall6(proc_write_console_output_attribute.Addr(),
5, uintptr(h), uintptr(unsafe.Pointer(&attrs[0])), uintptr(len(attrs)),
pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func set_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) {
r0, _, e1 := syscall.Syscall(proc_set_console_cursor_info.Addr(),
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func get_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) {
r0, _, e1 := syscall.Syscall(proc_get_console_cursor_info.Addr(),
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func set_console_cursor_position(h syscall.Handle, pos coord) (err error) {
r0, _, e1 := syscall.Syscall(proc_set_console_cursor_position.Addr(),
2, uintptr(h), pos.uintptr(), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func read_console_input(h syscall.Handle, record *input_record) (err error) {
r0, _, e1 := syscall.Syscall6(proc_read_console_input.Addr(),
4, uintptr(h), uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&tmp_arg)), 0, 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func get_console_mode(h syscall.Handle, mode *dword) (err error) {
r0, _, e1 := syscall.Syscall(proc_get_console_mode.Addr(),
2, uintptr(h), uintptr(unsafe.Pointer(mode)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func set_console_mode(h syscall.Handle, mode dword) (err error) {
r0, _, e1 := syscall.Syscall(proc_set_console_mode.Addr(),
2, uintptr(h), uintptr(mode), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func fill_console_output_character(h syscall.Handle, char wchar, n int) (err error) {
r0, _, e1 := syscall.Syscall6(proc_fill_console_output_character.Addr(),
5, uintptr(h), uintptr(char), uintptr(n), tmp_coord.uintptr(),
uintptr(unsafe.Pointer(&tmp_arg)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func fill_console_output_attribute(h syscall.Handle, attr word, n int) (err error) {
r0, _, e1 := syscall.Syscall6(proc_fill_console_output_attribute.Addr(),
5, uintptr(h), uintptr(attr), uintptr(n), tmp_coord.uintptr(),
uintptr(unsafe.Pointer(&tmp_arg)), 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func create_event() (out syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall6(proc_create_event.Addr(),
4, 0, 0, 0, 0, 0, 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return syscall.Handle(r0), err
}
func wait_for_multiple_objects(objects []syscall.Handle) (err error) {
r0, _, e1 := syscall.Syscall6(proc_wait_for_multiple_objects.Addr(),
4, uintptr(len(objects)), uintptr(unsafe.Pointer(&objects[0])),
0, 0xFFFFFFFF, 0, 0)
if uint32(r0) == 0xFFFFFFFF {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func set_event(ev syscall.Handle) (err error) {
r0, _, e1 := syscall.Syscall(proc_set_event.Addr(),
1, uintptr(ev), 0, 0)
if int(r0) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
type diff_msg struct {
pos short
lines short
chars []char_info
}
type input_event struct {
event Event
err error
}
var (
orig_cursor_info console_cursor_info
orig_size coord
orig_mode dword
orig_screen syscall.Handle
back_buffer cellbuf
front_buffer cellbuf
term_size coord
input_mode = InputEsc
cursor_x = cursor_hidden
cursor_y = cursor_hidden
foreground = ColorDefault
background = ColorDefault
in syscall.Handle
out syscall.Handle
interrupt syscall.Handle
charbuf []char_info
diffbuf []diff_msg
beg_x = -1
beg_y = -1
beg_i = -1
input_comm = make(chan Event)
interrupt_comm = make(chan struct{})
cancel_comm = make(chan bool, 1)
cancel_done_comm = make(chan bool)
alt_mode_esc = false
// these ones just to prevent heap allocs at all costs
tmp_info console_screen_buffer_info
tmp_arg dword
tmp_coord0 = coord{0, 0}
tmp_coord = coord{0, 0}
tmp_rect = small_rect{0, 0, 0, 0}
)
func get_cursor_position(out syscall.Handle) coord {
err := get_console_screen_buffer_info(out, &tmp_info)
if err != nil {
panic(err)
}
return tmp_info.cursor_position
}
func get_term_size(out syscall.Handle) coord {
err := get_console_screen_buffer_info(out, &tmp_info)
if err != nil {
panic(err)
}
return tmp_info.size
}
func get_win_size(out syscall.Handle) coord {
err := get_console_screen_buffer_info(out, &tmp_info)
if err != nil {
panic(err)
}
return coord{
x: tmp_info.window.right - tmp_info.window.left + 1,
y: tmp_info.window.bottom - tmp_info.window.top + 1,
}
}
func update_size_maybe() {
size := get_term_size(out)
if size.x != term_size.x || size.y != term_size.y {
term_size = size
back_buffer.resize(int(size.x), int(size.y))
front_buffer.resize(int(size.x), int(size.y))
front_buffer.clear()
clear()
area := int(size.x) * int(size.y)
if cap(charbuf) < area {
charbuf = make([]char_info, 0, area)
}
}
}
var color_table_bg = []word{
0, // default (black)
0, // black
background_red,
background_green,
background_red | background_green, // yellow
background_blue,
background_red | background_blue, // magenta
background_green | background_blue, // cyan
background_red | background_blue | background_green, // white
}
var color_table_fg = []word{
foreground_red | foreground_blue | foreground_green, // default (white)
0,
foreground_red,
foreground_green,
foreground_red | foreground_green, // yellow
foreground_blue,
foreground_red | foreground_blue, // magenta
foreground_green | foreground_blue, // cyan
foreground_red | foreground_blue | foreground_green, // white
}
const (
replacement_char = '\uFFFD'
max_rune = '\U0010FFFF'
surr1 = 0xd800
surr2 = 0xdc00
surr3 = 0xe000
surr_self = 0x10000
)
func append_diff_line(y int) int {
n := 0
for x := 0; x < front_buffer.width; {
cell_offset := y*front_buffer.width + x
back := &back_buffer.cells[cell_offset]
front := &front_buffer.cells[cell_offset]
attr, char := cell_to_char_info(*back)
charbuf = append(charbuf, char_info{attr: attr, char: char[0]})
*front = *back
n++
w := runewidth.RuneWidth(back.Ch)
if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) {
w = 1
}
x += w
// If not CJK, fill trailing space with whitespace
if !is_cjk && w == 2 {
charbuf = append(charbuf, char_info{attr: attr, char: ' '})
}
}
return n
}
// compares 'back_buffer' with 'front_buffer' and prepares all changes in the form of
// 'diff_msg's in the 'diff_buf'
func prepare_diff_messages() {
// clear buffers
diffbuf = diffbuf[:0]
charbuf = charbuf[:0]
var diff diff_msg
gbeg := 0
for y := 0; y < front_buffer.height; y++ {
same := true
line_offset := y * front_buffer.width
for x := 0; x < front_buffer.width; x++ {
cell_offset := line_offset + x
back := &back_buffer.cells[cell_offset]
front := &front_buffer.cells[cell_offset]
if *back != *front {
same = false
break
}
}
if same && diff.lines > 0 {
diffbuf = append(diffbuf, diff)
diff = diff_msg{}
}
if !same {
beg := len(charbuf)
end := beg + append_diff_line(y)
if diff.lines == 0 {
diff.pos = short(y)
gbeg = beg
}
diff.lines++
diff.chars = charbuf[gbeg:end]
}
}
if diff.lines > 0 {
diffbuf = append(diffbuf, diff)
diff = diff_msg{}
}
}
func get_ct(table []word, idx int) word {
idx = idx & 0x0F
if idx >= len(table) {
idx = len(table) - 1
}
return table[idx]
}
func cell_to_char_info(c Cell) (attr word, wc [2]wchar) {
attr = get_ct(color_table_fg, int(c.Fg)) | get_ct(color_table_bg, int(c.Bg))
if c.Fg&AttrReverse|c.Bg&AttrReverse != 0 {
attr = (attr&0xF0)>>4 | (attr&0x0F)<<4
}
if c.Fg&AttrBold != 0 {
attr |= foreground_intensity
}
if c.Bg&AttrBold != 0 {
attr |= background_intensity
}
r0, r1 := utf16.EncodeRune(c.Ch)
if r0 == 0xFFFD {
wc[0] = wchar(c.Ch)
wc[1] = ' '
} else {
wc[0] = wchar(r0)
wc[1] = wchar(r1)
}
return
}
func move_cursor(x, y int) {
err := set_console_cursor_position(out, coord{short(x), short(y)})
if err != nil {
panic(err)
}
}
func show_cursor(visible bool) {
var v int32
if visible {
v = 1
}
var info console_cursor_info
info.size = 100
info.visible = v
err := set_console_cursor_info(out, &info)
if err != nil {
panic(err)
}
}
func clear() {
var err error
attr, char := cell_to_char_info(Cell{
' ',
foreground,
background,
})
area := int(term_size.x) * int(term_size.y)
err = fill_console_output_attribute(out, attr, area)
if err != nil {
panic(err)
}
err = fill_console_output_character(out, char[0], area)
if err != nil {
panic(err)
}
if !is_cursor_hidden(cursor_x, cursor_y) {
move_cursor(cursor_x, cursor_y)
}
}
func key_event_record_to_event(r *key_event_record) (Event, bool) {
if r.key_down == 0 {
return Event{}, false
}
e := Event{Type: EventKey}
if input_mode&InputAlt != 0 {
if alt_mode_esc {
e.Mod = ModAlt
alt_mode_esc = false
}
if r.control_key_state&(left_alt_pressed|right_alt_pressed) != 0 {
e.Mod = ModAlt
}
}
ctrlpressed := r.control_key_state&(left_ctrl_pressed|right_ctrl_pressed) != 0
if r.virtual_key_code >= vk_f1 && r.virtual_key_code <= vk_f12 {
switch r.virtual_key_code {
case vk_f1:
e.Key = KeyF1
case vk_f2:
e.Key = KeyF2
case vk_f3:
e.Key = KeyF3
case vk_f4:
e.Key = KeyF4
case vk_f5:
e.Key = KeyF5
case vk_f6:
e.Key = KeyF6
case vk_f7:
e.Key = KeyF7
case vk_f8:
e.Key = KeyF8
case vk_f9:
e.Key = KeyF9
case vk_f10:
e.Key = KeyF10
case vk_f11:
e.Key = KeyF11
case vk_f12:
e.Key = KeyF12
default:
panic("unreachable")
}
return e, true
}
if r.virtual_key_code <= vk_delete {
switch r.virtual_key_code {
case vk_insert:
e.Key = KeyInsert
case vk_delete:
e.Key = KeyDelete
case vk_home:
e.Key = KeyHome
case vk_end:
e.Key = KeyEnd
case vk_pgup:
e.Key = KeyPgup
case vk_pgdn:
e.Key = KeyPgdn
case vk_arrow_up:
e.Key = KeyArrowUp
case vk_arrow_down:
e.Key = KeyArrowDown
case vk_arrow_left:
e.Key = KeyArrowLeft
case vk_arrow_right:
e.Key = KeyArrowRight
case vk_backspace:
if ctrlpressed {
e.Key = KeyBackspace2
} else {
e.Key = KeyBackspace
}
case vk_tab:
e.Key = KeyTab
case vk_enter:
e.Key = KeyEnter
case vk_esc:
switch {
case input_mode&InputEsc != 0:
e.Key = KeyEsc
case input_mode&InputAlt != 0:
alt_mode_esc = true
return Event{}, false
}
case vk_space:
if ctrlpressed {
// manual return here, because KeyCtrlSpace is zero
e.Key = KeyCtrlSpace
return e, true
} else {
e.Key = KeySpace
}
}
if e.Key != 0 {
return e, true
}
}
if ctrlpressed {
if Key(r.unicode_char) >= KeyCtrlA && Key(r.unicode_char) <= KeyCtrlRsqBracket {
e.Key = Key(r.unicode_char)
if input_mode&InputAlt != 0 && e.Key == KeyEsc {
alt_mode_esc = true
return Event{}, false
}
return e, true
}
switch r.virtual_key_code {
case 192, 50:
// manual return here, because KeyCtrl2 is zero
e.Key = KeyCtrl2
return e, true
case 51:
if input_mode&InputAlt != 0 {
alt_mode_esc = true
return Event{}, false
}
e.Key = KeyCtrl3
case 52:
e.Key = KeyCtrl4
case 53:
e.Key = KeyCtrl5
case 54:
e.Key = KeyCtrl6
case 189, 191, 55:
e.Key = KeyCtrl7
case 8, 56:
e.Key = KeyCtrl8
}
if e.Key != 0 {
return e, true
}
}
if r.unicode_char != 0 {
e.Ch = rune(r.unicode_char)
return e, true
}
return Event{}, false
}
func input_event_producer() {
var r input_record
var err error
var last_button Key
var last_button_pressed Key
var last_state = dword(0)
var last_x, last_y = -1, -1
handles := []syscall.Handle{in, interrupt}
for {
err = wait_for_multiple_objects(handles)
if err != nil {
input_comm <- Event{Type: EventError, Err: err}
}
select {
case <-cancel_comm:
cancel_done_comm <- true
return
default:
}
err = read_console_input(in, &r)
if err != nil {
input_comm <- Event{Type: EventError, Err: err}
}
switch r.event_type {
case key_event:
kr := (*key_event_record)(unsafe.Pointer(&r.event))
ev, ok := key_event_record_to_event(kr)
if ok {
for i := 0; i < int(kr.repeat_count); i++ {
input_comm <- ev
}
}
case window_buffer_size_event:
sr := *(*window_buffer_size_record)(unsafe.Pointer(&r.event))
input_comm <- Event{
Type: EventResize,
Width: int(sr.size.x),
Height: int(sr.size.y),
}
case mouse_event:
mr := *(*mouse_event_record)(unsafe.Pointer(&r.event))
ev := Event{Type: EventMouse}
switch mr.event_flags {
case 0, 2:
// single or double click
cur_state := mr.button_state
switch {
case last_state&mouse_lmb == 0 && cur_state&mouse_lmb != 0:
last_button = MouseLeft
last_button_pressed = last_button
case last_state&mouse_rmb == 0 && cur_state&mouse_rmb != 0:
last_button = MouseRight
last_button_pressed = last_button
case last_state&mouse_mmb == 0 && cur_state&mouse_mmb != 0:
last_button = MouseMiddle
last_button_pressed = last_button
case last_state&mouse_lmb != 0 && cur_state&mouse_lmb == 0:
last_button = MouseRelease
case last_state&mouse_rmb != 0 && cur_state&mouse_rmb == 0:
last_button = MouseRelease
case last_state&mouse_mmb != 0 && cur_state&mouse_mmb == 0:
last_button = MouseRelease
default:
last_state = cur_state
continue
}
last_state = cur_state
ev.Key = last_button
last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y)
ev.MouseX = last_x
ev.MouseY = last_y
case 1:
// mouse motion
x, y := int(mr.mouse_pos.x), int(mr.mouse_pos.y)
if last_state != 0 && (last_x != x || last_y != y) {
ev.Key = last_button_pressed
ev.Mod = ModMotion
ev.MouseX = x
ev.MouseY = y
last_x, last_y = x, y
} else {
ev.Type = EventNone
}
case 4:
// mouse wheel
n := int16(mr.button_state >> 16)
if n > 0 {
ev.Key = MouseWheelUp
} else {
ev.Key = MouseWheelDown
}
last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y)
ev.MouseX = last_x
ev.MouseY = last_y
default:
ev.Type = EventNone
}
if ev.Type != EventNone {
input_comm <- ev
}
}
}
}

221
vendor/github.com/nsf/termbox-go/terminfo.go generated vendored Normal file
View File

@ -0,0 +1,221 @@
// +build !windows
// This file contains a simple and incomplete implementation of the terminfo
// database. Information was taken from the ncurses manpages term(5) and
// terminfo(5). Currently, only the string capabilities for special keys and for
// functions without parameters are actually used. Colors are still done with
// ANSI escape sequences. Other special features that are not (yet?) supported
// are reading from ~/.terminfo, the TERMINFO_DIRS variable, Berkeley database
// format and extended capabilities.
package termbox
import (
"bytes"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
)
const (
ti_magic = 0432
ti_header_length = 12
ti_mouse_enter = "\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h"
ti_mouse_leave = "\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l"
)
func load_terminfo() ([]byte, error) {
var data []byte
var err error
term := os.Getenv("TERM")
if term == "" {
return nil, fmt.Errorf("termbox: TERM not set")
}
// The following behaviour follows the one described in terminfo(5) as
// distributed by ncurses.
terminfo := os.Getenv("TERMINFO")
if terminfo != "" {
// if TERMINFO is set, no other directory should be searched
return ti_try_path(terminfo)
}
// next, consider ~/.terminfo
home := os.Getenv("HOME")
if home != "" {
data, err = ti_try_path(home + "/.terminfo")
if err == nil {
return data, nil
}
}
// next, TERMINFO_DIRS
dirs := os.Getenv("TERMINFO_DIRS")
if dirs != "" {
for _, dir := range strings.Split(dirs, ":") {
if dir == "" {
// "" -> "/usr/share/terminfo"
dir = "/usr/share/terminfo"
}
data, err = ti_try_path(dir)
if err == nil {
return data, nil
}
}
}
// fall back to /usr/share/terminfo
return ti_try_path("/usr/share/terminfo")
}
func ti_try_path(path string) (data []byte, err error) {
// load_terminfo already made sure it is set
term := os.Getenv("TERM")
// first try, the typical *nix path
terminfo := path + "/" + term[0:1] + "/" + term
data, err = ioutil.ReadFile(terminfo)
if err == nil {
return
}
// fallback to darwin specific dirs structure
terminfo = path + "/" + hex.EncodeToString([]byte(term[:1])) + "/" + term
data, err = ioutil.ReadFile(terminfo)
return
}
func setup_term_builtin() error {
name := os.Getenv("TERM")
if name == "" {
return errors.New("termbox: TERM environment variable not set")
}
for _, t := range terms {
if t.name == name {
keys = t.keys
funcs = t.funcs
return nil
}
}
compat_table := []struct {
partial string
keys []string
funcs []string
}{
{"xterm", xterm_keys, xterm_funcs},
{"rxvt", rxvt_unicode_keys, rxvt_unicode_funcs},
{"linux", linux_keys, linux_funcs},
{"Eterm", eterm_keys, eterm_funcs},
{"screen", screen_keys, screen_funcs},
// let's assume that 'cygwin' is xterm compatible
{"cygwin", xterm_keys, xterm_funcs},
{"st", xterm_keys, xterm_funcs},
}
// try compatibility variants
for _, it := range compat_table {
if strings.Contains(name, it.partial) {
keys = it.keys
funcs = it.funcs
return nil
}
}
return errors.New("termbox: unsupported terminal")
}
func setup_term() (err error) {
var data []byte
var header [6]int16
var str_offset, table_offset int16
data, err = load_terminfo()
if err != nil {
return setup_term_builtin()
}
rd := bytes.NewReader(data)
// 0: magic number, 1: size of names section, 2: size of boolean section, 3:
// size of numbers section (in integers), 4: size of the strings section (in
// integers), 5: size of the string table
err = binary.Read(rd, binary.LittleEndian, header[:])
if err != nil {
return
}
if (header[1]+header[2])%2 != 0 {
// old quirk to align everything on word boundaries
header[2] += 1
}
str_offset = ti_header_length + header[1] + header[2] + 2*header[3]
table_offset = str_offset + 2*header[4]
keys = make([]string, 0xFFFF-key_min)
for i, _ := range keys {
keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset)
if err != nil {
return
}
}
funcs = make([]string, t_max_funcs)
// the last two entries are reserved for mouse. because the table offset is
// not there, the two entries have to fill in manually
for i, _ := range funcs[:len(funcs)-2] {
funcs[i], err = ti_read_string(rd, str_offset+2*ti_funcs[i], table_offset)
if err != nil {
return
}
}
funcs[t_max_funcs-2] = ti_mouse_enter
funcs[t_max_funcs-1] = ti_mouse_leave
return nil
}
func ti_read_string(rd *bytes.Reader, str_off, table int16) (string, error) {
var off int16
_, err := rd.Seek(int64(str_off), 0)
if err != nil {
return "", err
}
err = binary.Read(rd, binary.LittleEndian, &off)
if err != nil {
return "", err
}
_, err = rd.Seek(int64(table+off), 0)
if err != nil {
return "", err
}
var bs []byte
for {
b, err := rd.ReadByte()
if err != nil {
return "", err
}
if b == byte(0x00) {
break
}
bs = append(bs, b)
}
return string(bs), nil
}
// "Maps" the function constants from termbox.go to the number of the respective
// string capability in the terminfo file. Taken from (ncurses) term.h.
var ti_funcs = []int16{
28, 40, 16, 13, 5, 39, 36, 27, 26, 34, 89, 88,
}
// Same as above for the special keys.
var ti_keys = []int16{
66, 68 /* apparently not a typo; 67 is F10 for whatever reason */, 69, 70,
71, 72, 73, 74, 75, 67, 216, 217, 77, 59, 76, 164, 82, 81, 87, 61, 79, 83,
}

64
vendor/github.com/nsf/termbox-go/terminfo_builtin.go generated vendored Normal file
View File

@ -0,0 +1,64 @@
// +build !windows
package termbox
// Eterm
var eterm_keys = []string{
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
}
var eterm_funcs = []string{
"\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "",
}
// screen
var screen_keys = []string{
"\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC",
}
var screen_funcs = []string{
"\x1b[?1049h", "\x1b[?1049l", "\x1b[34h\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave,
}
// xterm
var xterm_keys = []string{
"\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1bOH", "\x1bOF", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC",
}
var xterm_funcs = []string{
"\x1b[?1049h", "\x1b[?1049l", "\x1b[?12l\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b(B\x1b[m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave,
}
// rxvt-unicode
var rxvt_unicode_keys = []string{
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
}
var rxvt_unicode_funcs = []string{
"\x1b[?1049h", "\x1b[r\x1b[?1049l", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x1b(B", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave,
}
// linux
var linux_keys = []string{
"\x1b[[A", "\x1b[[B", "\x1b[[C", "\x1b[[D", "\x1b[[E", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
}
var linux_funcs = []string{
"", "", "\x1b[?25h\x1b[?0c", "\x1b[?25l\x1b[?1c", "\x1b[H\x1b[J", "\x1b[0;10m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "",
}
// rxvt-256color
var rxvt_256color_keys = []string{
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
}
var rxvt_256color_funcs = []string{
"\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave,
}
var terms = []struct {
name string
keys []string
funcs []string
}{
{"Eterm", eterm_keys, eterm_funcs},
{"screen", screen_keys, screen_funcs},
{"xterm", xterm_keys, xterm_funcs},
{"rxvt-unicode", rxvt_unicode_keys, rxvt_unicode_funcs},
{"linux", linux_keys, linux_funcs},
{"rxvt-256color", rxvt_256color_keys, rxvt_256color_funcs},
}