-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathpasskb_linux.go
120 lines (96 loc) · 2.24 KB
/
passkb_linux.go
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
package passkb
import (
"fmt"
"strings"
"time"
"unicode"
"github.com/bendahl/uinput"
)
type keyPress struct {
code int
upper bool
}
var (
upperSymbolMap = map[rune]int{
'~': uinput.KeyGrave,
'{': uinput.KeyLeftbrace,
'}': uinput.KeyRightbrace,
'|': uinput.KeyBackslash,
':': uinput.KeySemicolon,
'"': uinput.KeyApostrophe,
'<': uinput.KeyComma,
'>': uinput.KeyDot,
'?': uinput.KeySlash,
}
)
func keyFromRune(r rune) (*keyPress, error) {
if i := strings.IndexRune("1234567890-=", r); i >= 0 {
return &keyPress{uinput.Key1 + i, false}, nil
}
if i := strings.IndexRune("qwertyuiop[]", r); i >= 0 {
return &keyPress{uinput.KeyQ + i, false}, nil
}
if i := strings.IndexRune("asdfghjkl;'`", r); i >= 0 {
return &keyPress{uinput.KeyA + i, false}, nil
}
if i := strings.IndexRune("\\zxcvbnm,./", r); i >= 0 {
return &keyPress{uinput.KeyBackslash + i, false}, nil
}
if i := strings.IndexRune("!@#$%^&*()_+", r); i >= 0 {
return &keyPress{uinput.Key1 + i, true}, nil
}
if i, ok := upperSymbolMap[r]; ok {
return &keyPress{i, true}, nil
}
if unicode.IsLetter(r) && unicode.IsUpper(r) {
lower, err := keyFromRune(unicode.ToLower(r))
if err != nil {
return nil, fmt.Errorf("Cannot convert character %v to a key", r)
}
lower.upper = true
return lower, nil
}
return nil, fmt.Errorf("Cannot convert character %v to a key", r)
}
func stringToKeys(s string) ([]*keyPress, error) {
var keys []*keyPress
for _, r := range s {
k, err := keyFromRune(r)
if err != nil {
return nil, err
}
keys = append(keys, k)
}
return keys, nil
}
type linuxKeyboard struct {
ukb uinput.Keyboard
}
func New(name string) (Keyboard, error) {
kb, err := uinput.CreateKeyboard("/dev/uinput", []byte(name))
if err != nil {
return nil, err
}
return &linuxKeyboard{kb}, nil
}
func (kb linuxKeyboard) Close() error {
return kb.ukb.Close()
}
func (kb linuxKeyboard) Type(str string, delay time.Duration) error {
keys, err := stringToKeys(str)
if err != nil {
return err
}
time.Sleep(delay)
for _, key := range keys {
if key.upper {
kb.ukb.KeyDown(uinput.KeyLeftshift)
}
time.Sleep(100 * time.Millisecond)
kb.ukb.KeyPress(key.code)
if key.upper {
kb.ukb.KeyUp(uinput.KeyLeftshift)
}
}
return nil
}