From afe8d2d617fdcb1bbabd7e9cb32ecc133a63f163 Mon Sep 17 00:00:00 2001 From: Diablodiab Date: Tue, 12 Jan 2016 21:48:09 +0100 Subject: [PATCH] Fixed two bugs in Android keyboard functionality and changed the way the keyboard is registered (introduced an id_3 value) --- input/drivers/android_input.c | 46 ++++++- .../drivers_keyboard/keyboard_event_android.h | 111 ++++++++++++++++ input/input_keymaps.c | 118 ++++++++++++++++++ input/input_keymaps.h | 1 + 4 files changed, 272 insertions(+), 4 deletions(-) diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index 4836058ade..41bba4290c 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -55,6 +55,7 @@ struct input_pointer static int id_1 = -1; static int id_2 = -1; +static int id_3 = -1; enum { @@ -470,7 +471,9 @@ static void *android_input_init(void) android->copy.pads_connected = 0; android->joypad = input_joypad_init_driver( settings->input.joypad_driver, android); - + + input_keymaps_init_keyboard_lut(rarch_key_map_android); + frontend_android_get_version_sdk(&sdk); RARCH_LOG("sdk version: %d\n", sdk); @@ -546,6 +549,25 @@ static INLINE int android_input_poll_event_type_motion( return 0; } +static INLINE void android_input_poll_event_type_keyboard( + AInputEvent *event, int keycode, int *handled) +{ + int keydown = (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN); + unsigned keyboardcode = input_keymaps_translate_keysym_to_rk(keycode); + + // Set keyboard modifier based on shift,ctrl and alt state + uint16_t mod = 0; + int meta = AKeyEvent_getMetaState(event); + if(meta & AMETA_ALT_ON) mod |= RETROKMOD_ALT; + if(meta & AMETA_CTRL_ON) mod |= RETROKMOD_CTRL; + if(meta & AMETA_SHIFT_ON) mod |= RETROKMOD_SHIFT; + + input_keyboard_event(keydown, keyboardcode, keyboardcode, mod, RETRO_DEVICE_KEYBOARD); + + if ((keycode == AKEYCODE_VOLUME_UP || keycode == AKEYCODE_VOLUME_DOWN)) + *handled = 0; +} + static INLINE void android_input_poll_event_type_key( struct android_app *android_app, AInputEvent *event, int port, int keycode, int source, @@ -823,6 +845,18 @@ static void handle_hotplug(android_input_data_t *android_data, else if (strstr(device_name, "MOGA")) strlcpy(name_buf, "Moga IME", sizeof(name_buf)); + // if device is keyboard only and didn't match any of the devices above + // then assume it is a keyboard, register the id, and return unless another + // keyboard is already registered + else if(source == AINPUT_SOURCE_KEYBOARD && id_3 == -1) + { + id_3 = id; + return; + } + + // if device was not keyboard only, yet did not match any of the devices + // above or another keyboard was already mapped, then try to autoconfigure + // as gamepad based on device_name else if (!string_is_empty(device_name)) strlcpy(name_buf, device_name, sizeof(name_buf)); @@ -906,10 +940,10 @@ static void android_input_poll_input(void *data) int id = android_input_get_id(event); int port = android_input_get_id_port(android_data, id, source); - if (port < 0) + if (port < 0 && id != id_3) handle_hotplug(android_data, android_app, &port, id, source); - + switch (type_event) { case AINPUT_EVENT_TYPE_MOTION: @@ -920,7 +954,11 @@ static void android_input_poll_input(void *data) case AINPUT_EVENT_TYPE_KEY: { int keycode = AKeyEvent_getKeyCode(event); - android_input_poll_event_type_key(android_app, + + if (id == id_3 && !predispatched) + android_input_poll_event_type_keyboard(event, keycode, &handled); + else + android_input_poll_event_type_key(android_app, event, port, keycode, source, type_event, &handled); } break; diff --git a/input/drivers_keyboard/keyboard_event_android.h b/input/drivers_keyboard/keyboard_event_android.h index e40bcbf99b..b808262b0f 100644 --- a/input/drivers_keyboard/keyboard_event_android.h +++ b/input/drivers_keyboard/keyboard_event_android.h @@ -16,6 +16,117 @@ #ifndef _KEYBOARD_EVENT_ANDROID_H #define _KEYBOARD_EVENT_ANDROID_H +// The list of defined Android keycodes is incomplete in SDK version 12 and lower. +// If using an SDK lower than 12 then add missing keycodes here +#if __ANDROID_API__ < 13 + +/* + * Key codes. + */ +enum { + AKEYCODE_ESCAPE = 111, + AKEYCODE_FORWARD_DEL = 112, + AKEYCODE_CTRL_LEFT = 113, + AKEYCODE_CTRL_RIGHT = 114, + AKEYCODE_CAPS_LOCK = 115, + AKEYCODE_SCROLL_LOCK = 116, + AKEYCODE_META_LEFT = 117, + AKEYCODE_META_RIGHT = 118, + AKEYCODE_FUNCTION = 119, + AKEYCODE_SYSRQ = 120, + AKEYCODE_BREAK = 121, + AKEYCODE_MOVE_HOME = 122, + AKEYCODE_MOVE_END = 123, + AKEYCODE_INSERT = 124, + AKEYCODE_FORWARD = 125, + AKEYCODE_MEDIA_PLAY = 126, + AKEYCODE_MEDIA_PAUSE = 127, + AKEYCODE_MEDIA_CLOSE = 128, + AKEYCODE_MEDIA_EJECT = 129, + AKEYCODE_MEDIA_RECORD = 130, + AKEYCODE_F1 = 131, + AKEYCODE_F2 = 132, + AKEYCODE_F3 = 133, + AKEYCODE_F4 = 134, + AKEYCODE_F5 = 135, + AKEYCODE_F6 = 136, + AKEYCODE_F7 = 137, + AKEYCODE_F8 = 138, + AKEYCODE_F9 = 139, + AKEYCODE_F10 = 140, + AKEYCODE_F11 = 141, + AKEYCODE_F12 = 142, + AKEYCODE_NUM_LOCK = 143, + AKEYCODE_NUMPAD_0 = 144, + AKEYCODE_NUMPAD_1 = 145, + AKEYCODE_NUMPAD_2 = 146, + AKEYCODE_NUMPAD_3 = 147, + AKEYCODE_NUMPAD_4 = 148, + AKEYCODE_NUMPAD_5 = 149, + AKEYCODE_NUMPAD_6 = 150, + AKEYCODE_NUMPAD_7 = 151, + AKEYCODE_NUMPAD_8 = 152, + AKEYCODE_NUMPAD_9 = 153, + AKEYCODE_NUMPAD_DIVIDE = 154, + AKEYCODE_NUMPAD_MULTIPLY = 155, + AKEYCODE_NUMPAD_SUBTRACT = 156, + AKEYCODE_NUMPAD_ADD = 157, + AKEYCODE_NUMPAD_DOT = 158, + AKEYCODE_NUMPAD_COMMA = 159, + AKEYCODE_NUMPAD_ENTER = 160, + AKEYCODE_NUMPAD_EQUALS = 161, + AKEYCODE_NUMPAD_LEFT_PAREN = 162, + AKEYCODE_NUMPAD_RIGHT_PAREN = 163, + AKEYCODE_VOLUME_MUTE = 164, + AKEYCODE_INFO = 165, + AKEYCODE_CHANNEL_UP = 166, + AKEYCODE_CHANNEL_DOWN = 167, + AKEYCODE_ZOOM_IN = 168, + AKEYCODE_ZOOM_OUT = 169, + AKEYCODE_TV = 170, + AKEYCODE_WINDOW = 171, + AKEYCODE_GUIDE = 172, + AKEYCODE_DVR = 173, + AKEYCODE_BOOKMARK = 174, + AKEYCODE_CAPTIONS = 175, + AKEYCODE_SETTINGS = 176, + AKEYCODE_TV_POWER = 177, + AKEYCODE_TV_INPUT = 178, + AKEYCODE_STB_POWER = 179, + AKEYCODE_STB_INPUT = 180, + AKEYCODE_AVR_POWER = 181, + AKEYCODE_AVR_INPUT = 182, + AKEYCODE_PROG_RED = 183, + AKEYCODE_PROG_GREEN = 184, + AKEYCODE_PROG_YELLOW = 185, + AKEYCODE_PROG_BLUE = 186, + AKEYCODE_APP_SWITCH = 187, + AKEYCODE_BUTTON_1 = 188, + AKEYCODE_BUTTON_2 = 189, + AKEYCODE_BUTTON_3 = 190, + AKEYCODE_BUTTON_4 = 191, + AKEYCODE_BUTTON_5 = 192, + AKEYCODE_BUTTON_6 = 193, + AKEYCODE_BUTTON_7 = 194, + AKEYCODE_BUTTON_8 = 195, + AKEYCODE_BUTTON_9 = 196, + AKEYCODE_BUTTON_10 = 197, + AKEYCODE_BUTTON_11 = 198, + AKEYCODE_BUTTON_12 = 199, + AKEYCODE_BUTTON_13 = 200, + AKEYCODE_BUTTON_14 = 201, + AKEYCODE_BUTTON_15 = 202, + AKEYCODE_BUTTON_16 = 203, +}; + +/* + * Meta key / modifer state. + */ +enum { + AMETA_CTRL_ON = 0x1000, +}; +#endif + #include #include diff --git a/input/input_keymaps.c b/input/input_keymaps.c index 8a0d2e041c..66b83e6667 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -18,6 +18,11 @@ #include #include +#ifdef ANDROID +#include +#include "drivers_keyboard/keyboard_event_android.h" +#endif + #ifdef HAVE_CONFIG_H #include "../config.h" #endif @@ -964,6 +969,119 @@ const struct rarch_key_map rarch_key_map_linux[] = { }; #endif +#ifdef ANDROID +const struct rarch_key_map rarch_key_map_android[] = { + { AKEYCODE_DEL, RETROK_BACKSPACE }, + { AKEYCODE_TAB, RETROK_TAB }, + { AKEYCODE_CLEAR, RETROK_CLEAR }, + { AKEYCODE_ENTER, RETROK_RETURN }, + { AKEYCODE_BREAK, RETROK_PAUSE }, + { AKEYCODE_ESCAPE, RETROK_ESCAPE }, + { AKEYCODE_SPACE, RETROK_SPACE }, + { AKEYCODE_APOSTROPHE, RETROK_QUOTE }, + { AKEYCODE_NUMPAD_LEFT_PAREN, RETROK_LEFTPAREN }, + { AKEYCODE_NUMPAD_RIGHT_PAREN, RETROK_RIGHTPAREN }, + { AKEYCODE_NUMPAD_MULTIPLY, RETROK_ASTERISK }, + { AKEYCODE_NUMPAD_ADD, RETROK_PLUS }, + { AKEYCODE_COMMA, RETROK_COMMA }, + { AKEYCODE_MINUS, RETROK_MINUS }, + { AKEYCODE_PERIOD, RETROK_PERIOD }, + { AKEYCODE_SLASH, RETROK_SLASH }, + { AKEYCODE_0, RETROK_0 }, + { AKEYCODE_1, RETROK_1 }, + { AKEYCODE_2, RETROK_2 }, + { AKEYCODE_3, RETROK_3 }, + { AKEYCODE_4, RETROK_4 }, + { AKEYCODE_5, RETROK_5 }, + { AKEYCODE_6, RETROK_6 }, + { AKEYCODE_7, RETROK_7 }, + { AKEYCODE_8, RETROK_8 }, + { AKEYCODE_9, RETROK_9 }, + { AKEYCODE_SEMICOLON, RETROK_SEMICOLON }, + { AKEYCODE_EQUALS, RETROK_EQUALS }, + { AKEYCODE_LEFT_BRACKET, RETROK_LEFTBRACKET }, + { AKEYCODE_BACKSLASH, RETROK_BACKSLASH }, + { AKEYCODE_RIGHT_BRACKET, RETROK_RIGHTBRACKET }, + { AKEYCODE_GRAVE, RETROK_BACKQUOTE }, + { AKEYCODE_A, RETROK_a }, + { AKEYCODE_B, RETROK_b }, + { AKEYCODE_C, RETROK_c }, + { AKEYCODE_D, RETROK_d }, + { AKEYCODE_E, RETROK_e }, + { AKEYCODE_F, RETROK_f }, + { AKEYCODE_G, RETROK_g }, + { AKEYCODE_H, RETROK_h }, + { AKEYCODE_I, RETROK_i }, + { AKEYCODE_J, RETROK_j }, + { AKEYCODE_K, RETROK_k }, + { AKEYCODE_L, RETROK_l }, + { AKEYCODE_M, RETROK_m }, + { AKEYCODE_N, RETROK_n }, + { AKEYCODE_O, RETROK_o }, + { AKEYCODE_P, RETROK_p }, + { AKEYCODE_Q, RETROK_q }, + { AKEYCODE_R, RETROK_r }, + { AKEYCODE_S, RETROK_s }, + { AKEYCODE_T, RETROK_t }, + { AKEYCODE_U, RETROK_u }, + { AKEYCODE_V, RETROK_v }, + { AKEYCODE_W, RETROK_w }, + { AKEYCODE_X, RETROK_x }, + { AKEYCODE_Y, RETROK_y }, + { AKEYCODE_Z, RETROK_z }, + { AKEYCODE_DEL, RETROK_DELETE }, + { AKEYCODE_NUMPAD_0, RETROK_KP0 }, + { AKEYCODE_NUMPAD_1, RETROK_KP1 }, + { AKEYCODE_NUMPAD_2, RETROK_KP2 }, + { AKEYCODE_NUMPAD_3, RETROK_KP3 }, + { AKEYCODE_NUMPAD_4, RETROK_KP4 }, + { AKEYCODE_NUMPAD_5, RETROK_KP5 }, + { AKEYCODE_NUMPAD_6, RETROK_KP6 }, + { AKEYCODE_NUMPAD_7, RETROK_KP7 }, + { AKEYCODE_NUMPAD_8, RETROK_KP8 }, + { AKEYCODE_NUMPAD_9, RETROK_KP9 }, + { AKEYCODE_NUMPAD_DOT, RETROK_KP_PERIOD }, + { AKEYCODE_NUMPAD_DIVIDE, RETROK_KP_DIVIDE }, + { AKEYCODE_NUMPAD_MULTIPLY, RETROK_KP_MULTIPLY }, + { AKEYCODE_NUMPAD_SUBTRACT, RETROK_KP_MINUS }, + { AKEYCODE_NUMPAD_ADD, RETROK_KP_PLUS }, + { AKEYCODE_NUMPAD_ENTER, RETROK_KP_ENTER }, + { AKEYCODE_NUMPAD_EQUALS, RETROK_KP_EQUALS }, + { AKEYCODE_DPAD_UP, RETROK_UP }, + { AKEYCODE_DPAD_DOWN, RETROK_DOWN }, + { AKEYCODE_DPAD_RIGHT, RETROK_RIGHT }, + { AKEYCODE_DPAD_LEFT, RETROK_LEFT }, + { AKEYCODE_INSERT, RETROK_INSERT }, + { AKEYCODE_MOVE_HOME, RETROK_HOME }, + { AKEYCODE_MOVE_END, RETROK_END }, + { AKEYCODE_PAGE_UP, RETROK_PAGEUP }, + { AKEYCODE_PAGE_DOWN, RETROK_PAGEDOWN }, + { AKEYCODE_F1, RETROK_F1 }, + { AKEYCODE_F2, RETROK_F2 }, + { AKEYCODE_F3, RETROK_F3 }, + { AKEYCODE_F4, RETROK_F4 }, + { AKEYCODE_F5, RETROK_F5 }, + { AKEYCODE_F6, RETROK_F6 }, + { AKEYCODE_F7, RETROK_F7 }, + { AKEYCODE_F8, RETROK_F8 }, + { AKEYCODE_F9, RETROK_F9 }, + { AKEYCODE_F10, RETROK_F10 }, + { AKEYCODE_F11, RETROK_F11 }, + { AKEYCODE_F12, RETROK_F12 }, + { AKEYCODE_NUM_LOCK, RETROK_NUMLOCK }, + { AKEYCODE_CAPS_LOCK, RETROK_CAPSLOCK }, + { AKEYCODE_SCROLL_LOCK, RETROK_SCROLLOCK }, + { AKEYCODE_SHIFT_LEFT, RETROK_RSHIFT }, + { AKEYCODE_SHIFT_RIGHT, RETROK_LSHIFT }, + { AKEYCODE_CTRL_RIGHT, RETROK_RCTRL }, + { AKEYCODE_CTRL_LEFT, RETROK_LCTRL }, + { AKEYCODE_ALT_RIGHT, RETROK_RALT }, + { AKEYCODE_ALT_LEFT, RETROK_LALT }, + { 0, RETROK_UNKNOWN }, +}; +#endif + + #ifdef __APPLE__ const struct rarch_key_map rarch_key_map_apple_hid[] = { { KEY_Delete, RETROK_BACKSPACE }, diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 47d6f62a7a..967f444bde 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -56,6 +56,7 @@ extern const struct rarch_key_map rarch_key_map_dinput[]; extern const struct rarch_key_map rarch_key_map_rwebinput[]; extern const struct rarch_key_map rarch_key_map_linux[]; extern const struct rarch_key_map rarch_key_map_apple_hid[]; +extern const struct rarch_key_map rarch_key_map_android[]; /** * input_keymaps_init_keyboard_lut: