diff options
author | Ryooooooga <eial5q265e5@gmail.com> | 2023-02-21 21:53:55 +0900 |
---|---|---|
committer | Ryooooooga <eial5q265e5@gmail.com> | 2023-02-21 21:53:55 +0900 |
commit | 90772e1eaac00314cfb45b8a2216aca28ef91105 (patch) | |
tree | dda871b4a57368f5234ee80b8a518254b03162ea /vendor | |
parent | 526c9dea9b298d69a3fafec3303549b0d6292af4 (diff) |
build: bump tcell version
Diffstat (limited to 'vendor')
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/README-wasm.md | 61 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/README.md | 8 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/cell.go | 9 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/color.go | 6 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go | 69 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/terms_static.go | 4 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/tscreen.go | 8 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/tscreen_stub.go | 4 | ||||
-rw-r--r-- | vendor/github.com/gdamore/tcell/v2/wscreen.go | 678 | ||||
-rw-r--r-- | vendor/github.com/rivo/uniseg/grapheme.go | 6 | ||||
-rw-r--r-- | vendor/github.com/rivo/uniseg/graphemerules.go | 2 | ||||
-rw-r--r-- | vendor/github.com/rivo/uniseg/line.go | 7 | ||||
-rw-r--r-- | vendor/github.com/rivo/uniseg/sentence.go | 4 | ||||
-rw-r--r-- | vendor/github.com/rivo/uniseg/step.go | 4 | ||||
-rw-r--r-- | vendor/github.com/rivo/uniseg/word.go | 4 | ||||
-rw-r--r-- | vendor/modules.txt | 6 |
16 files changed, 859 insertions, 21 deletions
diff --git a/vendor/github.com/gdamore/tcell/v2/README-wasm.md b/vendor/github.com/gdamore/tcell/v2/README-wasm.md new file mode 100644 index 000000000..faf96856f --- /dev/null +++ b/vendor/github.com/gdamore/tcell/v2/README-wasm.md @@ -0,0 +1,61 @@ +# WASM for _Tcell_ + +You can build _Tcell_ project into a webpage by compiling it slightly differently. This will result in a _Tcell_ project you can embed into another html page, or use as a standalone page. + +## Building your project + +WASM needs special build flags in order to work. You can build it by executing +```sh +GOOS=js GOARCH=wasm go build -o yourfile.wasm +``` + +## Additional files + +You also need 5 other files in the same directory as the wasm. Four (`tcell.html`, `tcell.js`, `termstyle.css`, and `beep.wav`) are provided in the `webfiles` directory. The last one, `wasm_exec.js`, can be copied from GOROOT into the current directory by executing +```sh +cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./ +``` + +In `tcell.js`, you also need to change the constant +```js +const wasmFilePath = "yourfile.wasm" +``` +to the file you outputed to when building. + +## Displaying your project + +### Standalone + +You can see the project (with an white background around the terminal) by serving the directory. You can do this using any framework, including another golang project: + +```golang +// server.go + +package main + +import ( + "log" + "net/http" +) + +func main() { + log.Fatal(http.ListenAndServe(":8080", + http.FileServer(http.Dir("/path/to/dir/to/serve")), + )) +} + +``` + +To see the webpage with this example, you can type in `localhost:8080/tcell.html` into your browser while `server.go` is running. + +### Embedding +It is recomended to use an iframe if you want to embed the app into a webpage: +```html +<iframe src="tcell.html" title="Tcell app"></iframe> +``` + +## Other considerations + +### Accessing files + +`io.Open(filename)` and other related functions for reading file systems do not work; use `http.Get(filename)` instead.
\ No newline at end of file diff --git a/vendor/github.com/gdamore/tcell/v2/README.md b/vendor/github.com/gdamore/tcell/v2/README.md index 13e6e0cd5..347e274a2 100644 --- a/vendor/github.com/gdamore/tcell/v2/README.md +++ b/vendor/github.com/gdamore/tcell/v2/README.md @@ -264,7 +264,11 @@ Windows console mode applications are supported. Modern console applications like ConEmu and the Windows 10 terminal, support all the good features (resize, mouse tracking, etc.) -### Plan9, WASM, and others +### WASM + +WASM is supported, but needs additional setup detailed in [README-wasm](README-wasm.md). + +### Plan9 and others These platforms won't work, but compilation stubs are supplied for folks that want to include parts of this in software for those @@ -279,4 +283,4 @@ please let me know. PRs are especially welcome. _Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options. - [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages. -- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis. +- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis.
\ No newline at end of file diff --git a/vendor/github.com/gdamore/tcell/v2/cell.go b/vendor/github.com/gdamore/tcell/v2/cell.go index c33900495..756a5068d 100644 --- a/vendor/github.com/gdamore/tcell/v2/cell.go +++ b/vendor/github.com/gdamore/tcell/v2/cell.go @@ -50,6 +50,10 @@ func (cb *CellBuffer) SetContent(x int, y int, if x >= 0 && y >= 0 && x < cb.w && y < cb.h { c := &cb.cells[(y*cb.w)+x] + for i := 1; i < c.width; i++ { + cb.SetDirty(x+i, y, true) + } + c.currComb = append([]rune{}, combc...) if c.currMain != mainc { @@ -178,13 +182,14 @@ func (cb *CellBuffer) Fill(r rune, style Style) { } } -var runeConfig *runewidth.Condition; +var runeConfig *runewidth.Condition + func init() { // The defaults for the runewidth package are poorly chosen for terminal // applications. We however will honor the setting in the environment if // it is set. if os.Getenv("RUNEWIDTH_EASTASIAN") == "" { - runewidth.DefaultCondition.EastAsianWidth = false; + runewidth.DefaultCondition.EastAsianWidth = false } // For performance reasons, we create a lookup table. However some users diff --git a/vendor/github.com/gdamore/tcell/v2/color.go b/vendor/github.com/gdamore/tcell/v2/color.go index 8e50fa302..e6581b0f6 100644 --- a/vendor/github.com/gdamore/tcell/v2/color.go +++ b/vendor/github.com/gdamore/tcell/v2/color.go @@ -1002,14 +1002,14 @@ func (c Color) IsRGB() bool { } // Hex returns the color's hexadecimal RGB 24-bit value with each component -// consisting of a single byte, ala R << 16 | G << 8 | B. If the color +// consisting of a single byte, R << 16 | G << 8 | B. If the color // is unknown or unset, -1 is returned. func (c Color) Hex() int32 { if !c.Valid() { return -1 } if c&ColorIsRGB != 0 { - return int32(c) & 0xffffff + return int32(c & 0xffffff) } if v, ok := ColorValues[c]; ok { return v @@ -1036,7 +1036,7 @@ func (c Color) TrueColor() Color { return ColorDefault } if c&ColorIsRGB != 0 { - return c + return c | ColorValid } return Color(c.Hex()) | ColorIsRGB | ColorValid } diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go b/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go new file mode 100644 index 000000000..db6351af2 --- /dev/null +++ b/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go @@ -0,0 +1,69 @@ +// Generated automatically. DO NOT HAND-EDIT. + +package alacritty + +import "github.com/gdamore/tcell/v2/terminfo" + +func init() { + + // alacritty with direct color indexing + terminfo.AddTerminfo(&terminfo.Terminfo{ + Name: "alacritty-direct", + Columns: 80, + Lines: 24, + Colors: 16777216, + Bell: "\a", + Clear: "\x1b[H\x1b[2J", + EnterCA: "\x1b[?1049h\x1b[22;0;0t", + ExitCA: "\x1b[?1049l\x1b[23;0;0t", + ShowCursor: "\x1b[?12l\x1b[?25h", + HideCursor: "\x1b[?25l", + AttrOff: "\x1b(B\x1b[m", + Underline: "\x1b[4m", + Bold: "\x1b[1m", + Dim: "\x1b[2m", + Italic: "\x1b[3m", + Reverse: "\x1b[7m", + EnterKeypad: "\x1b[?1h\x1b=", + ExitKeypad: "\x1b[?1l\x1b>", + SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", + SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", + SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m", + ResetFgBg: "\x1b[39;49m", + AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~", + EnterAcs: "\x1b(0", + ExitAcs: "\x1b(B", + StrikeThrough: "\x1b[9m", + Mouse: "\x1b[M", + SetCursor: "\x1b[%i%p1%d;%p2%dH", + CursorBack1: "\b", + CursorUp1: "\x1b[A", + KeyUp: "\x1bOA", + KeyDown: "\x1bOB", + KeyRight: "\x1bOC", + KeyLeft: "\x1bOD", + KeyInsert: "\x1b[2~", + KeyDelete: "\x1b[3~", + KeyBackspace: "\x7f", + KeyHome: "\x1bOH", + KeyEnd: "\x1bOF", + KeyPgUp: "\x1b[5~", + KeyPgDn: "\x1b[6~", + KeyF1: "\x1bOP", + KeyF2: "\x1bOQ", + KeyF3: "\x1bOR", + KeyF4: "\x1bOS", + KeyF5: "\x1b[15~", + KeyF6: "\x1b[17~", + KeyF7: "\x1b[18~", + KeyF8: "\x1b[19~", + KeyF9: "\x1b[20~", + KeyF10: "\x1b[21~", + KeyF11: "\x1b[23~", + KeyF12: "\x1b[24~", + KeyBacktab: "\x1b[Z", + Modifiers: 1, + TrueColor: true, + AutoMargin: true, + }) +} diff --git a/vendor/github.com/gdamore/tcell/v2/terms_static.go b/vendor/github.com/gdamore/tcell/v2/terms_static.go index d0c57d919..6d725cbcc 100644 --- a/vendor/github.com/gdamore/tcell/v2/terms_static.go +++ b/vendor/github.com/gdamore/tcell/v2/terms_static.go @@ -1,5 +1,5 @@ -//go:build tcell_minimal || nacl || js || zos || plan9 || windows || android -// +build tcell_minimal nacl js zos plan9 windows android +//go:build tcell_minimal || nacl || zos || plan9 || windows || android || js +// +build tcell_minimal nacl zos plan9 windows android js // Copyright 2019 The TCell Authors // diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen.go b/vendor/github.com/gdamore/tcell/v2/tscreen.go index e07dea4e7..e36e6e41f 100644 --- a/vendor/github.com/gdamore/tcell/v2/tscreen.go +++ b/vendor/github.com/gdamore/tcell/v2/tscreen.go @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !(js && wasm) +// +build !js !wasm + package tcell import ( @@ -341,6 +344,11 @@ func (t *tScreen) prepareBracketedPaste() { } func (t *tScreen) prepareExtendedOSC() { + // Linux is a special beast - because it has a mouse entry, but does + // not swallow these OSC commands properly. + if (strings.Contains(t.ti.Name, "linux")) { + return; + } // More stuff for limits in terminfo. This time we are applying // the most common OSC (operating system commands). Generally // terminals that don't understand these will ignore them. diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go b/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go index 9e3cdaa02..0e4deae02 100644 --- a/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go +++ b/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go @@ -1,5 +1,5 @@ -//go:build js || plan9 || windows -// +build js plan9 windows +//go:build plan9 || windows +// +build plan9 windows // Copyright 2022 The TCell Authors // diff --git a/vendor/github.com/gdamore/tcell/v2/wscreen.go b/vendor/github.com/gdamore/tcell/v2/wscreen.go new file mode 100644 index 000000000..080472065 --- /dev/null +++ b/vendor/github.com/gdamore/tcell/v2/wscreen.go @@ -0,0 +1,678 @@ +// Copyright 2023 The TCell Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use file except in compliance with the License. +// You may obtain a copy of the license at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build js && wasm +// +build js,wasm + +package tcell + +import ( + "errors" + "strings" + "sync" + "syscall/js" + "unicode/utf8" +) + +func NewTerminfoScreen() (Screen, error) { + t := &wScreen{} + t.fallback = make(map[rune]string) + + return t, nil +} + +type wScreen struct { + w, h int + style Style + cells CellBuffer + + running bool + clear bool + flagsPresent bool + pasteEnabled bool + mouseFlags MouseFlags + + cursorStyle CursorStyle + + quit chan struct{} + evch chan Event + fallback map[rune]string + + sync.Mutex +} + +func (t *wScreen) Init() error { + t.w, t.h = 80, 24 // default for html as of now + t.evch = make(chan Event, 10) + t.quit = make(chan struct{}) + + t.Lock() + t.running = true + t.style = StyleDefault + t.cells.Resize(t.w, t.h) + t.Unlock() + + js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent)) + + return nil +} + +func (t *wScreen) Fini() { + close(t.quit) +} + +func (t *wScreen) SetStyle(style Style) { + t.Lock() + t.style = style + t.Unlock() +} + +func (t *wScreen) Clear() { + t.Fill(' ', t.style) +} + +func (t *wScreen) Fill(r rune, style Style) { + t.Lock() + t.cells.Fill(r, style) + t.Unlock() +} + +func (t *wScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) { + t.Lock() + t.cells.SetContent(x, y, mainc, combc, style) + t.Unlock() +} + +func (t *wScreen) GetContent(x, y int) (rune, []rune, Style, int) { + t.Lock() + mainc, combc, style, width := t.cells.GetContent(x, y) + t.Unlock() + return mainc, combc, style, width +} + +func (t *wScreen) SetCell(x, y int, style Style, ch ...rune) { + if len(ch) > 0 { + t.SetContent(x, y, ch[0], ch[1:], style) + } else { + t.SetContent(x, y, ' ', nil, style) + } +} + +// paletteColor gives a more natural palette color actually matching +// typical XTerm. We might in the future want to permit styling these +// via CSS. + +var palette = map[Color]int32{ + ColorBlack: 0x000000, + ColorMaroon: 0xcd0000, + ColorGreen: 0x00cd00, + ColorOlive: 0xcdcd00, + ColorNavy: 0x0000ee, + ColorPurple: 0xcd00cd, + ColorTeal: 0x00cdcd, + ColorSilver: 0xe5e5e5, + ColorGray: 0x7f7f7f, + ColorRed: 0xff0000, + ColorLime: 0x00ff00, + ColorYellow: 0xffff00, + ColorBlue: 0x5c5cff, + ColorFuchsia: 0xff00ff, + ColorAqua: 0x00ffff, + ColorWhite: 0xffffff, +} + +func paletteColor(c Color) int32 { + if (c.IsRGB()) { + return int32(c & 0xffffff); + } + if (c >= ColorBlack && c <= ColorWhite) { + return palette[c] + } + return c.Hex() +} + +func (t *wScreen) drawCell(x, y int) int { + mainc, combc, style, width := t.cells.GetContent(x, y) + + if !t.cells.Dirty(x, y) { + return width + } + + if style == StyleDefault { + style = t.style + } + + fg, bg := paletteColor(style.fg), paletteColor(style.bg) + if (fg == -1) { + fg = 0xe5e5e5; + } + if (bg == -1) { + bg = 0x000000; + } + + var combcarr []interface{} = make([]interface{}, len(combc)) + for i, c := range combc { + combcarr[i] = c + } + + t.cells.SetDirty(x, y, false) + js.Global().Call("drawCell", x, y, mainc, combcarr, fg, bg, int(style.attrs)) + + return width +} + +func (t *wScreen) ShowCursor(x, y int) { + t.Lock() + js.Global().Call("showCursor", x, y) + t.Unlock() +} + +func (t *wScreen) SetCursorStyle(cs CursorStyle) { + t.Lock() + js.Global().Call("setCursorStyle", curStyleClasses[cs]) + t.Unlock() +} + +func (t *wScreen) HideCursor() { + t.ShowCursor(-1, -1) +} + +func (t *wScreen) Show() { + t.Lock() + t.resize() + t.draw() + t.Unlock() +} + +func (t *wScreen) clearScreen() { + js.Global().Call("clearScreen", t.style.fg.Hex(), t.style.bg.Hex()) + t.clear = false +} + +func (t *wScreen) draw() { + if t.clear { + t.clearScreen() + } + + for y := 0; y < t.h; y++ { + for x := 0; x < t.w; x++ { + width := t.drawCell(x, y) + x += width - 1 + } + } + + js.Global().Call("show") +} + +func (t *wScreen) EnableMouse(flags ...MouseFlags) { + var f MouseFlags + flagsPresent := false + for _, flag := range flags { + f |= flag + flagsPresent = true + } + if !flagsPresent { + f = MouseMotionEvents | MouseDragEvents | MouseButtonEvents + } + + t.Lock() + t.mouseFlags = f + t.enableMouse(f) + t.Unlock() +} + +func (t *wScreen) enableMouse(f MouseFlags) { + if f&MouseButtonEvents != 0 { + js.Global().Set("onMouseClick", js.FuncOf(t.onMouseEvent)) + } else { + js.Global().Set("onMouseClick", js.FuncOf(t.unset)) + } + + if f&MouseDragEvents != 0 || f&MouseMotionEvents != 0 { + js.Global().Set("onMouseMove", js.FuncOf(t.onMouseEvent)) + } else { + js.Global().Set("onMouseMove", js.FuncOf(t.unset)) + } +} + +func (t *wScreen) DisableMouse() { + t.Lock() + t.mouseFlags = 0 + t.enableMouse(0) + t.Unlock() +} + +func (t *wScreen) EnablePaste() { + t.Lock() + t.pasteEnabled = true + t.enablePasting(true) + t.Unlock() +} + +func (t *wScreen) DisablePaste() { + t.Lock() + t.pasteEnabled = false + t.enablePasting(false) + t.Unlock() +} + +func (t *wScreen) enablePasting(on bool) { + if on { + js.Global().Set("onPaste", js.FuncOf(t.onPaste)) + } else { + js.Global().Set("onPaste", js.FuncOf(t.unset)) + } +} + +func (t *wScreen) Size() (int, int) { + t.Lock() + w, h := t.w, t.h + t.Unlock() + return w, h +} + +// resize does nothing, as asking the web window to resize +// without a specified width or height will cause no change. +func (t *wScreen) resize() {} + +func (t *wScreen) Colors() int { + return 16777216 // 256 ^ 3 +} + +func (t *wScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) { + defer close(ch) + for { + select { + case <-quit: + return + case <-t.quit: + return + case ev := <-t.evch: + select { + case <-quit: + return + case <-t.quit: + return + case ch <- ev: + } + } + } +} + +func (t *wScreen) PollEvent() Event { + select { + case <-t.quit: + return nil + case ev := <-t.evch: + return ev + } +} + +func (t *wScreen) HasPendingEvent() bool { + return len(t.evch) > 0 +} + +func (t *wScreen) PostEventWait(ev Event) { + t.evch <- ev +} + +func (t *wScreen) PostEvent(ev Event) error { + select { + case t.evch <- ev: + return nil + default: + return ErrEventQFull + } +} + +func (t *wScreen) clip(x, y int) (int, int) { + w, h := t.cells.Size() + if x < 0 { + x = 0 + } + if y < 0 { + y = 0 + } + if x > w-1 { + x = w - 1 + } + if y > h-1 { + y = h - 1 + } + return x, y +} + +func (t *wScreen) onMouseEvent(this js.Value, args []js.Value) interface{} { + mod := ModNone + button := ButtonNone + + switch args[2].Int() { + case 0: + if t.mouseFlags&MouseMotionEvents == 0 { + // don't want this event! is a mouse motion event, but user has asked not. + return nil + } + button = ButtonNone + case 1: + button = Button1 + case 2: + button = Button3 // Note we prefer to treat right as button 2 + case 3: + button = Button2 // And the middle button as button 3 + } + + if args[3].Bool() { // mod shift + mod |= ModShift + } + + if args[4].Bool() { // mod alt + mod |= ModAlt + } + + if args[5].Bool() { // mod ctrl + mod |= ModCtrl + } + + t.PostEventWait(NewEventMouse(args[0].Int(), args[1].Int(), button, mod)) + return nil +} + +func (t *wScreen) onKeyEvent(this js.Value, args []js.Value) interface{} { + key := args[0].String() + + // don't accept any modifier keys as their own + if key == "Control" || key == "Alt" || key == "Meta" || key == "Shift" { + return nil + } + + mod := ModNone + if args[1].Bool() { // mod shift + mod |= ModShift + } + + if args[2].Bool() { // mod alt + mod |= ModAlt + } + + if args[3].Bool() { // mod ctrl + mod |= ModCtrl + } + + if args[4].Bool() { // mod meta + mod |= ModMeta + } + + // check for special case of Ctrl + key + if mod == ModCtrl { + if k, ok := WebKeyNames["Ctrl-"+strings.ToLower(key)]; ok { + t.PostEventWait(NewEventKey(k, 0, mod)) + return nil + } + } + + // next try function keys + if k, ok := WebKeyNames[key]; ok { + t.PostEventWait(NewEventKey(k, 0, mod)) + return nil + } + + // finally try normal, printable chars + r, _ := utf8.DecodeRuneInString(key) + t.PostEventWait(NewEventKey(KeyRune, r, mod)) + return nil +} + +func (t *wScreen) onPaste(this js.Value, args []js.Value) interface{} { + t.PostEventWait(NewEventPaste(args[0].Bool())) + return nil +} + +// unset is a dummy function for js when we want nothing to +// happen when javascript calls a function (for example, when +// mouse input is disabled, when onMouseEvent() is called from +// js, it redirects here and does nothing). +func (t *wScreen) unset(this js.Value, args []js.Value) interface{} { + return nil +} + +func (t *wScreen) Sync() { + t.Lock() + t.resize() + t.clear = true + t.cells.Invalidate() + t.draw() + t.Unlock() +} + +func (t *wScreen) CharacterSet() string { + return "UTF-8" +} + +func (t *wScreen) RegisterRuneFallback(orig rune, fallback string) { + t.Lock() + t.fallback[orig] = fallback + t.Unlock() +} + +func (t *wScreen) UnregisterRuneFallback(orig rune) { + t.Lock() + delete(t.fallback, orig) + t.Unlock() +} + +func (t *wScreen) CanDisplay(r rune, checkFallbacks bool) bool { + if utf8.ValidRune(r) { + return true + } + if !checkFallbacks { + return false + } + if _, ok := t.fallback[r]; ok { + return true + } + return false +} + +func (t *wScreen) HasMouse() bool { + return true +} + +func (t *wScreen) HasKey(k Key) bool { + return true +} + +func (t *wScreen) SetSize(w, h int) { + if w == t.w && h == t.h { + return + } + + t.cells.Invalidate() + t.cells.Resize(w, h) + js.Global().Call("resize", w, h) + t.w, t.h = w, h + t.PostEvent(NewEventResize(w, h)) +} + +func (t *wScreen) Resize(int, int, int, int) {} + +// Suspend simply pauses all input and output, and clears the screen. +// There isn't a "default terminal" to go back to. +func (t *wScreen) Suspend() error { + t.Lock() + if !t.running { + t.Unlock() + return nil + } + t.running = false + t.clearScreen() + t.enableMouse(0) + t.enablePasting(false) + js.Global().Set("onKeyEvent", js.FuncOf(t.unset)) // stop keypresses + return nil +} + +func (t *wScreen) Resume() error { + t.Lock() + + if t.running { + return errors.New("already engaged") + } + t.running = true + + t.enableMouse(t.mouseFlags) + t.enablePasting(t.pasteEnabled) + + js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent)) + + t.Unlock() + return nil +} + +func (t *wScreen) Beep() error { + js.Global().Call("beep") + return nil +} + +// WebKeyNames maps string names reported from HTML +// (KeyboardEvent.key) to tcell accepted keys. +var WebKeyNames = map[string]Key{ + "Enter": KeyEnter, + "Backspace": KeyBackspace, + "Tab": KeyTab, + "Backtab": KeyBacktab, + "Escape": KeyEsc, + "Backspace2": KeyBackspace2, + "Delete": KeyDelete, + "Insert": KeyInsert, + "ArrowUp": KeyUp, + "ArrowDown": KeyDown, + "ArrowLeft": KeyLeft, + "ArrowRight": KeyRight, + "Home": KeyHome, + "End": KeyEnd, + "UpLeft": KeyUpLeft, // not supported by HTML + "UpRight": KeyUpRight, // not supported by HTML + "DownLeft": KeyDownLeft, // not supported by HTML + "DownRight": KeyDownRight, // not supported by HTML + "Center": KeyCenter, + "PgDn": KeyPgDn, + "PgUp": KeyPgUp, + "Clear": KeyClear, + "Exit": KeyExit, + "Cancel": KeyCancel, + "Pause": KeyPause, + "Print": KeyPrint, + "F1": KeyF1, + "F2": KeyF2, + "F3": KeyF3, + "F4": KeyF4, + "F5": KeyF5, + "F6": KeyF6, + "F7": KeyF7, + "F8": KeyF8, + "F9": KeyF9, + "F10": KeyF10, + "F11": KeyF11, + "F12": KeyF12, + "F13": KeyF13, + "F14": KeyF14, + "F15": KeyF15, + "F16": KeyF16, + "F17": KeyF17, + "F18": KeyF18, + "F19": KeyF19, + "F20": KeyF20, + "F21": KeyF21, + "F22": KeyF22, + "F23": KeyF23, + "F24": KeyF24, + "F25": KeyF25, + "F26": KeyF26, + "F27": KeyF27, + "F28": KeyF28, + "F29": KeyF29, + "F30": KeyF30, + "F31": KeyF31, + "F32": KeyF32, + "F33": KeyF33, + "F34": KeyF34, + "F35": KeyF35, + "F36": KeyF36, + "F37": KeyF37, + "F38": KeyF38, + "F39": KeyF39, + "F40": KeyF40, + "F41": KeyF41, + "F42": KeyF42, + "F43": KeyF43, + "F44": KeyF44, + "F45": KeyF45, + "F46": KeyF46, + "F47": KeyF47, + "F48": KeyF48, + "F49": KeyF49, + "F50": KeyF50, + "F51": KeyF51, + "F52": KeyF52, + "F53": KeyF53, + "F54": KeyF54, + "F55": KeyF55, + "F56": KeyF56, + "F57": KeyF57, + "F58": KeyF58, + "F59": KeyF59, + "F60": KeyF60, + "F61": KeyF61, + "F62": KeyF62, + "F63": KeyF63, + "F64": KeyF64, + "Ctrl-a": KeyCtrlA, // not reported by HTML- need to do special check + "Ctrl-b": KeyCtrlB, // not reported by HTML- need to do special check + "Ctrl-c": KeyCtrlC, // not reported by HTML- need to do special check + "Ctrl-d": KeyCtrlD, // not reported by HTML- need to do special check + "Ctrl-e": KeyCtrlE, // not reported by HTML- need to do special check + "Ctrl-f": KeyCtrlF, // not reported by HTML- need to do special check + "Ctrl-g": KeyCtrlG, // not reported by HTML- need to do special check + "Ctrl-j": KeyCtrlJ, // not reported by HTML- need to do special check + "Ctrl-k": KeyCtrlK, // not reported by HTML- need to do special check + "Ctrl-l": KeyCtrlL, // not reported by HTML- need to do special check + "Ctrl-n": KeyCtrlN, // not reported by HTML- need to do special check + "Ctrl-o": KeyCtrlO, // not reported by HTML- need to do special check + "Ctrl-p": KeyCtrlP, // not reported by HTML- need to do special check + "Ctrl-q": KeyCtrlQ, // not reported by HTML- need to do special check + "Ctrl-r": KeyCtrlR, // not reported by HTML- need to do special check + "Ctrl-s": KeyCtrlS, // not reported by HTML- need to do |