84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
package driver
|
|
|
|
import (
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/vmware/govmomi/vim25/methods"
|
|
"github.com/vmware/govmomi/vim25/types"
|
|
"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
|
|
}
|