gobot.io/x/gobot@v1.16.0/platforms/keyboard/keyboard.go (about) 1 package keyboard 2 3 import ( 4 "os" 5 "os/exec" 6 ) 7 8 type bytes [3]byte 9 10 // KeyEvent contains data about a keyboard event 11 type KeyEvent struct { 12 Bytes bytes 13 Key int 14 Char string 15 } 16 17 const ( 18 Tilde = iota + 96 19 A 20 B 21 C 22 D 23 E 24 F 25 G 26 H 27 I 28 J 29 K 30 L 31 M 32 N 33 O 34 P 35 Q 36 R 37 S 38 T 39 U 40 V 41 W 42 X 43 Y 44 Z 45 ) 46 47 const ( 48 Escape = 27 49 Spacebar = 32 50 Hyphen = 45 51 Asterisk = 42 52 Plus = 43 53 Slash = 47 54 Dot = 46 55 ) 56 57 const ( 58 Zero = iota + 48 59 One 60 Two 61 Three 62 Four 63 Five 64 Six 65 Seven 66 Eight 67 Nine 68 ) 69 70 const ( 71 ArrowUp = iota + 65 72 ArrowDown 73 ArrowRight 74 ArrowLeft 75 ) 76 77 // used to hold the original stty state 78 var originalState string 79 80 func Parse(input bytes) KeyEvent { 81 var event = KeyEvent{Bytes: input, Char: string(input[:])} 82 83 var code byte 84 85 // basic input codes 86 if input[1] == 0 && input[2] == 0 { 87 code = input[0] 88 89 // space bar 90 if code == Spacebar { 91 event.Key = Spacebar 92 } 93 94 // vanilla escape 95 if code == Escape { 96 event.Key = Escape 97 } 98 99 // Hyphen 100 if code == Hyphen { 101 event.Key = Hyphen 102 } 103 104 // Asterisk 105 if code == Asterisk { 106 event.Key = Asterisk 107 } 108 109 // Plus 110 if code == Plus { 111 event.Key = Plus 112 } 113 114 // Slash 115 if code == Slash { 116 event.Key = Slash 117 } 118 119 // Dot 120 if code == Dot { 121 event.Key = Dot 122 } 123 124 // number keys 125 if code >= 48 && code <= 57 { 126 event.Key = int(code) 127 } 128 129 // alphabet 130 if code >= 97 && code <= 122 { 131 event.Key = int(code) 132 } 133 134 return event 135 } 136 137 // arrow keys 138 if input[0] == Escape && input[1] == 91 { 139 code = input[2] 140 141 if code >= 65 && code <= 68 { 142 event.Key = int(code) 143 return event 144 } 145 } 146 147 return event 148 } 149 150 // fetches original state, sets up TTY for raw (unbuffered) input 151 func configure() (err error) { 152 state, err := stty("-g") 153 if err != nil { 154 return err 155 } 156 157 originalState = state 158 159 // -echo: terminal doesn't echo typed characters back to the terminal 160 // -icanon: terminal doesn't interpret special characters (like backspace) 161 if _, err := stty("-echo", "-icanon"); err != nil { 162 return err 163 } 164 165 return 166 } 167 168 // restores the TTY to the original state 169 func restore() (err error) { 170 if _, err = stty("echo"); err != nil { 171 return 172 } 173 174 if _, err = stty(originalState); err != nil { 175 return 176 } 177 178 return 179 } 180 181 func stty(args ...string) (string, error) { 182 cmd := exec.Command("stty", args...) 183 cmd.Stdin = os.Stdin 184 185 out, err := cmd.Output() 186 if err != nil { 187 return "", err 188 } 189 190 return string(out), nil 191 }