better input handling

This commit is contained in:
Liam Galvin 2018-08-14 17:44:25 +01:00
parent f185f655d1
commit bb38d22a60
3 changed files with 248 additions and 58 deletions

View File

@ -7,68 +7,250 @@ 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
}
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 {
gui.logger.Debugf("KEY PRESS: key=0x%X scan=0x%X", key, scancode)
switch true {
case mods&glfw.ModControl > 0:
if mods&glfw.ModShift > 0 {
// ctrl + shift +
switch key {
case glfw.KeyV:
// todo handle both these errors
if buf, err := gui.window.GetClipboardString(); err == nil {
_ = gui.terminal.Write([]byte(buf))
}
case glfw.KeySemicolon:
gui.config.Slomo = !gui.config.Slomo
case modsPressed(mods, glfw.ModControl, glfw.ModShift):
switch key {
case glfw.KeyV:
// todo handle both these errors
if buf, err := gui.window.GetClipboardString(); err == nil {
_ = gui.terminal.Write([]byte(buf))
}
} else {
// ctrl +
switch key {
case glfw.KeyC: // ctrl^c
gui.logger.Debugf("Sending CTRL^C")
gui.terminal.Write([]byte{0x3}) // send EOT
case glfw.KeySemicolon:
gui.config.Slomo = !gui.config.Slomo
}
case modsPressed(mods, glfw.ModControl):
switch key {
case glfw.KeyC: // ctrl^c
gui.logger.Debugf("Sending CTRL^C")
gui.terminal.Write([]byte{0x3}) // send EOT
}
default: // no mods
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 gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'H',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'H',
})
}
case glfw.KeyEnd:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'F',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'F',
})
}
case glfw.KeyEscape:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
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:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'M',
})
} else {
gui.terminal.Write([]byte{0x0a})
}
case glfw.KeyBackspace:
gui.terminal.Write([]byte{0x08})
case glfw.KeyUp:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'A',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'A',
})
}
case glfw.KeyDown:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'B',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'B',
})
}
case glfw.KeyLeft:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'D',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'D',
})
}
case glfw.KeyRight:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'C',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'C',
})
}
}
}
switch key {
case glfw.KeyEnter:
gui.terminal.Write([]byte{0x0a})
case glfw.KeyBackspace:
gui.terminal.Write([]byte{0x08})
case glfw.KeyUp:
gui.terminal.Write([]byte{
0x1b,
'[',
'A',
})
case glfw.KeyDown:
gui.terminal.Write([]byte{
0x1b,
'[',
'B',
})
case glfw.KeyLeft:
gui.terminal.Write([]byte{
0x1b,
'[',
'D',
})
case glfw.KeyRight:
gui.terminal.Write([]byte{
0x1b,
'[',
'C',
})
case glfw.KeyTab:
gui.terminal.Write([]byte{
0x09,
})
}
//gui.logger.Debugf("Key pressed: 0x%X %q", key, string([]byte{byte(key)}))

View File

@ -41,7 +41,7 @@ func (terminal *Terminal) processInput(ctx context.Context, pty chan rune) {
if ok {
if err := handler(pty, terminal); err != nil {
terminal.logger.Errorf("Error handling escape sequence 0x%X: %s", b, err)
terminal.logger.Errorf("Error handling escape sequence: %s", err)
}
continue
}
@ -49,18 +49,22 @@ func (terminal *Terminal) processInput(ctx context.Context, pty chan rune) {
terminal.logger.Debugf("Received character 0x%X: %q", b, string(b))
switch b {
case 0x0a:
case 0x0a, 0x0c, 0x0b: // LF, FF, VT
terminal.ActiveBuffer().NewLine()
case 0x0d:
case 0x0d: // CR
terminal.ActiveBuffer().CarriageReturn()
case 0x08:
case 0x08: // BS
// backspace
terminal.ActiveBuffer().Backspace()
case 0x07:
case 0x07: // BEL
// @todo ring bell - flash red or some shit?
case 0x05: // ENQ
terminal.logger.Errorf("Received ENQ!")
case 0xe, 0xf:
terminal.logger.Errorf("Received SI/SO")
case 0x09:
terminal.logger.Errorf("Received TAB")
default:
// render character at current location
// fmt.Printf("%s\n", string([]byte{b}))
if b >= 0x20 {
terminal.ActiveBuffer().Write(b)
} else {

View File

@ -90,6 +90,10 @@ func New(pty *os.File, logger *zap.SugaredLogger, config *config.Config) *Termin
}
}
func (terminal *Terminal) IsApplicationCursorKeysModeEnabled() bool {
return terminal.modes.ApplicationCursorKeys
}
func (terminal *Terminal) SetMouseMode(mode MouseMode) {
terminal.mouseMode = mode
}