mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-02 09:21:40 +02:00
no more termbox
This commit is contained in:
parent
1149dea4b2
commit
c0cad91cb6
4
vendor/github.com/jesseduffield/termbox-go/AUTHORS
generated
vendored
4
vendor/github.com/jesseduffield/termbox-go/AUTHORS
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
# Please keep this file sorted.
|
|
||||||
|
|
||||||
Georg Reinke <guelfey@googlemail.com>
|
|
||||||
nsf <no.smile.face@gmail.com>
|
|
19
vendor/github.com/jesseduffield/termbox-go/LICENSE
generated
vendored
19
vendor/github.com/jesseduffield/termbox-go/LICENSE
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
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.
|
|
44
vendor/github.com/jesseduffield/termbox-go/README.md
generated
vendored
44
vendor/github.com/jesseduffield/termbox-go/README.md
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
[![GoDoc](https://godoc.org/github.com/nsf/termbox-go?status.svg)](http://godoc.org/github.com/nsf/termbox-go)
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
- [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/mop-tracker/mop) is stock market tracker for hackers.
|
|
||||||
- [termui](https://github.com/gizak/termui) is a terminal dashboard.
|
|
||||||
- [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine.
|
|
||||||
- [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart.
|
|
||||||
- [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
|
|
||||||
- [jv](https://github.com/maxzender/jv) helps you view JSON on the command-line.
|
|
||||||
- [pinger](https://github.com/hirose31/pinger) helps you to monitor numerous hosts using ICMP ECHO_REQUEST.
|
|
||||||
- [vixl44](https://github.com/sebashwa/vixl44) lets you create pixel art inside your terminal using vim movements
|
|
||||||
- [zterm](https://github.com/varunrau/zterm) is a typing game inspired by http://zty.pe/
|
|
||||||
- [gotypist](https://github.com/pb-/gotypist) is a fun touch-typing tutor following Steve Yegge's method.
|
|
||||||
- [cointop](https://github.com/miguelmota/cointop) is an interactive terminal based UI application for tracking cryptocurrencies.
|
|
||||||
- [pexpo](https://github.com/nnao45/pexpo) is a terminal sending ping tool written in Go.
|
|
||||||
- [jid](https://github.com/simeji/jid) is an interactive JSON drill down tool using filtering queries like jq.
|
|
||||||
|
|
||||||
### API reference
|
|
||||||
[godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go)
|
|
517
vendor/github.com/jesseduffield/termbox-go/api.go
generated
vendored
517
vendor/github.com/jesseduffield/termbox-go/api.go
generated
vendored
@ -1,517 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package termbox
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/mattn/go-runewidth"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
quitPolling = make(chan int)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if runtime.GOOS == "openbsd" || runtime.GOOS == "freebsd" {
|
|
||||||
out, err = os.OpenFile("/dev/tty", os.O_RDWR, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
in = int(out.Fd())
|
|
||||||
} else {
|
|
||||||
out, err = os.OpenFile("/dev/tty", os.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
|
|
||||||
close(quitPolling)
|
|
||||||
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}
|
|
||||||
status := extract_event(data, &event, false)
|
|
||||||
if status != event_extracted {
|
|
||||||
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 {
|
|
||||||
// Constant governing macOS specific behavior. See https://github.com/nsf/termbox-go/issues/132
|
|
||||||
// This is an arbitrary delay which hopefully will be enough time for any lagging
|
|
||||||
// partial escape sequences to come through.
|
|
||||||
const esc_wait_delay = 100 * time.Millisecond
|
|
||||||
|
|
||||||
var event Event
|
|
||||||
var esc_wait_timer *time.Timer
|
|
||||||
var esc_timeout <-chan time.Time
|
|
||||||
|
|
||||||
// try to extract event from input buffer, return on success
|
|
||||||
event.Type = EventKey
|
|
||||||
status := extract_event(inbuf, &event, true)
|
|
||||||
if event.N != 0 {
|
|
||||||
if event.N > len(inbuf) {
|
|
||||||
event.N = len(inbuf)
|
|
||||||
}
|
|
||||||
copy(inbuf, inbuf[event.N:])
|
|
||||||
event.Bytes = append(event.Bytes, inbuf[:event.N]...)
|
|
||||||
inbuf = inbuf[:len(inbuf)-event.N]
|
|
||||||
}
|
|
||||||
if status == event_extracted {
|
|
||||||
return event
|
|
||||||
} else if status == esc_wait {
|
|
||||||
esc_wait_timer = time.NewTimer(esc_wait_delay)
|
|
||||||
esc_timeout = esc_wait_timer.C
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case ev := <-input_comm:
|
|
||||||
if esc_wait_timer != nil {
|
|
||||||
if !esc_wait_timer.Stop() {
|
|
||||||
<-esc_wait_timer.C
|
|
||||||
}
|
|
||||||
esc_wait_timer = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if ev.err != nil {
|
|
||||||
return Event{Type: EventError, Err: ev.err}
|
|
||||||
}
|
|
||||||
|
|
||||||
inbuf = append(inbuf, ev.data...)
|
|
||||||
input_comm <- ev
|
|
||||||
status := extract_event(inbuf, &event, true)
|
|
||||||
if event.N != 0 {
|
|
||||||
if event.N > len(inbuf) {
|
|
||||||
event.N = len(inbuf)
|
|
||||||
}
|
|
||||||
copy(inbuf, inbuf[event.N:])
|
|
||||||
event.Bytes = append(event.Bytes, inbuf[:event.N]...)
|
|
||||||
inbuf = inbuf[:len(inbuf)-event.N]
|
|
||||||
}
|
|
||||||
if status == event_extracted {
|
|
||||||
return event
|
|
||||||
} else if status == esc_wait {
|
|
||||||
esc_wait_timer = time.NewTimer(esc_wait_delay)
|
|
||||||
esc_timeout = esc_wait_timer.C
|
|
||||||
}
|
|
||||||
case <-esc_timeout:
|
|
||||||
esc_wait_timer = nil
|
|
||||||
|
|
||||||
status := extract_event(inbuf, &event, false)
|
|
||||||
if event.N != 0 {
|
|
||||||
if event.N > len(inbuf) {
|
|
||||||
event.N = len(inbuf)
|
|
||||||
}
|
|
||||||
copy(inbuf, inbuf[event.N:])
|
|
||||||
event.Bytes = append(event.Bytes, inbuf[:event.N]...)
|
|
||||||
inbuf = inbuf[:len(inbuf)-event.N]
|
|
||||||
}
|
|
||||||
if status == event_extracted {
|
|
||||||
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
|
|
||||||
case <-quitPolling:
|
|
||||||
return Event{Type: EventStop}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 don't need to provide an offset.
|
|
||||||
//
|
|
||||||
// 4. OutputGrayscale => [1..26]
|
|
||||||
// This mode supports the 4th range of the 256 mode
|
|
||||||
// and black and white colors from 3th range of the 256 mode
|
|
||||||
// But you don't 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()
|
|
||||||
}
|
|
189
vendor/github.com/jesseduffield/termbox-go/api_common.go
generated
vendored
189
vendor/github.com/jesseduffield/termbox-go/api_common.go
generated
vendored
@ -1,189 +0,0 @@
|
|||||||
// 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
|
|
||||||
Bytes []byte // byte array that triggered the 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 attributes.
|
|
||||||
// For example windows console doesn't support AttrUnderline. And on some
|
|
||||||
// terminals applying AttrBold to background may result in blinking text. Use
|
|
||||||
// them with caution and test your code on various terminals.
|
|
||||||
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
|
|
||||||
EventStop
|
|
||||||
)
|
|
239
vendor/github.com/jesseduffield/termbox-go/api_windows.go
generated
vendored
239
vendor/github.com/jesseduffield/termbox-go/api_windows.go
generated
vendored
@ -1,239 +0,0 @@
|
|||||||
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/jesseduffield/termbox-go/collect_terminfo.py
generated
vendored
110
vendor/github.com/jesseduffield/termbox-go/collect_terminfo.py
generated
vendored
@ -1,110 +0,0 @@
|
|||||||
#!/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)
|
|
||||||
|
|
11
vendor/github.com/jesseduffield/termbox-go/escwait.go
generated
vendored
11
vendor/github.com/jesseduffield/termbox-go/escwait.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// +build !darwin
|
|
||||||
|
|
||||||
package termbox
|
|
||||||
|
|
||||||
// On all systems other than macOS, disable behavior which will wait before
|
|
||||||
// deciding that the escape key was pressed, to account for partially send
|
|
||||||
// escape sequences, especially with regard to lengthy mouse sequences.
|
|
||||||
// See https://github.com/nsf/termbox-go/issues/132
|
|
||||||
func enable_wait_for_escape_sequence() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
9
vendor/github.com/jesseduffield/termbox-go/escwait_darwin.go
generated
vendored
9
vendor/github.com/jesseduffield/termbox-go/escwait_darwin.go
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
package termbox
|
|
||||||
|
|
||||||
// On macOS, enable behavior which will wait before deciding that the escape
|
|
||||||
// key was pressed, to account for partially send escape sequences, especially
|
|
||||||
// with regard to lengthy mouse sequences.
|
|
||||||
// See https://github.com/nsf/termbox-go/issues/132
|
|
||||||
func enable_wait_for_escape_sequence() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
41
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin.go
generated
vendored
41
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin.go
generated
vendored
@ -1,41 +0,0 @@
|
|||||||
// 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
|
|
||||||
)
|
|
40
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin_amd64.go
generated
vendored
40
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin_amd64.go
generated
vendored
@ -1,40 +0,0 @@
|
|||||||
// 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/jesseduffield/termbox-go/syscalls_dragonfly.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_dragonfly.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
// 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/jesseduffield/termbox-go/syscalls_freebsd.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_freebsd.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
// 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/jesseduffield/termbox-go/syscalls_linux.go
generated
vendored
33
vendor/github.com/jesseduffield/termbox-go/syscalls_linux.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
// 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/jesseduffield/termbox-go/syscalls_netbsd.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_netbsd.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
// 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/jesseduffield/termbox-go/syscalls_openbsd.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_openbsd.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
// 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/jesseduffield/termbox-go/syscalls_windows.go
generated
vendored
61
vendor/github.com/jesseduffield/termbox-go/syscalls_windows.go
generated
vendored
@ -1,61 +0,0 @@
|
|||||||
// 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
|
|
||||||
)
|
|
532
vendor/github.com/jesseduffield/termbox-go/termbox.go
generated
vendored
532
vendor/github.com/jesseduffield/termbox-go/termbox.go
generated
vendored
@ -1,532 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package termbox
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf8"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
type extract_event_res int
|
|
||||||
|
|
||||||
const (
|
|
||||||
event_not_extracted extract_event_res = iota
|
|
||||||
event_extracted
|
|
||||||
esc_wait
|
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
|
||||||
quitPolling chan int // get set on each initialize
|
|
||||||
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 sequences
|
|
||||||
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, allow_esc_wait bool) extract_event_res {
|
|
||||||
if len(inbuf) == 0 {
|
|
||||||
event.N = 0
|
|
||||||
return event_not_extracted
|
|
||||||
}
|
|
||||||
|
|
||||||
if inbuf[0] == '\033' {
|
|
||||||
// possible escape sequence
|
|
||||||
if n, ok := parse_escape_sequence(event, inbuf); n != 0 {
|
|
||||||
event.N = n
|
|
||||||
if ok {
|
|
||||||
return event_extracted
|
|
||||||
} else {
|
|
||||||
return event_not_extracted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// possible partially read escape sequence; trigger a wait if appropriate
|
|
||||||
if enable_wait_for_escape_sequence() && allow_esc_wait {
|
|
||||||
event.N = 0
|
|
||||||
return esc_wait
|
|
||||||
}
|
|
||||||
|
|
||||||
// it's not escape sequence, then it's Alt or Esc, check input_mode
|
|
||||||
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 event_extracted
|
|
||||||
case input_mode&InputAlt != 0:
|
|
||||||
// if we're in alt mode, set Alt modifier to event and redo parsing
|
|
||||||
event.Mod = ModAlt
|
|
||||||
status := extract_event(inbuf[1:], event, false)
|
|
||||||
if status == event_extracted {
|
|
||||||
event.N++
|
|
||||||
} else {
|
|
||||||
event.N = 0
|
|
||||||
}
|
|
||||||
return status
|
|
||||||
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 event_extracted
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 event_extracted
|
|
||||||
}
|
|
||||||
|
|
||||||
return event_not_extracted
|
|
||||||
}
|
|
||||||
|
|
||||||
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/jesseduffield/termbox-go/termbox_common.go
generated
vendored
59
vendor/github.com/jesseduffield/termbox-go/termbox_common.go
generated
vendored
@ -1,59 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
915
vendor/github.com/jesseduffield/termbox-go/termbox_windows.go
generated
vendored
915
vendor/github.com/jesseduffield/termbox-go/termbox_windows.go
generated
vendored
@ -1,915 +0,0 @@
|
|||||||
package termbox
|
|
||||||
|
|
||||||
import "math"
|
|
||||||
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
|
|
||||||
}
|
|
||||||
console_font_info struct {
|
|
||||||
font uint32
|
|
||||||
font_size coord
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
mouse_lmb = 0x1
|
|
||||||
mouse_rmb = 0x2
|
|
||||||
mouse_mmb = 0x4 | 0x8 | 0x10
|
|
||||||
SM_CXMIN = 28
|
|
||||||
SM_CYMIN = 29
|
|
||||||
)
|
|
||||||
|
|
||||||
func (this coord) uintptr() uintptr {
|
|
||||||
return uintptr(*(*int32)(unsafe.Pointer(&this)))
|
|
||||||
}
|
|
||||||
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
var moduser32 = syscall.NewLazyDLL("user32.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")
|
|
||||||
proc_get_current_console_font = kernel32.NewProc("GetCurrentConsoleFont")
|
|
||||||
get_system_metrics = moduser32.NewProc("GetSystemMetrics")
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func get_current_console_font(h syscall.Handle, info *console_font_info) (err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall(proc_get_current_console_font.Addr(),
|
|
||||||
3, uintptr(h), 0, uintptr(unsafe.Pointer(info)))
|
|
||||||
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}
|
|
||||||
tmp_finfo console_font_info
|
|
||||||
)
|
|
||||||
|
|
||||||
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_min_size(out syscall.Handle) coord {
|
|
||||||
x, _, err := get_system_metrics.Call(SM_CXMIN)
|
|
||||||
y, _, err := get_system_metrics.Call(SM_CYMIN)
|
|
||||||
|
|
||||||
if x == 0 || y == 0 {
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err1 := get_current_console_font(out, &tmp_finfo)
|
|
||||||
if err1 != nil {
|
|
||||||
panic(err1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return coord{
|
|
||||||
x: short(math.Ceil(float64(x) / float64(tmp_finfo.font_size.x))),
|
|
||||||
y: short(math.Ceil(float64(y) / float64(tmp_finfo.font_size.y))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func get_win_size(out syscall.Handle) coord {
|
|
||||||
err := get_console_screen_buffer_info(out, &tmp_info)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
min_size := get_win_min_size(out)
|
|
||||||
|
|
||||||
size := coord{
|
|
||||||
x: tmp_info.window.right - tmp_info.window.left + 1,
|
|
||||||
y: tmp_info.window.bottom - tmp_info.window.top + 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
if size.x < min_size.x {
|
|
||||||
size.x = min_size.x
|
|
||||||
}
|
|
||||||
|
|
||||||
if size.y < min_size.y {
|
|
||||||
size.y = min_size.y
|
|
||||||
}
|
|
||||||
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
func update_size_maybe() {
|
|
||||||
size := get_win_size(out)
|
|
||||||
if size.x != term_size.x || size.y != term_size.y {
|
|
||||||
set_console_screen_buffer_size(out, size)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
233
vendor/github.com/jesseduffield/termbox-go/terminfo.go
generated
vendored
233
vendor/github.com/jesseduffield/termbox-go/terminfo.go
generated
vendored
@ -1,233 +0,0 @@
|
|||||||
// +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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// next, /lib/terminfo
|
|
||||||
data, err = ti_try_path("/lib/terminfo")
|
|
||||||
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},
|
|
||||||
{"alacritty", 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
|
|
||||||
}
|
|
||||||
|
|
||||||
number_sec_len := int16(2)
|
|
||||||
if header[0] == 542 { // doc says it should be octal 0542, but what I see it terminfo files is 542, learn to program please... thank you..
|
|
||||||
number_sec_len = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
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] + number_sec_len*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,
|
|
||||||
}
|
|
65
vendor/github.com/jesseduffield/termbox-go/terminfo_builtin.go
generated
vendored
65
vendor/github.com/jesseduffield/termbox-go/terminfo_builtin.go
generated
vendored
@ -1,65 +0,0 @@
|
|||||||
// +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},
|
|
||||||
{"alacritty", xterm_keys, xterm_funcs},
|
|
||||||
}
|
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -154,7 +154,6 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
|
|||||||
github.com/jesseduffield/gocui
|
github.com/jesseduffield/gocui
|
||||||
# github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe
|
# github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe
|
||||||
## explicit
|
## explicit
|
||||||
github.com/jesseduffield/termbox-go
|
|
||||||
# github.com/jesseduffield/yaml v2.1.0+incompatible
|
# github.com/jesseduffield/yaml v2.1.0+incompatible
|
||||||
## explicit
|
## explicit
|
||||||
github.com/jesseduffield/yaml
|
github.com/jesseduffield/yaml
|
||||||
|
Loading…
Reference in New Issue
Block a user