aminal/gui/input.go

323 lines
5.8 KiB
Go

package gui
import (
"fmt"
"github.com/go-gl/glfw/v3.2/glfw"
)
// send typed runes straight through to the pty
func (gui *GUI) char(w *glfw.Window, r rune) {
gui.terminal.Write([]byte(string(r)))
}
func modsPressed(pressed glfw.ModifierKey, mods ...glfw.ModifierKey) bool {
for _, mod := range mods {
if pressed&mod == 0 {
return false
}
pressed ^= mod
}
return pressed == 0
}
var ctrlBytes = map[glfw.Key]byte{
glfw.KeyA: 0x1,
glfw.KeyB: 0x2,
glfw.KeyC: 0x3,
glfw.KeyD: 0x4,
glfw.KeyE: 0x5,
glfw.KeyF: 0x6,
glfw.KeyG: 0x7,
glfw.KeyH: 0x08,
glfw.KeyI: 0x9,
glfw.KeyJ: 0x0a,
glfw.KeyK: 0x0b,
glfw.KeyL: 0x0c,
glfw.KeyM: 0x0d,
glfw.KeyN: 0x0e,
glfw.KeyO: 0x0f,
glfw.KeyP: 0x10,
glfw.KeyQ: 0x11,
glfw.KeyR: 0x12,
glfw.KeyS: 0x13,
glfw.KeyT: 0x14,
glfw.KeyU: 0x15,
glfw.KeyV: 0x16,
glfw.KeyW: 0x17,
glfw.KeyX: 0x18,
glfw.KeyY: 0x19,
glfw.KeyZ: 0x1a,
}
func (gui *GUI) key(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
if action == glfw.Repeat || action == glfw.Press {
if gui.overlay != nil {
if key == glfw.KeyEscape {
gui.setOverlay(nil)
}
}
for userAction, shortcut := range gui.keyboardShortcuts {
if shortcut.Match(mods, key) {
f, ok := actionMap[userAction]
if ok {
f(gui)
break
}
}
}
modStr := ""
switch true {
case modsPressed(mods, glfw.ModControl, glfw.ModShift, glfw.ModAlt):
modStr = "8"
case modsPressed(mods, glfw.ModControl, glfw.ModAlt):
modStr = "7"
case modsPressed(mods, glfw.ModControl, glfw.ModShift):
modStr = "6"
case modsPressed(mods, glfw.ModControl):
modStr = "5"
if b, ok := ctrlBytes[key]; ok {
gui.terminal.Write([]byte{b})
return
}
case modsPressed(mods, glfw.ModAlt, glfw.ModShift):
modStr = "4"
case modsPressed(mods, glfw.ModAlt):
modStr = "3"
case modsPressed(mods, glfw.ModShift):
modStr = "2"
}
switch key {
case glfw.KeyF1:
gui.terminal.Write([]byte{
0x1b,
'O',
'P',
})
case glfw.KeyF2:
gui.terminal.Write([]byte{
0x1b,
'O',
'Q',
})
case glfw.KeyF3:
gui.terminal.Write([]byte{
0x1b,
'O',
'R',
})
case glfw.KeyF4:
gui.terminal.Write([]byte{
0x1b,
'O',
'S',
})
case glfw.KeyF5:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '5', '~',
})
case glfw.KeyF6:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '7', '~',
})
case glfw.KeyF7:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '8', '~',
})
case glfw.KeyF8:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '9', '~',
})
case glfw.KeyF9:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '0', '~',
})
case glfw.KeyF10:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '1', '~',
})
case glfw.KeyF11:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '3', '~',
})
case glfw.KeyF12:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '4', '~',
})
case glfw.KeyInsert:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '~',
})
case glfw.KeyDelete:
gui.terminal.Write([]byte{
0x1b,
'[',
'3', '~',
})
case glfw.KeyHome:
if modStr == "" {
gui.terminal.Write([]byte("\x1b[1~"))
} else {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%s~", modStr)))
}
case glfw.KeyEnd:
if modStr == "" {
gui.terminal.Write([]byte("\x1b[4~"))
} else {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[4;%s~", modStr)))
}
case glfw.KeyPageUp:
if modStr == "" {
gui.terminal.Write([]byte("\x1b[5~"))
} else {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[5;%s~", modStr)))
}
case glfw.KeyPageDown:
if modStr == "" {
gui.terminal.Write([]byte("\x1b[6~"))
} else {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[6;%s~", modStr)))
}
case glfw.KeyEscape:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
0x1b,
})
}
case glfw.KeyTab:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'I',
})
} else {
gui.terminal.Write([]byte{
0x09,
})
}
case glfw.KeyEnter:
gui.terminal.Write([]byte{
0x0d,
})
case glfw.KeyKPEnter:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'M',
})
} else {
gui.terminal.Write([]byte{
0x0d,
})
}
case glfw.KeyBackspace:
gui.terminal.Write([]byte{0x08})
case glfw.KeyUp:
if modStr != "" {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sA", modStr)))
}
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'A',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'A',
})
}
case glfw.KeyDown:
if modStr != "" {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sB", modStr)))
}
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'B',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'B',
})
}
case glfw.KeyLeft:
if modStr != "" {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sD", modStr)))
}
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'D',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'D',
})
}
case glfw.KeyRight:
if modStr != "" {
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sC", modStr)))
}
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'C',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'C',
})
}
}
}
}