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 } 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) 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" switch key { case glfw.KeyC: gui.window.SetClipboardString(gui.terminal.ActiveBuffer().GetSelectedText()) return case glfw.KeyV: if s, err := gui.window.GetClipboardString(); err == nil { _ = gui.terminal.Paste([]byte(s)) } return case glfw.KeySemicolon: gui.config.Slomo = !gui.config.Slomo return } case modsPressed(mods, glfw.ModControl): modStr = "5" switch key { case glfw.KeyC: // ctrl^c gui.logger.Debugf("Sending CTRL^C") gui.terminal.Write([]byte{0x3}) // send EOT return case glfw.KeyD: gui.logger.Debugf("Sending CTRL^D") gui.terminal.Write([]byte{0x4}) // send EOT return case glfw.KeyH: gui.logger.Debugf("Sending CTRL^H") gui.terminal.Write([]byte{0x08}) return case glfw.KeyJ: gui.logger.Debugf("Sending CTRL^J") gui.terminal.Write([]byte{0x0a}) return case glfw.KeyM: gui.logger.Debugf("Sending CTRL^M") gui.terminal.Write([]byte{0x0d}) return case glfw.KeyX: gui.logger.Debugf("Sending CTRL^X") gui.terminal.Write([]byte{0x18}) 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', }) } } //gui.logger.Debugf("Key pressed: 0x%X %q", key, string([]byte{byte(key)})) //gui.terminal.Write([]byte{byte(scancode)}) } }