-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathusb_driver.go
More file actions
135 lines (120 loc) · 3.6 KB
/
usb_driver.go
File metadata and controls
135 lines (120 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package bootcommand
import (
"fmt"
"log"
"os"
"strings"
"time"
"unicode"
"golang.org/x/mobile/event/key"
)
// SendUsbScanCodes will be called to send codes to the VM
type SendUsbScanCodes func(k key.Code, down bool) error
type usbDriver struct {
sendImpl SendUsbScanCodes
interval time.Duration
specialMap map[string]key.Code
scancodeMap map[rune]key.Code
}
func NewUSBDriver(send SendUsbScanCodes, interval time.Duration) *usbDriver {
// We delay (default 100ms) between each key event to allow for CPU or
// network latency. See PackerKeyEnv for tuning.
keyInterval := PackerKeyDefault
if delay, err := time.ParseDuration(os.Getenv(PackerKeyEnv)); err == nil {
keyInterval = delay
}
// override interval based on builder-specific override.
if interval > time.Duration(0) {
keyInterval = interval
}
special := map[string]key.Code{
"enter": key.CodeReturnEnter,
"return": key.CodeReturnEnter,
"esc": key.CodeEscape,
"bs": key.CodeDeleteBackspace,
"del": key.CodeDeleteForward,
"tab": key.CodeTab,
"f1": key.CodeF1,
"f2": key.CodeF2,
"f3": key.CodeF3,
"f4": key.CodeF4,
"f5": key.CodeF5,
"f6": key.CodeF6,
"f7": key.CodeF7,
"f8": key.CodeF8,
"f9": key.CodeF9,
"f10": key.CodeF10,
"f11": key.CodeF11,
"f12": key.CodeF12,
"insert": key.CodeInsert,
"home": key.CodeHome,
"end": key.CodeEnd,
"pageup": key.CodePageUp,
"pagedown": key.CodePageDown,
"left": key.CodeLeftArrow,
"right": key.CodeRightArrow,
"up": key.CodeUpArrow,
"down": key.CodeDownArrow,
"leftalt": key.CodeLeftAlt,
"leftctrl": key.CodeLeftControl,
"leftshift": key.CodeLeftShift,
"rightalt": key.CodeRightAlt,
"rightctrl": key.CodeRightControl,
"rightshift": key.CodeRightShift,
"leftsuper": key.CodeLeftGUI,
"rightsuper": key.CodeRightGUI,
"spacebar": key.CodeSpacebar,
}
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
var scancodeMap = make(map[rune]key.Code)
for chars, start := range scancodeIndex {
for i, r := range chars {
scancodeMap[r] = start + key.Code(i)
}
}
return &usbDriver{
sendImpl: send,
specialMap: special,
interval: keyInterval,
scancodeMap: scancodeMap,
}
}
func (d *usbDriver) keyEvent(k key.Code, down bool) error {
if err := d.sendImpl(k, down); err != nil {
return err
}
time.Sleep(d.interval)
return nil
}
func (d *usbDriver) Flush() error {
return nil
}
func (d *usbDriver) SendKey(k rune, action KeyAction) error {
keyShift := unicode.IsUpper(k) || strings.ContainsRune(shiftedChars, k)
keyCode := d.scancodeMap[k]
log.Printf("Sending char '%c', code %s, shift %v", k, keyCode, keyShift)
return d.keyEvent(keyCode, keyShift)
}
func (d *usbDriver) SendSpecial(special string, action KeyAction) (err error) {
keyCode, ok := d.specialMap[special]
if !ok {
return fmt.Errorf("special %s not found.", special)
}
log.Printf("Special code '<%s>' found, replacing with: %s", special, keyCode)
switch action {
case KeyOn:
err = d.keyEvent(keyCode, true)
case KeyOff, KeyPress:
err = d.keyEvent(keyCode, false)
}
return err
}