| /* |
| Copyright 2017 TeamWin |
| This file is part of TWRP/TeamWin Recovery Project. |
| |
| TWRP is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| TWRP is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with TWRP. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| // hardwarekeyboard.cpp - HardwareKeyboard object |
| |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <fcntl.h> |
| #include <sys/stat.h> |
| #include <sys/time.h> |
| #include <sys/mman.h> |
| #include <sys/types.h> |
| #include <time.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| |
| #include <string> |
| |
| extern "C" { |
| #include "common.h" |
| } |
| |
| #include "../twcommon.h" |
| #include "objects.hpp" |
| #include <linux/input.h> |
| |
| HardwareKeyboard::HardwareKeyboard() |
| : mLastKeyChar(0) |
| { |
| } |
| |
| HardwareKeyboard::~HardwareKeyboard() |
| { |
| } |
| |
| // Map keys to other keys. |
| static int TranslateKeyCode(int key_code) |
| { |
| switch (key_code) { |
| case KEY_SLEEP: // Lock key on Asus Transformer hardware keyboard |
| return KEY_POWER; |
| } |
| return key_code; |
| } |
| |
| static int KeyCodeToChar(int key_code, bool shiftkey, bool ctrlkey) |
| { |
| int keyboard = -1; |
| |
| switch (key_code) { |
| case KEY_A: |
| if (shiftkey) |
| keyboard = 'A'; |
| else |
| keyboard = 'a'; |
| break; |
| case KEY_B: |
| if (shiftkey) |
| keyboard = 'B'; |
| else |
| keyboard = 'b'; |
| break; |
| case KEY_C: |
| if (shiftkey) |
| keyboard = 'C'; |
| else |
| keyboard = 'c'; |
| break; |
| case KEY_D: |
| if (shiftkey) |
| keyboard = 'D'; |
| else |
| keyboard = 'd'; |
| break; |
| case KEY_E: |
| if (shiftkey) |
| keyboard = 'E'; |
| else |
| keyboard = 'e'; |
| break; |
| case KEY_F: |
| if (shiftkey) |
| keyboard = 'F'; |
| else |
| keyboard = 'f'; |
| break; |
| case KEY_G: |
| if (shiftkey) |
| keyboard = 'G'; |
| else |
| keyboard = 'g'; |
| break; |
| case KEY_H: |
| if (shiftkey) |
| keyboard = 'H'; |
| else |
| keyboard = 'h'; |
| break; |
| case KEY_I: |
| if (shiftkey) |
| keyboard = 'I'; |
| else |
| keyboard = 'i'; |
| break; |
| case KEY_J: |
| if (shiftkey) |
| keyboard = 'J'; |
| else |
| keyboard = 'j'; |
| break; |
| case KEY_K: |
| if (shiftkey) |
| keyboard = 'K'; |
| else |
| keyboard = 'k'; |
| break; |
| case KEY_L: |
| if (shiftkey) |
| keyboard = 'L'; |
| else |
| keyboard = 'l'; |
| break; |
| case KEY_M: |
| if (shiftkey) |
| keyboard = 'M'; |
| else |
| keyboard = 'm'; |
| break; |
| case KEY_N: |
| if (shiftkey) |
| keyboard = 'N'; |
| else |
| keyboard = 'n'; |
| break; |
| case KEY_O: |
| if (shiftkey) |
| keyboard = 'O'; |
| else |
| keyboard = 'o'; |
| break; |
| case KEY_P: |
| if (shiftkey) |
| keyboard = 'P'; |
| else |
| keyboard = 'p'; |
| break; |
| case KEY_Q: |
| if (shiftkey) |
| keyboard = 'Q'; |
| else |
| keyboard = 'q'; |
| break; |
| case KEY_R: |
| if (shiftkey) |
| keyboard = 'R'; |
| else |
| keyboard = 'r'; |
| break; |
| case KEY_S: |
| if (shiftkey) |
| keyboard = 'S'; |
| else |
| keyboard = 's'; |
| break; |
| case KEY_T: |
| if (shiftkey) |
| keyboard = 'T'; |
| else |
| keyboard = 't'; |
| break; |
| case KEY_U: |
| if (shiftkey) |
| keyboard = 'U'; |
| else |
| keyboard = 'u'; |
| break; |
| case KEY_V: |
| if (shiftkey) |
| keyboard = 'V'; |
| else |
| keyboard = 'v'; |
| break; |
| case KEY_W: |
| if (shiftkey) |
| keyboard = 'W'; |
| else |
| keyboard = 'w'; |
| break; |
| case KEY_X: |
| if (shiftkey) |
| keyboard = 'X'; |
| else |
| keyboard = 'x'; |
| break; |
| case KEY_Y: |
| if (shiftkey) |
| keyboard = 'Y'; |
| else |
| keyboard = 'y'; |
| break; |
| case KEY_Z: |
| if (shiftkey) |
| keyboard = 'Z'; |
| else |
| keyboard = 'z'; |
| break; |
| case KEY_0: |
| if (shiftkey) |
| keyboard = ')'; |
| else |
| keyboard = '0'; |
| break; |
| case KEY_1: |
| if (shiftkey) |
| keyboard = '!'; |
| else |
| keyboard = '1'; |
| break; |
| case KEY_2: |
| if (shiftkey) |
| keyboard = '@'; |
| else |
| keyboard = '2'; |
| break; |
| case KEY_3: |
| if (shiftkey) |
| keyboard = '#'; |
| else |
| keyboard = '3'; |
| break; |
| case KEY_4: |
| if (shiftkey) |
| keyboard = '$'; |
| else |
| keyboard = '4'; |
| break; |
| case KEY_5: |
| if (shiftkey) |
| keyboard = '%'; |
| else |
| keyboard = '5'; |
| break; |
| case KEY_6: |
| if (shiftkey) |
| keyboard = '^'; |
| else |
| keyboard = '6'; |
| break; |
| case KEY_7: |
| if (shiftkey) |
| keyboard = '&'; |
| else |
| keyboard = '7'; |
| break; |
| case KEY_8: |
| if (shiftkey) |
| keyboard = '*'; |
| else |
| keyboard = '8'; |
| break; |
| case KEY_9: |
| if (shiftkey) |
| keyboard = '('; |
| else |
| keyboard = '9'; |
| break; |
| case KEY_SPACE: |
| keyboard = ' '; |
| break; |
| case KEY_BACKSPACE: |
| keyboard = KEYBOARD_BACKSPACE; |
| break; |
| case KEY_TAB: |
| keyboard = KEYBOARD_TAB; |
| break; |
| case KEY_ENTER: |
| keyboard = KEYBOARD_ACTION; |
| break; |
| case KEY_SLASH: |
| if (shiftkey) |
| keyboard = '?'; |
| else |
| keyboard = '/'; |
| break; |
| case KEY_DOT: |
| if (shiftkey) |
| keyboard = '>'; |
| else |
| keyboard = '.'; |
| break; |
| case KEY_COMMA: |
| if (shiftkey) |
| keyboard = '<'; |
| else |
| keyboard = ','; |
| break; |
| case KEY_MINUS: |
| if (shiftkey) |
| keyboard = '_'; |
| else |
| keyboard = '-'; |
| break; |
| case KEY_GRAVE: |
| if (shiftkey) |
| keyboard = '~'; |
| else |
| keyboard = '`'; |
| break; |
| case KEY_EQUAL: |
| if (shiftkey) |
| keyboard = '+'; |
| else |
| keyboard = '='; |
| break; |
| case KEY_LEFTBRACE: |
| if (shiftkey) |
| keyboard = '{'; |
| else |
| keyboard = '['; |
| break; |
| case KEY_RIGHTBRACE: |
| if (shiftkey) |
| keyboard = '}'; |
| else |
| keyboard = ']'; |
| break; |
| case KEY_BACKSLASH: |
| if (shiftkey) |
| keyboard = '|'; |
| else |
| keyboard = '\\'; |
| break; |
| case KEY_SEMICOLON: |
| if (shiftkey) |
| keyboard = ':'; |
| else |
| keyboard = ';'; |
| break; |
| case KEY_APOSTROPHE: |
| if (shiftkey) |
| keyboard = '\"'; |
| else |
| keyboard = '\''; |
| break; |
| |
| #ifdef _EVENT_LOGGING |
| default: |
| LOGERR("Unmapped keycode: %i\n", key_code); |
| break; |
| #endif |
| } |
| if (ctrlkey) |
| { |
| if (keyboard >= 96) |
| keyboard -= 96; |
| else |
| keyboard = -1; |
| } |
| return keyboard; |
| } |
| |
| bool HardwareKeyboard::IsKeyDown(int key_code) |
| { |
| std::set<int>::iterator it = mPressedKeys.find(key_code); |
| return (it != mPressedKeys.end()); |
| } |
| |
| int HardwareKeyboard::KeyDown(int key_code) |
| { |
| #ifdef _EVENT_LOGGING |
| LOGERR("HardwareKeyboard::KeyDown %i\n", key_code); |
| #endif |
| key_code = TranslateKeyCode(key_code); |
| mPressedKeys.insert(key_code); |
| |
| bool ctrlkey = IsKeyDown(KEY_LEFTCTRL) || IsKeyDown(KEY_RIGHTCTRL); |
| bool shiftkey = IsKeyDown(KEY_LEFTSHIFT) || IsKeyDown(KEY_RIGHTSHIFT); |
| |
| int ch = KeyCodeToChar(key_code, shiftkey, ctrlkey); |
| |
| if (ch != -1) { |
| mLastKeyChar = ch; |
| if (!PageManager::NotifyCharInput(ch)) |
| return 1; // Return 1 to enable key repeat |
| } else { |
| mLastKeyChar = 0; |
| mLastKey = key_code; |
| if (!PageManager::NotifyKey(key_code, true)) |
| return 1; // Return 1 to enable key repeat |
| } |
| return 0; |
| } |
| |
| int HardwareKeyboard::KeyUp(int key_code) |
| { |
| #ifdef _EVENT_LOGGING |
| LOGERR("HardwareKeyboard::KeyUp %i\n", key_code); |
| #endif |
| key_code = TranslateKeyCode(key_code); |
| std::set<int>::iterator itr = mPressedKeys.find(key_code); |
| if (itr != mPressedKeys.end()) { |
| mPressedKeys.erase(itr); |
| PageManager::NotifyKey(key_code, false); |
| } |
| return 0; |
| } |
| |
| int HardwareKeyboard::KeyRepeat() |
| { |
| #ifdef _EVENT_LOGGING |
| LOGERR("HardwareKeyboard::KeyRepeat: %i\n", mLastKeyChar); |
| #endif |
| if (mLastKeyChar) |
| PageManager::NotifyCharInput(mLastKeyChar); |
| else if (mLastKey) |
| PageManager::NotifyKey(mLastKey, true); |
| return 0; |
| } |
| |
| void HardwareKeyboard::ConsumeKeyRelease(int key) |
| { |
| // causes following KeyUp event to suppress notifications |
| mPressedKeys.erase(key); |
| } |