83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
|
package driver
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"unicode"
|
||
|
"github.com/vmware/govmomi/vim25/types"
|
||
|
"github.com/vmware/govmomi/vim25/methods"
|
||
|
"golang.org/x/mobile/event/key"
|
||
|
)
|
||
|
|
||
|
type KeyInput struct {
|
||
|
Message string
|
||
|
Scancode key.Code
|
||
|
Alt bool
|
||
|
Ctrl bool
|
||
|
Shift bool
|
||
|
}
|
||
|
|
||
|
var scancodeMap = make(map[rune]key.Code)
|
||
|
|
||
|
func init() {
|
||
|
scancodeIndex := make(map[string]key.Code)
|
||
|
scancodeIndex["abcdefghijklmnopqrstuvwxyz"] = key.CodeA
|
||
|
scancodeIndex["ABCDEFGHIJKLMNOPQRSTUVWXYZ"] = key.CodeA
|
||
|
scancodeIndex["1234567890"] = key.Code1
|
||
|
scancodeIndex["!@#$%^&*()"] = key.Code1
|
||
|
scancodeIndex[" "] = key.CodeSpacebar
|
||
|
scancodeIndex["-=[]\\"] = key.CodeHyphenMinus
|
||
|
scancodeIndex["_+{}|" ] = key.CodeHyphenMinus
|
||
|
scancodeIndex[ ";'`,./" ] = key.CodeSemicolon
|
||
|
scancodeIndex[":\"~<>?" ] = key.CodeSemicolon
|
||
|
|
||
|
for chars, start := range scancodeIndex {
|
||
|
for i, r := range chars {
|
||
|
scancodeMap[r] = start + key.Code(i)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const shiftedChars = "!@#$%^&*()_+{}|:\"~<>?"
|
||
|
|
||
|
func (vm *VirtualMachine) TypeOnKeyboard(input KeyInput) (int32, error) {
|
||
|
var spec types.UsbScanCodeSpec
|
||
|
|
||
|
for _, r := range input.Message {
|
||
|
scancode := scancodeMap[r]
|
||
|
shift := input.Shift || unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r)
|
||
|
|
||
|
spec.KeyEvents = append(spec.KeyEvents, types.UsbScanCodeSpecKeyEvent{
|
||
|
// https://github.com/lamw/vghetto-scripts/blob/f74bc8ba20064f46592bcce5a873b161a7fa3d72/powershell/VMKeystrokes.ps1#L130
|
||
|
UsbHidCode: int32(scancode)<<16 | 7,
|
||
|
Modifiers: &types.UsbScanCodeSpecModifierType{
|
||
|
LeftControl: &input.Ctrl,
|
||
|
LeftAlt: &input.Alt,
|
||
|
LeftShift: &shift,
|
||
|
},
|
||
|
})
|
||
|
}
|
||
|
|
||
|
if input.Scancode != 0 {
|
||
|
spec.KeyEvents = append(spec.KeyEvents, types.UsbScanCodeSpecKeyEvent{
|
||
|
UsbHidCode: int32(input.Scancode)<<16 | 7,
|
||
|
Modifiers: &types.UsbScanCodeSpecModifierType{
|
||
|
LeftControl: &input.Ctrl,
|
||
|
LeftAlt: &input.Alt,
|
||
|
LeftShift: &input.Shift,
|
||
|
},
|
||
|
})
|
||
|
}
|
||
|
|
||
|
req := &types.PutUsbScanCodes{
|
||
|
This: vm.vm.Reference(),
|
||
|
Spec: spec,
|
||
|
}
|
||
|
|
||
|
resp, err := methods.PutUsbScanCodes(vm.driver.ctx, vm.driver.client.RoundTripper, req)
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
|
||
|
return resp.Returnval, nil
|
||
|
}
|