/* * Apple // emulator for *ix * * This software package is subject to the GNU General Public License * version 3 or later (your choice) as published by the Free Software * Foundation. * * Copyright 2015 Aaron Culliney * */ #include "common.h" #include "androidkeys.h" // Codepaths for Bluetooth or other HID keyboards attached to an Android device. // For OpenGL emulated touchscreen keyboard, see gltouchkbd.c static inline bool _is_shifted(int metaState) { return (metaState & META_SHIFT_MASK); } static inline bool _is_ctrl(int metaState) { return (metaState & META_CTRL_LEFT_ON) || (metaState & META_CTRL_RIGHT_ON); } void android_keycode_to_emulator(int keyCode, int metaState, bool pressed) { int key = -1; bool isASCII = true; do { if ((keyCode >= KEYCODE_NUMPAD_0) && (keyCode <= KEYCODE_NUMPAD_9)) { key = keyCode - ASCII_NUMPAD_0_OFFSET; break; } else if ((keyCode >= KEYCODE_A) && (keyCode <= KEYCODE_Z)) { key = caps_lock || _is_shifted(metaState) ? (keyCode + ASCII_UCASE_OFFSET) : (keyCode + ASCII_LCASE_OFFSET); break; } else if ((keyCode >= KEYCODE_F1) && (keyCode <= KEYCODE_F12)) { isASCII = false; key = keyCode - FN_OFFSET; break; } switch (keyCode) { case KEYCODE_BUTTON_A: case KEYCODE_BUTTON_X: case KEYCODE_BUTTON_L1: joydriver_setButton0Pressed(pressed); return; case KEYCODE_BUTTON_B: case KEYCODE_BUTTON_Y: case KEYCODE_BUTTON_R1: joydriver_setButton1Pressed(pressed); return; } switch (keyCode) { case KEYCODE_0: key = _is_shifted(metaState) ? ')' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_1: key = _is_shifted(metaState) ? '!' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_2: key = _is_shifted(metaState) ? '@' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_3: key = _is_shifted(metaState) ? '#' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_4: key = _is_shifted(metaState) ? '$' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_5: key = _is_shifted(metaState) ? '%' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_6: key = _is_shifted(metaState) ? '^' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_7: key = _is_shifted(metaState) ? '&' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_8: key = _is_shifted(metaState) ? '*' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_9: key = _is_shifted(metaState) ? '(' : keyCode + ASCII_0_OFFSET; break; case KEYCODE_APOSTROPHE: key = _is_shifted(metaState) ? '"' : '\''; break; case KEYCODE_AT: key = '@'; break; case KEYCODE_BACKSLASH: key = _is_shifted(metaState) ? '|' : '\\'; break; case KEYCODE_COMMA: key = _is_shifted(metaState) ? '<' : ','; break; case KEYCODE_EQUALS: key = _is_shifted(metaState) ? '+' : '='; break; case KEYCODE_GRAVE: key = _is_shifted(metaState) ? '~' : '`'; break; case KEYCODE_LEFT_BRACKET: key = _is_shifted(metaState) ? '{' : '['; break; case KEYCODE_MINUS: key = _is_shifted(metaState) ? '_' : '-'; break; case KEYCODE_NUMPAD_ADD: key = '+'; break; case KEYCODE_NUMPAD_COMMA: key = ','; break; case KEYCODE_NUMPAD_DIVIDE: key = '/'; break; case KEYCODE_NUMPAD_DOT: key = '.'; break; case KEYCODE_NUMPAD_EQUALS: key = '='; break; case KEYCODE_NUMPAD_LEFT_PAREN: key = '('; break; case KEYCODE_NUMPAD_RIGHT_PAREN: key = ')'; break; case KEYCODE_NUMPAD_MULTIPLY: key = '*'; break; case KEYCODE_NUMPAD_SUBTRACT: key = '-'; break; case KEYCODE_PERIOD: key = _is_shifted(metaState) ? '>' : '.'; break; case KEYCODE_PLUS: key = '+'; break; case KEYCODE_POUND: key = '#'; break; case KEYCODE_RIGHT_BRACKET: key = _is_shifted(metaState) ? '}' : ']'; break; case KEYCODE_SEMICOLON: key = _is_shifted(metaState) ? ':' : ';'; break; case KEYCODE_SLASH: key = _is_shifted(metaState) ? '?' : '/'; break; case KEYCODE_SPACE: key = ' '; break; case KEYCODE_STAR: key = '*'; break; default: break; } if (key != -1) { break; } // META isASCII = false; switch (keyCode) { case KEYCODE_DPAD_LEFT: key = SCODE_L; break; case KEYCODE_DPAD_RIGHT: key = SCODE_R; break; case KEYCODE_DPAD_DOWN: key = SCODE_D; break; case KEYCODE_DPAD_UP: key = SCODE_U; break; case KEYCODE_DPAD_CENTER: key = SCODE_HOME; break; case KEYCODE_PAGE_UP: key = SCODE_PGUP; break; case KEYCODE_PAGE_DOWN: key = SCODE_PGDN; break; case KEYCODE_INSERT: key = SCODE_INS; break; case KEYCODE_SHIFT_LEFT: key = SCODE_L_SHIFT; break; case KEYCODE_SHIFT_RIGHT: key = SCODE_R_SHIFT; break; case KEYCODE_CTRL_LEFT: key = SCODE_L_CTRL; break; case KEYCODE_CTRL_RIGHT: key = SCODE_R_CTRL; break; case KEYCODE_ALT_LEFT: case KEYCODE_META_LEFT: key = SCODE_L_ALT; break; case KEYCODE_ALT_RIGHT: case KEYCODE_META_RIGHT: key = SCODE_R_ALT; break; case KEYCODE_BREAKPAUSE: key = SCODE_BRK; break; case KEYCODE_CAPS_LOCK: caps_lock = (metaState & META_CAPS_LOCK_ON); return; case KEYCODE_DEL: key = SCODE_L;// DEL is prolly not what they meant =P break; case KEYCODE_ENTER: key = SCODE_RET; break; case KEYCODE_TAB: key = SCODE_TAB; break; case KEYCODE_ESC: key = SCODE_ESC; break; default: break; } } while (0); if (key < 0) { return; } //LOG("keyCode:%08x -> key:%02x ('%c') metaState:%08x", keyCode, key, key, metaState); if (isASCII && _is_ctrl(metaState)) { key = keys_ascii2Scancode(key); keys_handleInput(key, /*is_pressed:*/true, /*is_ascii:*/false); isASCII = false; pressed = false; } assert(key < 0x80); keys_handleInput(key, pressed, isASCII); }