blob: f831727d150662e3bb3ad6e90d4bd2d0ffafa327 [file] [log] [blame]
Matt Mowere04eee72016-12-31 00:38:57 -06001/*
2 Copyright 2017 TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
Dees_Troy51a0e822012-09-05 15:24:24 -040019// hardwarekeyboard.cpp - HardwareKeyboard object
Dees_Troy51a0e822012-09-05 15:24:24 -040020
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <fcntl.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040026#include <sys/stat.h>
27#include <sys/time.h>
28#include <sys/mman.h>
29#include <sys/types.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040030#include <time.h>
31#include <unistd.h>
32#include <stdlib.h>
33
34#include <string>
35
36extern "C" {
Ethan Yonkere13fa632015-01-27 11:30:03 -060037#include "../common.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040038}
39
Dees_Troy51a0e822012-09-05 15:24:24 -040040#include "objects.hpp"
that9fa51532015-01-29 02:04:47 +010041#include <linux/input.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040042
thatf37aec22015-02-01 13:38:35 +010043HardwareKeyboard::HardwareKeyboard()
44 : mLastKeyChar(0)
45{
Dees_Troy51a0e822012-09-05 15:24:24 -040046}
47
thatf37aec22015-02-01 13:38:35 +010048HardwareKeyboard::~HardwareKeyboard()
49{
Dees_Troy51a0e822012-09-05 15:24:24 -040050}
51
thatf37aec22015-02-01 13:38:35 +010052// Map keys to other keys.
53static int TranslateKeyCode(int key_code)
54{
55 switch (key_code) {
thatf37aec22015-02-01 13:38:35 +010056 case KEY_SLEEP: // Lock key on Asus Transformer hardware keyboard
57 return KEY_POWER;
58 }
59 return key_code;
60}
Ethan Yonkere13fa632015-01-27 11:30:03 -060061
that8834a0f2016-01-05 23:29:30 +010062static int KeyCodeToChar(int key_code, bool shiftkey, bool ctrlkey)
thatf37aec22015-02-01 13:38:35 +010063{
thatf37aec22015-02-01 13:38:35 +010064 int keyboard = -1;
65
Ethan Yonkere13fa632015-01-27 11:30:03 -060066 switch (key_code) {
Ethan Yonkere13fa632015-01-27 11:30:03 -060067 case KEY_A:
68 if (shiftkey)
69 keyboard = 'A';
70 else
71 keyboard = 'a';
72 break;
73 case KEY_B:
74 if (shiftkey)
75 keyboard = 'B';
76 else
77 keyboard = 'b';
78 break;
79 case KEY_C:
80 if (shiftkey)
81 keyboard = 'C';
82 else
83 keyboard = 'c';
84 break;
85 case KEY_D:
86 if (shiftkey)
87 keyboard = 'D';
88 else
89 keyboard = 'd';
90 break;
91 case KEY_E:
92 if (shiftkey)
93 keyboard = 'E';
94 else
95 keyboard = 'e';
96 break;
97 case KEY_F:
98 if (shiftkey)
99 keyboard = 'F';
100 else
101 keyboard = 'f';
102 break;
103 case KEY_G:
104 if (shiftkey)
105 keyboard = 'G';
106 else
107 keyboard = 'g';
108 break;
109 case KEY_H:
110 if (shiftkey)
111 keyboard = 'H';
112 else
113 keyboard = 'h';
114 break;
115 case KEY_I:
116 if (shiftkey)
117 keyboard = 'I';
118 else
119 keyboard = 'i';
120 break;
121 case KEY_J:
122 if (shiftkey)
123 keyboard = 'J';
124 else
125 keyboard = 'j';
126 break;
127 case KEY_K:
128 if (shiftkey)
129 keyboard = 'K';
130 else
131 keyboard = 'k';
132 break;
133 case KEY_L:
134 if (shiftkey)
135 keyboard = 'L';
136 else
137 keyboard = 'l';
138 break;
139 case KEY_M:
140 if (shiftkey)
141 keyboard = 'M';
142 else
143 keyboard = 'm';
144 break;
145 case KEY_N:
146 if (shiftkey)
147 keyboard = 'N';
148 else
149 keyboard = 'n';
150 break;
151 case KEY_O:
152 if (shiftkey)
153 keyboard = 'O';
154 else
155 keyboard = 'o';
156 break;
157 case KEY_P:
158 if (shiftkey)
159 keyboard = 'P';
160 else
161 keyboard = 'p';
162 break;
163 case KEY_Q:
164 if (shiftkey)
165 keyboard = 'Q';
166 else
167 keyboard = 'q';
168 break;
169 case KEY_R:
170 if (shiftkey)
171 keyboard = 'R';
172 else
173 keyboard = 'r';
174 break;
175 case KEY_S:
176 if (shiftkey)
177 keyboard = 'S';
178 else
179 keyboard = 's';
180 break;
181 case KEY_T:
182 if (shiftkey)
183 keyboard = 'T';
184 else
185 keyboard = 't';
186 break;
187 case KEY_U:
188 if (shiftkey)
189 keyboard = 'U';
190 else
191 keyboard = 'u';
192 break;
193 case KEY_V:
194 if (shiftkey)
195 keyboard = 'V';
196 else
197 keyboard = 'v';
198 break;
199 case KEY_W:
200 if (shiftkey)
201 keyboard = 'W';
202 else
203 keyboard = 'w';
204 break;
205 case KEY_X:
206 if (shiftkey)
207 keyboard = 'X';
208 else
209 keyboard = 'x';
210 break;
211 case KEY_Y:
212 if (shiftkey)
213 keyboard = 'Y';
214 else
215 keyboard = 'y';
216 break;
217 case KEY_Z:
218 if (shiftkey)
219 keyboard = 'Z';
220 else
221 keyboard = 'z';
222 break;
223 case KEY_0:
224 if (shiftkey)
225 keyboard = ')';
226 else
227 keyboard = '0';
228 break;
229 case KEY_1:
230 if (shiftkey)
231 keyboard = '!';
232 else
233 keyboard = '1';
234 break;
235 case KEY_2:
236 if (shiftkey)
237 keyboard = '@';
238 else
239 keyboard = '2';
240 break;
241 case KEY_3:
242 if (shiftkey)
243 keyboard = '#';
244 else
245 keyboard = '3';
246 break;
247 case KEY_4:
248 if (shiftkey)
249 keyboard = '$';
250 else
251 keyboard = '4';
252 break;
253 case KEY_5:
254 if (shiftkey)
255 keyboard = '%';
256 else
257 keyboard = '5';
258 break;
259 case KEY_6:
260 if (shiftkey)
261 keyboard = '^';
262 else
263 keyboard = '6';
264 break;
265 case KEY_7:
266 if (shiftkey)
267 keyboard = '&';
268 else
269 keyboard = '7';
270 break;
271 case KEY_8:
272 if (shiftkey)
273 keyboard = '*';
274 else
275 keyboard = '8';
276 break;
277 case KEY_9:
278 if (shiftkey)
279 keyboard = '(';
280 else
281 keyboard = '9';
282 break;
283 case KEY_SPACE:
284 keyboard = ' ';
285 break;
286 case KEY_BACKSPACE:
287 keyboard = KEYBOARD_BACKSPACE;
288 break;
that8834a0f2016-01-05 23:29:30 +0100289 case KEY_TAB:
290 keyboard = KEYBOARD_TAB;
291 break;
Ethan Yonkere13fa632015-01-27 11:30:03 -0600292 case KEY_ENTER:
293 keyboard = KEYBOARD_ACTION;
294 break;
295 case KEY_SLASH:
296 if (shiftkey)
297 keyboard = '?';
298 else
299 keyboard = '/';
300 break;
301 case KEY_DOT:
302 if (shiftkey)
303 keyboard = '>';
304 else
305 keyboard = '.';
306 break;
307 case KEY_COMMA:
308 if (shiftkey)
309 keyboard = '<';
310 else
311 keyboard = ',';
312 break;
313 case KEY_MINUS:
314 if (shiftkey)
315 keyboard = '_';
316 else
317 keyboard = '-';
318 break;
319 case KEY_GRAVE:
320 if (shiftkey)
321 keyboard = '~';
322 else
323 keyboard = '`';
324 break;
325 case KEY_EQUAL:
326 if (shiftkey)
327 keyboard = '+';
328 else
329 keyboard = '=';
330 break;
331 case KEY_LEFTBRACE:
332 if (shiftkey)
333 keyboard = '{';
334 else
335 keyboard = '[';
336 break;
337 case KEY_RIGHTBRACE:
338 if (shiftkey)
339 keyboard = '}';
340 else
341 keyboard = ']';
342 break;
343 case KEY_BACKSLASH:
344 if (shiftkey)
345 keyboard = '|';
346 else
347 keyboard = '\\';
348 break;
349 case KEY_SEMICOLON:
350 if (shiftkey)
351 keyboard = ':';
352 else
353 keyboard = ';';
354 break;
355 case KEY_APOSTROPHE:
356 if (shiftkey)
357 keyboard = '\"';
358 else
359 keyboard = '\'';
360 break;
thatf37aec22015-02-01 13:38:35 +0100361
Ethan Yonkere13fa632015-01-27 11:30:03 -0600362#ifdef _EVENT_LOGGING
363 default:
364 LOGE("Unmapped keycode: %i\n", key_code);
365 break;
366#endif
367 }
that8834a0f2016-01-05 23:29:30 +0100368 if (ctrlkey)
369 {
370 if (keyboard >= 96)
371 keyboard -= 96;
372 else
373 keyboard = -1;
374 }
375 return keyboard;
376}
377
378bool HardwareKeyboard::IsKeyDown(int key_code)
379{
380 std::set<int>::iterator it = mPressedKeys.find(key_code);
381 return (it != mPressedKeys.end());
382}
383
384int HardwareKeyboard::KeyDown(int key_code)
385{
386#ifdef _EVENT_LOGGING
387 LOGE("HardwareKeyboard::KeyDown %i\n", key_code);
388#endif
389 key_code = TranslateKeyCode(key_code);
390 mPressedKeys.insert(key_code);
391
392 bool ctrlkey = IsKeyDown(KEY_LEFTCTRL) || IsKeyDown(KEY_RIGHTCTRL);
393 bool shiftkey = IsKeyDown(KEY_LEFTSHIFT) || IsKeyDown(KEY_RIGHTSHIFT);
394
395 int ch = KeyCodeToChar(key_code, shiftkey, ctrlkey);
396
397 if (ch != -1) {
398 mLastKeyChar = ch;
399 if (!PageManager::NotifyCharInput(ch))
Ethan Yonkere13fa632015-01-27 11:30:03 -0600400 return 1; // Return 1 to enable key repeat
401 } else {
thatf37aec22015-02-01 13:38:35 +0100402 mLastKeyChar = 0;
that8834a0f2016-01-05 23:29:30 +0100403 mLastKey = key_code;
404 if (!PageManager::NotifyKey(key_code, true))
405 return 1; // Return 1 to enable key repeat
Ethan Yonkere13fa632015-01-27 11:30:03 -0600406 }
407 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400408}
409
thatf37aec22015-02-01 13:38:35 +0100410int HardwareKeyboard::KeyUp(int key_code)
411{
412#ifdef _EVENT_LOGGING
413 LOGE("HardwareKeyboard::KeyUp %i\n", key_code);
414#endif
415 key_code = TranslateKeyCode(key_code);
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100416 std::set<int>::iterator itr = mPressedKeys.find(key_code);
Ethan Yonkere13fa632015-01-27 11:30:03 -0600417 if (itr != mPressedKeys.end()) {
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100418 mPressedKeys.erase(itr);
419 PageManager::NotifyKey(key_code, false);
420 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400421 return 0;
422}
423
thatf37aec22015-02-01 13:38:35 +0100424int HardwareKeyboard::KeyRepeat()
425{
Dees_Troy51a0e822012-09-05 15:24:24 -0400426#ifdef _EVENT_LOGGING
thatf37aec22015-02-01 13:38:35 +0100427 LOGE("HardwareKeyboard::KeyRepeat: %i\n", mLastKeyChar);
Dees_Troy51a0e822012-09-05 15:24:24 -0400428#endif
thatf37aec22015-02-01 13:38:35 +0100429 if (mLastKeyChar)
that8834a0f2016-01-05 23:29:30 +0100430 PageManager::NotifyCharInput(mLastKeyChar);
431 else if (mLastKey)
432 PageManager::NotifyKey(mLastKey, true);
Dees_Troy51a0e822012-09-05 15:24:24 -0400433 return 0;
434}
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100435
thatf37aec22015-02-01 13:38:35 +0100436void HardwareKeyboard::ConsumeKeyRelease(int key)
437{
438 // causes following KeyUp event to suppress notifications
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100439 mPressedKeys.erase(key);
440}