|
@@ -10,8 +10,8 @@ import (
|
|
|
"strings"
|
|
|
"unsafe"
|
|
|
|
|
|
- . "github.com/Azure/go-ansiterm"
|
|
|
- . "github.com/Azure/go-ansiterm/winterm"
|
|
|
+ ansiterm "github.com/Azure/go-ansiterm"
|
|
|
+ "github.com/Azure/go-ansiterm/winterm"
|
|
|
)
|
|
|
|
|
|
// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation.
|
|
@@ -26,12 +26,12 @@ type ansiReader struct {
|
|
|
}
|
|
|
|
|
|
func newAnsiReader(nFile int) *ansiReader {
|
|
|
- file, fd := GetStdFile(nFile)
|
|
|
+ file, fd := winterm.GetStdFile(nFile)
|
|
|
return &ansiReader{
|
|
|
file: file,
|
|
|
fd: fd,
|
|
|
- command: make([]byte, 0, ANSI_MAX_CMD_LENGTH),
|
|
|
- escapeSequence: []byte(KEY_ESC_CSI),
|
|
|
+ command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
|
|
|
+ escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
|
|
|
buffer: make([]byte, 0),
|
|
|
}
|
|
|
}
|
|
@@ -101,28 +101,28 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
|
|
|
}
|
|
|
|
|
|
// readInputEvents polls until at least one event is available.
|
|
|
-func readInputEvents(fd uintptr, maxBytes int) ([]INPUT_RECORD, error) {
|
|
|
+func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
|
|
|
// Determine the maximum number of records to retrieve
|
|
|
// -- Cast around the type system to obtain the size of a single INPUT_RECORD.
|
|
|
// unsafe.Sizeof requires an expression vs. a type-reference; the casting
|
|
|
// tricks the type system into believing it has such an expression.
|
|
|
- recordSize := int(unsafe.Sizeof(*((*INPUT_RECORD)(unsafe.Pointer(&maxBytes)))))
|
|
|
+ recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes)))))
|
|
|
countRecords := maxBytes / recordSize
|
|
|
- if countRecords > MAX_INPUT_EVENTS {
|
|
|
- countRecords = MAX_INPUT_EVENTS
|
|
|
+ if countRecords > ansiterm.MAX_INPUT_EVENTS {
|
|
|
+ countRecords = ansiterm.MAX_INPUT_EVENTS
|
|
|
}
|
|
|
logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize)
|
|
|
|
|
|
// Wait for and read input events
|
|
|
- events := make([]INPUT_RECORD, countRecords)
|
|
|
+ events := make([]winterm.INPUT_RECORD, countRecords)
|
|
|
nEvents := uint32(0)
|
|
|
- eventsExist, err := WaitForSingleObject(fd, WAIT_INFINITE)
|
|
|
+ eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
if eventsExist {
|
|
|
- err = ReadConsoleInput(fd, events, &nEvents)
|
|
|
+ err = winterm.ReadConsoleInput(fd, events, &nEvents)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
@@ -135,43 +135,43 @@ func readInputEvents(fd uintptr, maxBytes int) ([]INPUT_RECORD, error) {
|
|
|
|
|
|
// KeyEvent Translation Helpers
|
|
|
|
|
|
-var arrowKeyMapPrefix = map[WORD]string{
|
|
|
- VK_UP: "%s%sA",
|
|
|
- VK_DOWN: "%s%sB",
|
|
|
- VK_RIGHT: "%s%sC",
|
|
|
- VK_LEFT: "%s%sD",
|
|
|
+var arrowKeyMapPrefix = map[winterm.WORD]string{
|
|
|
+ winterm.VK_UP: "%s%sA",
|
|
|
+ winterm.VK_DOWN: "%s%sB",
|
|
|
+ winterm.VK_RIGHT: "%s%sC",
|
|
|
+ winterm.VK_LEFT: "%s%sD",
|
|
|
}
|
|
|
|
|
|
-var keyMapPrefix = map[WORD]string{
|
|
|
- VK_UP: "\x1B[%sA",
|
|
|
- VK_DOWN: "\x1B[%sB",
|
|
|
- VK_RIGHT: "\x1B[%sC",
|
|
|
- VK_LEFT: "\x1B[%sD",
|
|
|
- VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
|
|
|
- VK_END: "\x1B[4%s~", // showkey shows ^[[4
|
|
|
- VK_INSERT: "\x1B[2%s~",
|
|
|
- VK_DELETE: "\x1B[3%s~",
|
|
|
- VK_PRIOR: "\x1B[5%s~",
|
|
|
- VK_NEXT: "\x1B[6%s~",
|
|
|
- VK_F1: "",
|
|
|
- VK_F2: "",
|
|
|
- VK_F3: "\x1B[13%s~",
|
|
|
- VK_F4: "\x1B[14%s~",
|
|
|
- VK_F5: "\x1B[15%s~",
|
|
|
- VK_F6: "\x1B[17%s~",
|
|
|
- VK_F7: "\x1B[18%s~",
|
|
|
- VK_F8: "\x1B[19%s~",
|
|
|
- VK_F9: "\x1B[20%s~",
|
|
|
- VK_F10: "\x1B[21%s~",
|
|
|
- VK_F11: "\x1B[23%s~",
|
|
|
- VK_F12: "\x1B[24%s~",
|
|
|
+var keyMapPrefix = map[winterm.WORD]string{
|
|
|
+ winterm.VK_UP: "\x1B[%sA",
|
|
|
+ winterm.VK_DOWN: "\x1B[%sB",
|
|
|
+ winterm.VK_RIGHT: "\x1B[%sC",
|
|
|
+ winterm.VK_LEFT: "\x1B[%sD",
|
|
|
+ winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
|
|
|
+ winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4
|
|
|
+ winterm.VK_INSERT: "\x1B[2%s~",
|
|
|
+ winterm.VK_DELETE: "\x1B[3%s~",
|
|
|
+ winterm.VK_PRIOR: "\x1B[5%s~",
|
|
|
+ winterm.VK_NEXT: "\x1B[6%s~",
|
|
|
+ winterm.VK_F1: "",
|
|
|
+ winterm.VK_F2: "",
|
|
|
+ winterm.VK_F3: "\x1B[13%s~",
|
|
|
+ winterm.VK_F4: "\x1B[14%s~",
|
|
|
+ winterm.VK_F5: "\x1B[15%s~",
|
|
|
+ winterm.VK_F6: "\x1B[17%s~",
|
|
|
+ winterm.VK_F7: "\x1B[18%s~",
|
|
|
+ winterm.VK_F8: "\x1B[19%s~",
|
|
|
+ winterm.VK_F9: "\x1B[20%s~",
|
|
|
+ winterm.VK_F10: "\x1B[21%s~",
|
|
|
+ winterm.VK_F11: "\x1B[23%s~",
|
|
|
+ winterm.VK_F12: "\x1B[24%s~",
|
|
|
}
|
|
|
|
|
|
// translateKeyEvents converts the input events into the appropriate ANSI string.
|
|
|
-func translateKeyEvents(events []INPUT_RECORD, escapeSequence []byte) []byte {
|
|
|
+func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte {
|
|
|
var buffer bytes.Buffer
|
|
|
for _, event := range events {
|
|
|
- if event.EventType == KEY_EVENT && event.KeyEvent.KeyDown != 0 {
|
|
|
+ if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 {
|
|
|
buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence))
|
|
|
}
|
|
|
}
|
|
@@ -180,7 +180,7 @@ func translateKeyEvents(events []INPUT_RECORD, escapeSequence []byte) []byte {
|
|
|
}
|
|
|
|
|
|
// keyToString maps the given input event record to the corresponding string.
|
|
|
-func keyToString(keyEvent *KEY_EVENT_RECORD, escapeSequence []byte) string {
|
|
|
+func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string {
|
|
|
if keyEvent.UnicodeChar == 0 {
|
|
|
return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence)
|
|
|
}
|
|
@@ -199,14 +199,14 @@ func keyToString(keyEvent *KEY_EVENT_RECORD, escapeSequence []byte) string {
|
|
|
|
|
|
// <Alt>+Key generates ESC N Key
|
|
|
if !control && alt {
|
|
|
- return KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
|
|
|
+ return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
|
|
|
}
|
|
|
|
|
|
return string(keyEvent.UnicodeChar)
|
|
|
}
|
|
|
|
|
|
// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string.
|
|
|
-func formatVirtualKey(key WORD, controlState DWORD, escapeSequence []byte) string {
|
|
|
+func formatVirtualKey(key winterm.WORD, controlState winterm.DWORD, escapeSequence []byte) string {
|
|
|
shift, alt, control := getControlKeys(controlState)
|
|
|
modifier := getControlKeysModifier(shift, alt, control, false)
|
|
|
|
|
@@ -222,35 +222,35 @@ func formatVirtualKey(key WORD, controlState DWORD, escapeSequence []byte) strin
|
|
|
}
|
|
|
|
|
|
// getControlKeys extracts the shift, alt, and ctrl key states.
|
|
|
-func getControlKeys(controlState DWORD) (shift, alt, control bool) {
|
|
|
- shift = 0 != (controlState & SHIFT_PRESSED)
|
|
|
- alt = 0 != (controlState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
|
|
|
- control = 0 != (controlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
|
|
+func getControlKeys(controlState winterm.DWORD) (shift, alt, control bool) {
|
|
|
+ shift = 0 != (controlState & winterm.SHIFT_PRESSED)
|
|
|
+ alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED))
|
|
|
+ control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED))
|
|
|
return shift, alt, control
|
|
|
}
|
|
|
|
|
|
// getControlKeysModifier returns the ANSI modifier for the given combination of control keys.
|
|
|
func getControlKeysModifier(shift, alt, control, meta bool) string {
|
|
|
if shift && alt && control {
|
|
|
- return KEY_CONTROL_PARAM_8
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_8
|
|
|
}
|
|
|
if alt && control {
|
|
|
- return KEY_CONTROL_PARAM_7
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_7
|
|
|
}
|
|
|
if shift && control {
|
|
|
- return KEY_CONTROL_PARAM_6
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_6
|
|
|
}
|
|
|
if control {
|
|
|
- return KEY_CONTROL_PARAM_5
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_5
|
|
|
}
|
|
|
if shift && alt {
|
|
|
- return KEY_CONTROL_PARAM_4
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_4
|
|
|
}
|
|
|
if alt {
|
|
|
- return KEY_CONTROL_PARAM_3
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_3
|
|
|
}
|
|
|
if shift {
|
|
|
- return KEY_CONTROL_PARAM_2
|
|
|
+ return ansiterm.KEY_CONTROL_PARAM_2
|
|
|
}
|
|
|
return ""
|
|
|
}
|