From 8f9fc8f7fe4ccf37cc1170ef6189f6445eae17fd Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 21 Apr 2020 15:47:04 +0800 Subject: [PATCH] Handle all input events in java --- .../src/main/java/SuperTuxKartActivity.java | 156 +++- .../source/Irrlicht/CIrrDeviceAndroid.cpp | 846 +++++++----------- .../source/Irrlicht/CIrrDeviceAndroid.h | 18 - .../Irrlicht/stk_android_native_app_glue.c | 4 + src/guiengine/widgets/CGUIEditBox.cpp | 35 - src/guiengine/widgets/CGUIEditBox.hpp | 4 - 6 files changed, 467 insertions(+), 596 deletions(-) diff --git a/android/src/main/java/SuperTuxKartActivity.java b/android/src/main/java/SuperTuxKartActivity.java index 07c688391..6bf6c6ef7 100644 --- a/android/src/main/java/SuperTuxKartActivity.java +++ b/android/src/main/java/SuperTuxKartActivity.java @@ -34,6 +34,29 @@ import org.minidns.record.TXT; public class SuperTuxKartActivity extends NativeActivity { + // Same as irrlicht + enum TouchInputEvent + { + ETIE_PRESSED_DOWN, + ETIE_LEFT_UP, + ETIE_MOVED, + ETIE_COUNT + } + + class TouchEventData + { + public TouchInputEvent event_type; + public int x; + public int y; + TouchEventData() + { + event_type = TouchInputEvent.ETIE_PRESSED_DOWN; + x = 0; + y = 0; + } + }; + + private TouchEventData[] m_touch_event_data; private STKEditText m_stk_edittext; private static Context m_context; private static HIDDeviceManager m_hid_device_manager; @@ -43,6 +66,11 @@ public class SuperTuxKartActivity extends NativeActivity // ------------------------------------------------------------------------ private native void startSTK(); // ------------------------------------------------------------------------ + private native static void addKey(int key_code, int action, int meta_state, + int scan_code, int unichar); + // ------------------------------------------------------------------------ + private native static void addTouch(int id, int x, int y, int event_type); + // ------------------------------------------------------------------------ private void hideKeyboardNative(final boolean clear_text) { if (m_stk_edittext == null) @@ -103,7 +131,12 @@ public class SuperTuxKartActivity extends NativeActivity public void onCreate(Bundle instance) { super.onCreate(instance); + // We don't use native activity input event queue + getWindow().takeInputQueue(null); System.loadLibrary("main"); + m_touch_event_data = new TouchEventData[32]; + for (int i = 0; i < 32; i++) + m_touch_event_data[i] = new TouchEventData(); m_context = this; m_stk_edittext = null; @@ -182,6 +215,8 @@ public class SuperTuxKartActivity extends NativeActivity @Override public boolean dispatchKeyEvent(KeyEvent event) { + int key_code = event.getKeyCode(); + int action = event.getAction(); int device_id = event.getDeviceId(); int source = event.getSource(); @@ -195,24 +230,71 @@ public class SuperTuxKartActivity extends NativeActivity if (SDLControllerManager.isDeviceSDLJoystick(device_id)) { // Note that we process events with specific key codes here - if (event.getAction() == KeyEvent.ACTION_DOWN) + if (action == KeyEvent.ACTION_DOWN) { - if (SDLControllerManager.onNativePadDown(device_id, event.getKeyCode()) == 0) + if (SDLControllerManager.onNativePadDown(device_id, key_code) == 0) return true; } - else if (event.getAction() == KeyEvent.ACTION_UP) + else if (action == KeyEvent.ACTION_UP) { - if (SDLControllerManager.onNativePadUp(device_id, event.getKeyCode()) == 0) + if (SDLControllerManager.onNativePadUp(device_id, key_code) == 0) return true; } } + int repeat_count = event.getRepeatCount(); + int meta_state = event.getMetaState(); + int scan_code = event.getScanCode(); + // User pressed back button + if (key_code == KeyEvent.KEYCODE_BACK && + action == KeyEvent.ACTION_DOWN) + { + // Avoid repeating the event which leads to some strange behaviour + // For ACTION_UP it's always zero + if (repeat_count == 0) + addKey(key_code, action, meta_state, scan_code, 0); + return true; + } + + boolean has_hardware_keyboard = isHardwareKeyboardConnected(); + // Allow hacker keyboard (one of the native android keyboard) + // to close itself when pressing the esc button + if (key_code == KeyEvent.KEYCODE_ESCAPE && + action == KeyEvent.ACTION_DOWN && !has_hardware_keyboard && + m_stk_edittext != null && m_stk_edittext.isFocused()) + { + hideKeyboardNative(/*clear_text*/false); + return true; + } + // Called when user change cursor / select all text in native android // keyboard boolean ret = super.dispatchKeyEvent(event); - if (!isHardwareKeyboardConnected() && m_stk_edittext != null) + if (!has_hardware_keyboard && m_stk_edittext != null) m_stk_edittext.updateSTKEditBox(); - return ret; + + // Allow sending navigation key event found in native android keyboard + // so user can using up or down to toggle multiple textfield + boolean send_navigation = key_code == KeyEvent.KEYCODE_DPAD_UP || + key_code == KeyEvent.KEYCODE_DPAD_DOWN || + key_code == KeyEvent.KEYCODE_DPAD_LEFT || + key_code == KeyEvent.KEYCODE_DPAD_RIGHT; + // We don't send navigation event if it's consumed by input method + send_navigation = send_navigation && !ret; + + if (has_hardware_keyboard || send_navigation) + { + if (has_hardware_keyboard && + m_stk_edittext != null && m_stk_edittext.isFocused()) + m_stk_edittext.beforeHideKeyboard(/*clear_text*/true); + // KeyCharacterMap.COMBINING_ACCENT is not handled at the moment + int unichar = event.getUnicodeChar(meta_state); + addKey(key_code, action, meta_state, scan_code, unichar); + // We use only java to handle key for hardware keyboard + return true; + } + else + return ret; } // ------------------------------------------------------------------------ @Override @@ -223,6 +305,68 @@ public class SuperTuxKartActivity extends NativeActivity return super.dispatchGenericMotionEvent(ev); } // ------------------------------------------------------------------------ + @Override + public boolean dispatchTouchEvent(MotionEvent ev) + { + boolean ret = super.dispatchTouchEvent(ev); + if (!ret) + { + TouchInputEvent event_type; + int action = ev.getAction(); + switch (action & MotionEvent.ACTION_MASK) + { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_POINTER_DOWN: + event_type = TouchInputEvent.ETIE_PRESSED_DOWN; + break; + case MotionEvent.ACTION_MOVE: + event_type = TouchInputEvent.ETIE_MOVED; + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_CANCEL: + event_type = TouchInputEvent.ETIE_LEFT_UP; + break; + default: + return false; + } + + int count = 1; + int idx = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> + MotionEvent.ACTION_POINTER_INDEX_SHIFT; + + // Process all touches for move action. + if (event_type == TouchInputEvent.ETIE_MOVED) + { + count = ev.getPointerCount(); + idx = 0; + } + + for (int i = 0; i < count; i++) + { + int id = ev.getPointerId(i + idx); + int x = (int)ev.getX(i + idx); + int y = (int)ev.getY(i + idx); + + if (id >= 32) + continue; + + // Don't send move event when nothing changed + if (m_touch_event_data[id].event_type == event_type && + m_touch_event_data[id].x == x && + m_touch_event_data[id].y == y) + continue; + + m_touch_event_data[id].event_type = event_type; + m_touch_event_data[id].x = x; + m_touch_event_data[id].y = y; + addTouch(id, x, y, event_type.ordinal()); + } + return true; + } + return false; + } + // ------------------------------------------------------------------------ public void showKeyboard(final int type) { final Context context = this; diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp index 8f9d95756..009810797 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include "os.h" #include "CContextEGL.h" @@ -23,6 +24,9 @@ // Call when android keyboard is opened or close, and save its height for // moving screen std::atomic g_keyboard_height(0); +std::mutex g_event_mutex; +std::vector g_events; +std::map g_keymap; #define MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_saveKeyboardHeight(JNIEnv* env, jobject this_obj, jint height) #define ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME) MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME) @@ -33,6 +37,63 @@ ANDROID_SAVE_KBD_HEIGHT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME) g_keyboard_height.store((int)height); } +#define ADD_TOUCH_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_addTouch(JNIEnv* env, jobject this_obj, jint id, jint X, jint Y, jint event_type) +#define ANDROID_ADD_TOUCH_CALLBACK(PKG_NAME) ADD_TOUCH_CALLBACK(PKG_NAME) +extern "C" +ANDROID_ADD_TOUCH_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME) +{ + irr::SEvent event; + event.EventType = irr::EET_TOUCH_INPUT_EVENT; + event.TouchInput.ID = id; + event.TouchInput.X = X; + event.TouchInput.Y = Y; + event.TouchInput.Event = (irr::ETOUCH_INPUT_EVENT)event_type; + std::lock_guard lock(g_event_mutex); + g_events.push_back(event); +} + +#define ADD_KEY_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_addKey(JNIEnv* env, jobject this_obj, jint key_code, jint action, jint meta_state, jint scan_code, jint unichar) +#define ANDROID_ADD_KEY_CALLBACK(PKG_NAME) ADD_KEY_CALLBACK(PKG_NAME) + +extern "C" +ANDROID_ADD_KEY_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME) +{ + irr::SEvent event; + event.EventType = irr::EET_KEY_INPUT_EVENT; + event.KeyInput.Char = unichar; + event.KeyInput.PressedDown = false; + event.KeyInput.Key = irr::IRR_KEY_UNKNOWN; + + if (action == AKEY_EVENT_ACTION_DOWN) + { + event.KeyInput.PressedDown = true; + } + else if (action == AKEY_EVENT_ACTION_UP) + { + event.KeyInput.PressedDown = false; + } + + event.KeyInput.Shift = (meta_state & AMETA_SHIFT_ON || + meta_state & AMETA_SHIFT_LEFT_ON || + meta_state & AMETA_SHIFT_RIGHT_ON); + + event.KeyInput.Control = (meta_state & AMETA_CTRL_ON || + meta_state & AMETA_CTRL_LEFT_ON || + meta_state & AMETA_CTRL_RIGHT_ON); + + event.KeyInput.SystemKeyCode = key_code; + event.KeyInput.Key = g_keymap[key_code]; + + // If button doesn't return key code, then at least use device-specific + // scan code, because it's better than nothing + if (event.KeyInput.Key == 0) + event.KeyInput.Key = (irr::EKEY_CODE)((int)irr::IRR_KEY_CODES_COUNT + scan_code); + + std::lock_guard lock(g_event_mutex); + g_events.push_back(event); +} + + namespace irr { namespace video @@ -73,7 +134,6 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param) Gyroscope(0), AccelerometerActive(false), GyroscopeActive(false), - TextInputEnabled(false), HasTouchDevice(false), GamepadAxisX(0), GamepadAxisY(0), @@ -87,8 +147,6 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param) m_moved_height_func = NULL; m_jni_env = NULL; - createKeyMap(); - CursorControl = new gui::MobileCursorControl(); Android = (android_app*)(param.PrivateData); @@ -105,7 +163,7 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param) Android->userData = this; Android->onAppCmd = handleAndroidCommand; Android->onAppCmdDirect = NULL; - Android->onInputEvent = handleInput; + Android->onInputEvent = NULL; printConfig(); @@ -276,6 +334,32 @@ bool CIrrDeviceAndroid::run() { if (m_moved_height_func != NULL) m_moved_height = m_moved_height_func(this); + + // Input events + std::vector events; + std::unique_lock ul(g_event_mutex); + std::swap(events, g_events); + ul.unlock(); + for (auto& e : events) + { + bool simulate_mouse = false; + core::position2d mouse_pos; + if (e.EventType == EET_TOUCH_INPUT_EVENT) + { + if (e.TouchInput.ID == 0) + { + simulate_mouse = true; + mouse_pos.X = e.TouchInput.X; + mouse_pos.Y = e.TouchInput.Y; + } + } + postEventFromUser(e); + // Simulate mouse event for first finger on multitouch device. + // This allows to click on GUI elements. + if (simulate_mouse) + simulateMouse(e, mouse_pos); + } + s32 Events = 0; android_poll_source* Source = 0; bool should_run = (IsStarted && IsFocused && !IsPaused); @@ -511,544 +595,240 @@ void CIrrDeviceAndroid::handleAndroidCommand(android_app* app, int32_t cmd) device->postEventFromUser(event); } -s32 CIrrDeviceAndroid::handleInput(android_app* app, AInputEvent* androidEvent) -{ - CIrrDeviceAndroid* device = (CIrrDeviceAndroid*)app->userData; - assert(device != NULL); - - // SDL will handle it - int32_t source = AInputEvent_getSource(androidEvent); - if (source == AINPUT_SOURCE_GAMEPAD || - source == AINPUT_SOURCE_JOYSTICK || - source == AINPUT_SOURCE_DPAD) - return 0; - - s32 status = 0; - int32_t type = AInputEvent_getType(androidEvent); - - switch (type) - { - case AINPUT_EVENT_TYPE_MOTION: - { - status = device->handleTouch(androidEvent); - break; - } - case AINPUT_EVENT_TYPE_KEY: - { - status = device->handleKeyboard(androidEvent); - break; - } - default: - break; - } - - return status; -} - -s32 CIrrDeviceAndroid::handleTouch(AInputEvent* androidEvent) -{ - s32 status = 0; - - SEvent event; - event.EventType = EET_TOUCH_INPUT_EVENT; - - s32 eventAction = AMotionEvent_getAction(androidEvent); - -#if 0 - // Useful for debugging. We might have to pass some of those infos on at some point. - // but preferably device independent (so iphone can use same irrlicht flags). - int32_t flags = AMotionEvent_getFlags(androidEvent); - os::Printer::log("flags: ", core::stringc(flags).c_str(), ELL_DEBUG); - int32_t metaState = AMotionEvent_getMetaState(androidEvent); - os::Printer::log("metaState: ", core::stringc(metaState).c_str(), ELL_DEBUG); - int32_t edgeFlags = AMotionEvent_getEdgeFlags(androidEvent); - os::Printer::log("edgeFlags: ", core::stringc(flags).c_str(), ELL_DEBUG); -#endif - - bool touchReceived = true; - bool simulate_mouse = false; - int adjusted_height = getMovedHeight(); - core::position2d mouse_pos = core::position2d(0, 0); - - switch (eventAction & AMOTION_EVENT_ACTION_MASK) - { - case AMOTION_EVENT_ACTION_DOWN: - case AMOTION_EVENT_ACTION_POINTER_DOWN: - event.TouchInput.Event = ETIE_PRESSED_DOWN; - break; - case AMOTION_EVENT_ACTION_MOVE: - event.TouchInput.Event = ETIE_MOVED; - break; - case AMOTION_EVENT_ACTION_UP: - case AMOTION_EVENT_ACTION_POINTER_UP: - case AMOTION_EVENT_ACTION_CANCEL: - event.TouchInput.Event = ETIE_LEFT_UP; - break; - default: - touchReceived = false; - break; - } - - if (touchReceived) - { - s32 count = 1; - s32 idx = (eventAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> - AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; - - // Process all touches for move action. - if (event.TouchInput.Event == ETIE_MOVED) - { - count = AMotionEvent_getPointerCount(androidEvent); - idx = 0; - } - - for (s32 i = 0; i < count; ++i) - { - event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i + idx); - event.TouchInput.X = AMotionEvent_getX(androidEvent, i + idx); - event.TouchInput.Y = AMotionEvent_getY(androidEvent, i + idx); - - if (event.TouchInput.ID >= 32) - continue; - - TouchEventData& event_data = TouchEventsData[event.TouchInput.ID]; - - // Don't send move event when nothing changed - if (event_data.event == event.TouchInput.Event && - event_data.x == event.TouchInput.X && - event_data.y == event.TouchInput.Y) - continue; - - event_data.event = event.TouchInput.Event; - event_data.x = event.TouchInput.X; - event_data.y = event.TouchInput.Y + adjusted_height; - - postEventFromUser(event); - - if (event.TouchInput.ID == 0) - { - simulate_mouse = true; - mouse_pos.X = event.TouchInput.X; - mouse_pos.Y = event.TouchInput.Y; - } - } - - status = 1; - } - - // Simulate mouse event for first finger on multitouch device. - // This allows to click on GUI elements. - if (simulate_mouse) - simulateMouse(event, mouse_pos); - - return status; -} - - -s32 CIrrDeviceAndroid::handleKeyboard(AInputEvent* androidEvent) -{ - s32 status = 0; - - bool ignore_event = false; - - SEvent event; - event.EventType = EET_KEY_INPUT_EVENT; - event.KeyInput.Char = 0; - event.KeyInput.PressedDown = false; - event.KeyInput.Key = IRR_KEY_UNKNOWN; - - int32_t keyCode = AKeyEvent_getKeyCode(androidEvent); - int32_t keyAction = AKeyEvent_getAction(androidEvent); - int32_t keyMetaState = AKeyEvent_getMetaState(androidEvent); - int32_t keyRepeat = AKeyEvent_getRepeatCount(androidEvent); - int32_t scanCode = AKeyEvent_getScanCode(androidEvent); - - if (keyAction == AKEY_EVENT_ACTION_DOWN) - { - event.KeyInput.PressedDown = true; - } - else if (keyAction == AKEY_EVENT_ACTION_UP) - { - event.KeyInput.PressedDown = false; - } - - event.KeyInput.Shift = (keyMetaState & AMETA_SHIFT_ON || - keyMetaState & AMETA_SHIFT_LEFT_ON || - keyMetaState & AMETA_SHIFT_RIGHT_ON); - - event.KeyInput.Control = (keyMetaState & AMETA_CTRL_ON || - keyMetaState & AMETA_CTRL_LEFT_ON || - keyMetaState & AMETA_CTRL_RIGHT_ON); - - event.KeyInput.SystemKeyCode = (u32)keyCode; - event.KeyInput.Key = KeyMap[keyCode]; - - if (event.KeyInput.Key > 0) - { - if (TextInputEnabled == true) - { - event.KeyInput.Char = getUnicodeChar(androidEvent); - } - - if (event.KeyInput.Char == 0) - { - event.KeyInput.Char = getKeyChar(event); - } - } - - // If button doesn't return key code, then at least use device-specific - // scan code, because it's better than nothing - if (event.KeyInput.Key == 0) - { - event.KeyInput.Key = (EKEY_CODE)((int)IRR_KEY_CODES_COUNT + scanCode); - } - - // Handle an event when back button in pressed just like an escape key - // and also avoid repeating the event to avoid some strange behaviour - if (event.KeyInput.SystemKeyCode == AKEYCODE_BACK && - (event.KeyInput.PressedDown == false || keyRepeat > 0)) - { - ignore_event = true; - } - - // Mark escape key and gamepad buttons as handled by application to avoid - // receiving duplicated events - if (event.KeyInput.SystemKeyCode == AKEYCODE_ESCAPE || - event.KeyInput.SystemKeyCode == AKEYCODE_BACK || - (event.KeyInput.SystemKeyCode >= AKEYCODE_BUTTON_A && - event.KeyInput.SystemKeyCode <= AKEYCODE_BUTTON_MODE)) - { - status = 1; - } - - if (!ignore_event) - { - postEventFromUser(event); - } - - return status; -} - video::SExposedVideoData& CIrrDeviceAndroid::getExposedVideoData() { return ExposedVideoData; } -void CIrrDeviceAndroid::createKeyMap() +// Create the keymap in startSTK +extern "C" void createKeyMap() { - KeyMap[AKEYCODE_UNKNOWN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_SOFT_LEFT] = IRR_KEY_LBUTTON; - KeyMap[AKEYCODE_SOFT_RIGHT] = IRR_KEY_RBUTTON; - KeyMap[AKEYCODE_HOME] = IRR_KEY_HOME; - KeyMap[AKEYCODE_BACK] = IRR_KEY_ESCAPE; - KeyMap[AKEYCODE_CALL] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_ENDCALL] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_0] = IRR_KEY_0; - KeyMap[AKEYCODE_1] = IRR_KEY_1; - KeyMap[AKEYCODE_2] = IRR_KEY_2; - KeyMap[AKEYCODE_3] = IRR_KEY_3; - KeyMap[AKEYCODE_4] = IRR_KEY_4; - KeyMap[AKEYCODE_5] = IRR_KEY_5; - KeyMap[AKEYCODE_6] = IRR_KEY_6; - KeyMap[AKEYCODE_7] = IRR_KEY_7; - KeyMap[AKEYCODE_8] = IRR_KEY_8; - KeyMap[AKEYCODE_9] = IRR_KEY_9; - KeyMap[AKEYCODE_STAR] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_POUND] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_DPAD_UP] = IRR_KEY_UP; - KeyMap[AKEYCODE_DPAD_DOWN] = IRR_KEY_DOWN; - KeyMap[AKEYCODE_DPAD_LEFT] = IRR_KEY_LEFT; - KeyMap[AKEYCODE_DPAD_RIGHT] = IRR_KEY_RIGHT; - KeyMap[AKEYCODE_DPAD_CENTER] = IRR_KEY_RETURN; - KeyMap[AKEYCODE_VOLUME_UP] = IRR_KEY_VOLUME_DOWN; - KeyMap[AKEYCODE_VOLUME_DOWN] = IRR_KEY_VOLUME_UP; - KeyMap[AKEYCODE_POWER] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CAMERA] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CLEAR] = IRR_KEY_CLEAR; - KeyMap[AKEYCODE_A] = IRR_KEY_A; - KeyMap[AKEYCODE_B] = IRR_KEY_B; - KeyMap[AKEYCODE_C] = IRR_KEY_C; - KeyMap[AKEYCODE_D] = IRR_KEY_D; - KeyMap[AKEYCODE_E] = IRR_KEY_E; - KeyMap[AKEYCODE_F] = IRR_KEY_F; - KeyMap[AKEYCODE_G] = IRR_KEY_G; - KeyMap[AKEYCODE_H] = IRR_KEY_H; - KeyMap[AKEYCODE_I] = IRR_KEY_I; - KeyMap[AKEYCODE_J] = IRR_KEY_J; - KeyMap[AKEYCODE_K] = IRR_KEY_K; - KeyMap[AKEYCODE_L] = IRR_KEY_L; - KeyMap[AKEYCODE_M] = IRR_KEY_M; - KeyMap[AKEYCODE_N] = IRR_KEY_N; - KeyMap[AKEYCODE_O] = IRR_KEY_O; - KeyMap[AKEYCODE_P] = IRR_KEY_P; - KeyMap[AKEYCODE_Q] = IRR_KEY_Q; - KeyMap[AKEYCODE_R] = IRR_KEY_R; - KeyMap[AKEYCODE_S] = IRR_KEY_S; - KeyMap[AKEYCODE_T] = IRR_KEY_T; - KeyMap[AKEYCODE_U] = IRR_KEY_U; - KeyMap[AKEYCODE_V] = IRR_KEY_V; - KeyMap[AKEYCODE_W] = IRR_KEY_W; - KeyMap[AKEYCODE_X] = IRR_KEY_X; - KeyMap[AKEYCODE_Y] = IRR_KEY_Y; - KeyMap[AKEYCODE_Z] = IRR_KEY_Z; - KeyMap[AKEYCODE_COMMA] = IRR_KEY_COMMA; - KeyMap[AKEYCODE_PERIOD] = IRR_KEY_PERIOD; - KeyMap[AKEYCODE_ALT_LEFT] = IRR_KEY_MENU; - KeyMap[AKEYCODE_ALT_RIGHT] = IRR_KEY_MENU; - KeyMap[AKEYCODE_SHIFT_LEFT] = IRR_KEY_LSHIFT; - KeyMap[AKEYCODE_SHIFT_RIGHT] = IRR_KEY_RSHIFT; - KeyMap[AKEYCODE_TAB] = IRR_KEY_TAB; - KeyMap[AKEYCODE_SPACE] = IRR_KEY_SPACE; - KeyMap[AKEYCODE_SYM] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_EXPLORER] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_ENVELOPE] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_ENTER] = IRR_KEY_RETURN; - KeyMap[AKEYCODE_DEL] = IRR_KEY_BACK; - KeyMap[AKEYCODE_GRAVE] = IRR_KEY_OEM_3; - KeyMap[AKEYCODE_MINUS] = IRR_KEY_MINUS; - KeyMap[AKEYCODE_EQUALS] = IRR_KEY_PLUS; - KeyMap[AKEYCODE_LEFT_BRACKET] = IRR_KEY_OEM_4; - KeyMap[AKEYCODE_RIGHT_BRACKET] = IRR_KEY_OEM_6; - KeyMap[AKEYCODE_BACKSLASH] = IRR_KEY_OEM_5; - KeyMap[AKEYCODE_SEMICOLON] = IRR_KEY_OEM_1; - KeyMap[AKEYCODE_APOSTROPHE] = IRR_KEY_OEM_7; - KeyMap[AKEYCODE_SLASH] = IRR_KEY_OEM_2; - KeyMap[AKEYCODE_AT] = IRR_KEY_2; - KeyMap[AKEYCODE_NUM] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_HEADSETHOOK] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_FOCUS] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_PLUS] = IRR_KEY_PLUS; - KeyMap[AKEYCODE_MENU] = IRR_KEY_MENU; - KeyMap[AKEYCODE_NOTIFICATION] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_SEARCH] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MEDIA_PLAY_PAUSE] = IRR_KEY_MEDIA_PLAY_PAUSE; - KeyMap[AKEYCODE_MEDIA_STOP] = IRR_KEY_MEDIA_STOP; - KeyMap[AKEYCODE_MEDIA_NEXT] = IRR_KEY_MEDIA_NEXT_TRACK; - KeyMap[AKEYCODE_MEDIA_PREVIOUS] = IRR_KEY_MEDIA_PREV_TRACK; - KeyMap[AKEYCODE_MEDIA_REWIND] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MEDIA_FAST_FORWARD] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MUTE] = IRR_KEY_VOLUME_MUTE; - KeyMap[AKEYCODE_PAGE_UP] = IRR_KEY_PRIOR; - KeyMap[AKEYCODE_PAGE_DOWN] = IRR_KEY_NEXT; - KeyMap[AKEYCODE_PICTSYMBOLS] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_SWITCH_CHARSET] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_UNKNOWN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_SOFT_LEFT] = IRR_KEY_LBUTTON; + g_keymap[AKEYCODE_SOFT_RIGHT] = IRR_KEY_RBUTTON; + g_keymap[AKEYCODE_HOME] = IRR_KEY_HOME; + g_keymap[AKEYCODE_BACK] = IRR_KEY_ESCAPE; + g_keymap[AKEYCODE_CALL] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_ENDCALL] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_0] = IRR_KEY_0; + g_keymap[AKEYCODE_1] = IRR_KEY_1; + g_keymap[AKEYCODE_2] = IRR_KEY_2; + g_keymap[AKEYCODE_3] = IRR_KEY_3; + g_keymap[AKEYCODE_4] = IRR_KEY_4; + g_keymap[AKEYCODE_5] = IRR_KEY_5; + g_keymap[AKEYCODE_6] = IRR_KEY_6; + g_keymap[AKEYCODE_7] = IRR_KEY_7; + g_keymap[AKEYCODE_8] = IRR_KEY_8; + g_keymap[AKEYCODE_9] = IRR_KEY_9; + g_keymap[AKEYCODE_STAR] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_POUND] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_DPAD_UP] = IRR_KEY_UP; + g_keymap[AKEYCODE_DPAD_DOWN] = IRR_KEY_DOWN; + g_keymap[AKEYCODE_DPAD_LEFT] = IRR_KEY_LEFT; + g_keymap[AKEYCODE_DPAD_RIGHT] = IRR_KEY_RIGHT; + g_keymap[AKEYCODE_DPAD_CENTER] = IRR_KEY_RETURN; + g_keymap[AKEYCODE_VOLUME_UP] = IRR_KEY_VOLUME_DOWN; + g_keymap[AKEYCODE_VOLUME_DOWN] = IRR_KEY_VOLUME_UP; + g_keymap[AKEYCODE_POWER] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CAMERA] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CLEAR] = IRR_KEY_CLEAR; + g_keymap[AKEYCODE_A] = IRR_KEY_A; + g_keymap[AKEYCODE_B] = IRR_KEY_B; + g_keymap[AKEYCODE_C] = IRR_KEY_C; + g_keymap[AKEYCODE_D] = IRR_KEY_D; + g_keymap[AKEYCODE_E] = IRR_KEY_E; + g_keymap[AKEYCODE_F] = IRR_KEY_F; + g_keymap[AKEYCODE_G] = IRR_KEY_G; + g_keymap[AKEYCODE_H] = IRR_KEY_H; + g_keymap[AKEYCODE_I] = IRR_KEY_I; + g_keymap[AKEYCODE_J] = IRR_KEY_J; + g_keymap[AKEYCODE_K] = IRR_KEY_K; + g_keymap[AKEYCODE_L] = IRR_KEY_L; + g_keymap[AKEYCODE_M] = IRR_KEY_M; + g_keymap[AKEYCODE_N] = IRR_KEY_N; + g_keymap[AKEYCODE_O] = IRR_KEY_O; + g_keymap[AKEYCODE_P] = IRR_KEY_P; + g_keymap[AKEYCODE_Q] = IRR_KEY_Q; + g_keymap[AKEYCODE_R] = IRR_KEY_R; + g_keymap[AKEYCODE_S] = IRR_KEY_S; + g_keymap[AKEYCODE_T] = IRR_KEY_T; + g_keymap[AKEYCODE_U] = IRR_KEY_U; + g_keymap[AKEYCODE_V] = IRR_KEY_V; + g_keymap[AKEYCODE_W] = IRR_KEY_W; + g_keymap[AKEYCODE_X] = IRR_KEY_X; + g_keymap[AKEYCODE_Y] = IRR_KEY_Y; + g_keymap[AKEYCODE_Z] = IRR_KEY_Z; + g_keymap[AKEYCODE_COMMA] = IRR_KEY_COMMA; + g_keymap[AKEYCODE_PERIOD] = IRR_KEY_PERIOD; + g_keymap[AKEYCODE_ALT_LEFT] = IRR_KEY_MENU; + g_keymap[AKEYCODE_ALT_RIGHT] = IRR_KEY_MENU; + g_keymap[AKEYCODE_SHIFT_LEFT] = IRR_KEY_LSHIFT; + g_keymap[AKEYCODE_SHIFT_RIGHT] = IRR_KEY_RSHIFT; + g_keymap[AKEYCODE_TAB] = IRR_KEY_TAB; + g_keymap[AKEYCODE_SPACE] = IRR_KEY_SPACE; + g_keymap[AKEYCODE_SYM] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_EXPLORER] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_ENVELOPE] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_ENTER] = IRR_KEY_RETURN; + g_keymap[AKEYCODE_DEL] = IRR_KEY_BACK; + g_keymap[AKEYCODE_GRAVE] = IRR_KEY_OEM_3; + g_keymap[AKEYCODE_MINUS] = IRR_KEY_MINUS; + g_keymap[AKEYCODE_EQUALS] = IRR_KEY_PLUS; + g_keymap[AKEYCODE_LEFT_BRACKET] = IRR_KEY_OEM_4; + g_keymap[AKEYCODE_RIGHT_BRACKET] = IRR_KEY_OEM_6; + g_keymap[AKEYCODE_BACKSLASH] = IRR_KEY_OEM_5; + g_keymap[AKEYCODE_SEMICOLON] = IRR_KEY_OEM_1; + g_keymap[AKEYCODE_APOSTROPHE] = IRR_KEY_OEM_7; + g_keymap[AKEYCODE_SLASH] = IRR_KEY_OEM_2; + g_keymap[AKEYCODE_AT] = IRR_KEY_2; + g_keymap[AKEYCODE_NUM] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_HEADSETHOOK] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_FOCUS] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_PLUS] = IRR_KEY_PLUS; + g_keymap[AKEYCODE_MENU] = IRR_KEY_MENU; + g_keymap[AKEYCODE_NOTIFICATION] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_SEARCH] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MEDIA_PLAY_PAUSE] = IRR_KEY_MEDIA_PLAY_PAUSE; + g_keymap[AKEYCODE_MEDIA_STOP] = IRR_KEY_MEDIA_STOP; + g_keymap[AKEYCODE_MEDIA_NEXT] = IRR_KEY_MEDIA_NEXT_TRACK; + g_keymap[AKEYCODE_MEDIA_PREVIOUS] = IRR_KEY_MEDIA_PREV_TRACK; + g_keymap[AKEYCODE_MEDIA_REWIND] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MEDIA_FAST_FORWARD] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MUTE] = IRR_KEY_VOLUME_MUTE; + g_keymap[AKEYCODE_PAGE_UP] = IRR_KEY_PRIOR; + g_keymap[AKEYCODE_PAGE_DOWN] = IRR_KEY_NEXT; + g_keymap[AKEYCODE_PICTSYMBOLS] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_SWITCH_CHARSET] = IRR_KEY_UNKNOWN; // following look like controller inputs - KeyMap[AKEYCODE_BUTTON_A] = IRR_KEY_BUTTON_A; - KeyMap[AKEYCODE_BUTTON_B] = IRR_KEY_BUTTON_B; - KeyMap[AKEYCODE_BUTTON_C] = IRR_KEY_BUTTON_C; - KeyMap[AKEYCODE_BUTTON_X] = IRR_KEY_BUTTON_X; - KeyMap[AKEYCODE_BUTTON_Y] = IRR_KEY_BUTTON_Y; - KeyMap[AKEYCODE_BUTTON_Z] = IRR_KEY_BUTTON_Z; - KeyMap[AKEYCODE_BUTTON_L1] = IRR_KEY_BUTTON_L1; - KeyMap[AKEYCODE_BUTTON_R1] = IRR_KEY_BUTTON_R1; - KeyMap[AKEYCODE_BUTTON_L2] = IRR_KEY_BUTTON_L2; - KeyMap[AKEYCODE_BUTTON_R2] = IRR_KEY_BUTTON_R2; - KeyMap[AKEYCODE_BUTTON_THUMBL] = IRR_KEY_BUTTON_THUMBL; - KeyMap[AKEYCODE_BUTTON_THUMBR] = IRR_KEY_BUTTON_THUMBR; - KeyMap[AKEYCODE_BUTTON_START] = IRR_KEY_BUTTON_START; - KeyMap[AKEYCODE_BUTTON_SELECT] = IRR_KEY_BUTTON_SELECT; - KeyMap[AKEYCODE_BUTTON_MODE] = IRR_KEY_BUTTON_MODE; + g_keymap[AKEYCODE_BUTTON_A] = IRR_KEY_BUTTON_A; + g_keymap[AKEYCODE_BUTTON_B] = IRR_KEY_BUTTON_B; + g_keymap[AKEYCODE_BUTTON_C] = IRR_KEY_BUTTON_C; + g_keymap[AKEYCODE_BUTTON_X] = IRR_KEY_BUTTON_X; + g_keymap[AKEYCODE_BUTTON_Y] = IRR_KEY_BUTTON_Y; + g_keymap[AKEYCODE_BUTTON_Z] = IRR_KEY_BUTTON_Z; + g_keymap[AKEYCODE_BUTTON_L1] = IRR_KEY_BUTTON_L1; + g_keymap[AKEYCODE_BUTTON_R1] = IRR_KEY_BUTTON_R1; + g_keymap[AKEYCODE_BUTTON_L2] = IRR_KEY_BUTTON_L2; + g_keymap[AKEYCODE_BUTTON_R2] = IRR_KEY_BUTTON_R2; + g_keymap[AKEYCODE_BUTTON_THUMBL] = IRR_KEY_BUTTON_THUMBL; + g_keymap[AKEYCODE_BUTTON_THUMBR] = IRR_KEY_BUTTON_THUMBR; + g_keymap[AKEYCODE_BUTTON_START] = IRR_KEY_BUTTON_START; + g_keymap[AKEYCODE_BUTTON_SELECT] = IRR_KEY_BUTTON_SELECT; + g_keymap[AKEYCODE_BUTTON_MODE] = IRR_KEY_BUTTON_MODE; - KeyMap[AKEYCODE_ESCAPE] = IRR_KEY_ESCAPE; - KeyMap[AKEYCODE_FORWARD_DEL] = IRR_KEY_DELETE; - KeyMap[AKEYCODE_CTRL_LEFT] = IRR_KEY_CONTROL; - KeyMap[AKEYCODE_CTRL_RIGHT] = IRR_KEY_CONTROL; - KeyMap[AKEYCODE_CAPS_LOCK] = IRR_KEY_CAPITAL; - KeyMap[AKEYCODE_SCROLL_LOCK] = IRR_KEY_SCROLL; - KeyMap[AKEYCODE_META_LEFT] = IRR_KEY_LWIN; - KeyMap[AKEYCODE_META_RIGHT] = IRR_KEY_RWIN; - KeyMap[AKEYCODE_FUNCTION] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_SYSRQ] = IRR_KEY_SNAPSHOT; - KeyMap[AKEYCODE_BREAK] = IRR_KEY_PAUSE; - KeyMap[AKEYCODE_MOVE_HOME] = IRR_KEY_HOME; - KeyMap[AKEYCODE_MOVE_END] = IRR_KEY_END; - KeyMap[AKEYCODE_INSERT] = IRR_KEY_INSERT; - KeyMap[AKEYCODE_FORWARD] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MEDIA_PLAY] = IRR_KEY_PLAY; - KeyMap[AKEYCODE_MEDIA_PAUSE] = IRR_KEY_MEDIA_PLAY_PAUSE; - KeyMap[AKEYCODE_MEDIA_CLOSE] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MEDIA_EJECT] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MEDIA_RECORD] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_F1] = IRR_KEY_F1; - KeyMap[AKEYCODE_F2] = IRR_KEY_F2; - KeyMap[AKEYCODE_F3] = IRR_KEY_F3; - KeyMap[AKEYCODE_F4] = IRR_KEY_F4; - KeyMap[AKEYCODE_F5] = IRR_KEY_F5; - KeyMap[AKEYCODE_F6] = IRR_KEY_F6; - KeyMap[AKEYCODE_F7] = IRR_KEY_F7; - KeyMap[AKEYCODE_F8] = IRR_KEY_F8; - KeyMap[AKEYCODE_F9] = IRR_KEY_F9; - KeyMap[AKEYCODE_F10] = IRR_KEY_F10; - KeyMap[AKEYCODE_F11] = IRR_KEY_F11; - KeyMap[AKEYCODE_F12] = IRR_KEY_F12; - KeyMap[AKEYCODE_NUM_LOCK] = IRR_KEY_NUMLOCK; - KeyMap[AKEYCODE_NUMPAD_0] = IRR_KEY_NUMPAD0; - KeyMap[AKEYCODE_NUMPAD_1] = IRR_KEY_NUMPAD1; - KeyMap[AKEYCODE_NUMPAD_2] = IRR_KEY_NUMPAD2; - KeyMap[AKEYCODE_NUMPAD_3] = IRR_KEY_NUMPAD3; - KeyMap[AKEYCODE_NUMPAD_4] = IRR_KEY_NUMPAD4; - KeyMap[AKEYCODE_NUMPAD_5] = IRR_KEY_NUMPAD5; - KeyMap[AKEYCODE_NUMPAD_6] = IRR_KEY_NUMPAD6; - KeyMap[AKEYCODE_NUMPAD_7] = IRR_KEY_NUMPAD7; - KeyMap[AKEYCODE_NUMPAD_8] = IRR_KEY_NUMPAD8; - KeyMap[AKEYCODE_NUMPAD_9] = IRR_KEY_NUMPAD9; - KeyMap[AKEYCODE_NUMPAD_DIVIDE] = IRR_KEY_DIVIDE; - KeyMap[AKEYCODE_NUMPAD_MULTIPLY] = IRR_KEY_MULTIPLY; - KeyMap[AKEYCODE_NUMPAD_SUBTRACT] = IRR_KEY_SUBTRACT; - KeyMap[AKEYCODE_NUMPAD_ADD] = IRR_KEY_ADD; - KeyMap[AKEYCODE_NUMPAD_DOT] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_NUMPAD_COMMA] = IRR_KEY_COMMA; - KeyMap[AKEYCODE_NUMPAD_ENTER] = IRR_KEY_RETURN; - KeyMap[AKEYCODE_NUMPAD_EQUALS] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_NUMPAD_LEFT_PAREN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_NUMPAD_RIGHT_PAREN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_VOLUME_MUTE] = IRR_KEY_VOLUME_MUTE; - KeyMap[AKEYCODE_INFO] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CHANNEL_UP] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CHANNEL_DOWN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_ZOOM_IN] = IRR_KEY_ZOOM; - KeyMap[AKEYCODE_ZOOM_OUT] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_TV] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_WINDOW] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_GUIDE] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_DVR] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BOOKMARK] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CAPTIONS] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_SETTINGS] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_TV_POWER] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_TV_INPUT] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_STB_POWER] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_STB_INPUT] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_AVR_POWER] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_AVR_INPUT] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_PROG_RED] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_PROG_GREEN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_PROG_YELLOW] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_PROG_BLUE] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_APP_SWITCH] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_1] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_2] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_3] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_4] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_5] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_6] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_7] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_8] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_9] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_10] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_11] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_12] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_13] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_14] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_15] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BUTTON_16] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_LANGUAGE_SWITCH] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MANNER_MODE] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_3D_MODE] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CONTACTS] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CALENDAR] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MUSIC] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_CALCULATOR] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_ZENKAKU_HANKAKU] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_EISU] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MUHENKAN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_HENKAN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_KATAKANA_HIRAGANA] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_YEN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_RO] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_KANA] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_ASSIST] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BRIGHTNESS_DOWN] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_BRIGHTNESS_UP] = IRR_KEY_UNKNOWN; - KeyMap[AKEYCODE_MEDIA_AUDIO_TRACK] = IRR_KEY_UNKNOWN; -} - -wchar_t CIrrDeviceAndroid::getKeyChar(SEvent& event) -{ - // Handle ASCII chars - - wchar_t key_char = 0; - - // A-Z - if (event.KeyInput.SystemKeyCode > 28 && event.KeyInput.SystemKeyCode < 55) - { - if (event.KeyInput.Shift) - { - key_char = event.KeyInput.SystemKeyCode + 36; - } - else - { - key_char = event.KeyInput.SystemKeyCode + 68; - } - } - - // 0-9 - else if (event.KeyInput.SystemKeyCode > 6 && event.KeyInput.SystemKeyCode < 17) - { - key_char = event.KeyInput.SystemKeyCode + 41; - } - - else if (event.KeyInput.SystemKeyCode == AKEYCODE_BACK) - { - key_char = 8; - } - else if (event.KeyInput.SystemKeyCode == AKEYCODE_DEL) - { - key_char = 8; - } - else if (event.KeyInput.SystemKeyCode == AKEYCODE_TAB) - { - key_char = 9; - } - else if (event.KeyInput.SystemKeyCode == AKEYCODE_ENTER) - { - key_char = 13; - } - else if (event.KeyInput.SystemKeyCode == AKEYCODE_SPACE) - { - key_char = 32; - } - else if (event.KeyInput.SystemKeyCode == AKEYCODE_COMMA) - { - key_char = 44; - } - else if (event.KeyInput.SystemKeyCode == AKEYCODE_PERIOD) - { - key_char = 46; - } - - return key_char; -} - -wchar_t CIrrDeviceAndroid::getUnicodeChar(AInputEvent* event) -{ - jlong down_time = AKeyEvent_getDownTime(event); - jlong event_time = AKeyEvent_getEventTime(event); - jint action = AKeyEvent_getAction(event); - jint code = AKeyEvent_getKeyCode(event); - jint repeat = AKeyEvent_getRepeatCount(event); - jint meta_state = AKeyEvent_getMetaState(event); - jint device_id = AInputEvent_getDeviceId(event); - jint scan_code = AKeyEvent_getScanCode(event); - jint flags = AKeyEvent_getFlags(event); - jint source = AInputEvent_getSource(event); - - jclass key_event = m_jni_env->FindClass("android/view/KeyEvent"); - jmethodID key_event_constructor = m_jni_env->GetMethodID(key_event, "", - "(JJIIIIIIII)V"); - - jobject key_event_obj = m_jni_env->NewObject(key_event, key_event_constructor, - down_time, event_time, action, code, - repeat, meta_state, device_id, - scan_code, flags, source); - - jmethodID get_unicode = m_jni_env->GetMethodID(key_event, "getUnicodeChar", "(I)I"); - - wchar_t unicode_char = m_jni_env->CallIntMethod(key_event_obj, get_unicode, - meta_state); - - return unicode_char; + g_keymap[AKEYCODE_ESCAPE] = IRR_KEY_ESCAPE; + g_keymap[AKEYCODE_FORWARD_DEL] = IRR_KEY_DELETE; + g_keymap[AKEYCODE_CTRL_LEFT] = IRR_KEY_CONTROL; + g_keymap[AKEYCODE_CTRL_RIGHT] = IRR_KEY_CONTROL; + g_keymap[AKEYCODE_CAPS_LOCK] = IRR_KEY_CAPITAL; + g_keymap[AKEYCODE_SCROLL_LOCK] = IRR_KEY_SCROLL; + g_keymap[AKEYCODE_META_LEFT] = IRR_KEY_LWIN; + g_keymap[AKEYCODE_META_RIGHT] = IRR_KEY_RWIN; + g_keymap[AKEYCODE_FUNCTION] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_SYSRQ] = IRR_KEY_SNAPSHOT; + g_keymap[AKEYCODE_BREAK] = IRR_KEY_PAUSE; + g_keymap[AKEYCODE_MOVE_HOME] = IRR_KEY_HOME; + g_keymap[AKEYCODE_MOVE_END] = IRR_KEY_END; + g_keymap[AKEYCODE_INSERT] = IRR_KEY_INSERT; + g_keymap[AKEYCODE_FORWARD] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MEDIA_PLAY] = IRR_KEY_PLAY; + g_keymap[AKEYCODE_MEDIA_PAUSE] = IRR_KEY_MEDIA_PLAY_PAUSE; + g_keymap[AKEYCODE_MEDIA_CLOSE] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MEDIA_EJECT] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MEDIA_RECORD] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_F1] = IRR_KEY_F1; + g_keymap[AKEYCODE_F2] = IRR_KEY_F2; + g_keymap[AKEYCODE_F3] = IRR_KEY_F3; + g_keymap[AKEYCODE_F4] = IRR_KEY_F4; + g_keymap[AKEYCODE_F5] = IRR_KEY_F5; + g_keymap[AKEYCODE_F6] = IRR_KEY_F6; + g_keymap[AKEYCODE_F7] = IRR_KEY_F7; + g_keymap[AKEYCODE_F8] = IRR_KEY_F8; + g_keymap[AKEYCODE_F9] = IRR_KEY_F9; + g_keymap[AKEYCODE_F10] = IRR_KEY_F10; + g_keymap[AKEYCODE_F11] = IRR_KEY_F11; + g_keymap[AKEYCODE_F12] = IRR_KEY_F12; + g_keymap[AKEYCODE_NUM_LOCK] = IRR_KEY_NUMLOCK; + g_keymap[AKEYCODE_NUMPAD_0] = IRR_KEY_NUMPAD0; + g_keymap[AKEYCODE_NUMPAD_1] = IRR_KEY_NUMPAD1; + g_keymap[AKEYCODE_NUMPAD_2] = IRR_KEY_NUMPAD2; + g_keymap[AKEYCODE_NUMPAD_3] = IRR_KEY_NUMPAD3; + g_keymap[AKEYCODE_NUMPAD_4] = IRR_KEY_NUMPAD4; + g_keymap[AKEYCODE_NUMPAD_5] = IRR_KEY_NUMPAD5; + g_keymap[AKEYCODE_NUMPAD_6] = IRR_KEY_NUMPAD6; + g_keymap[AKEYCODE_NUMPAD_7] = IRR_KEY_NUMPAD7; + g_keymap[AKEYCODE_NUMPAD_8] = IRR_KEY_NUMPAD8; + g_keymap[AKEYCODE_NUMPAD_9] = IRR_KEY_NUMPAD9; + g_keymap[AKEYCODE_NUMPAD_DIVIDE] = IRR_KEY_DIVIDE; + g_keymap[AKEYCODE_NUMPAD_MULTIPLY] = IRR_KEY_MULTIPLY; + g_keymap[AKEYCODE_NUMPAD_SUBTRACT] = IRR_KEY_SUBTRACT; + g_keymap[AKEYCODE_NUMPAD_ADD] = IRR_KEY_ADD; + g_keymap[AKEYCODE_NUMPAD_DOT] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_NUMPAD_COMMA] = IRR_KEY_COMMA; + g_keymap[AKEYCODE_NUMPAD_ENTER] = IRR_KEY_RETURN; + g_keymap[AKEYCODE_NUMPAD_EQUALS] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_NUMPAD_LEFT_PAREN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_NUMPAD_RIGHT_PAREN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_VOLUME_MUTE] = IRR_KEY_VOLUME_MUTE; + g_keymap[AKEYCODE_INFO] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CHANNEL_UP] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CHANNEL_DOWN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_ZOOM_IN] = IRR_KEY_ZOOM; + g_keymap[AKEYCODE_ZOOM_OUT] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_TV] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_WINDOW] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_GUIDE] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_DVR] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BOOKMARK] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CAPTIONS] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_SETTINGS] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_TV_POWER] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_TV_INPUT] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_STB_POWER] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_STB_INPUT] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_AVR_POWER] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_AVR_INPUT] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_PROG_RED] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_PROG_GREEN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_PROG_YELLOW] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_PROG_BLUE] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_APP_SWITCH] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_1] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_2] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_3] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_4] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_5] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_6] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_7] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_8] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_9] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_10] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_11] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_12] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_13] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_14] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_15] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BUTTON_16] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_LANGUAGE_SWITCH] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MANNER_MODE] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_3D_MODE] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CONTACTS] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CALENDAR] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MUSIC] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_CALCULATOR] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_ZENKAKU_HANKAKU] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_EISU] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MUHENKAN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_HENKAN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_KATAKANA_HIRAGANA] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_YEN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_RO] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_KANA] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_ASSIST] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BRIGHTNESS_DOWN] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_BRIGHTNESS_UP] = IRR_KEY_UNKNOWN; + g_keymap[AKEYCODE_MEDIA_AUDIO_TRACK] = IRR_KEY_UNKNOWN; } void CIrrDeviceAndroid::openURL(const std::string& url) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h index 6e125cb71..bd90e58ea 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h @@ -72,7 +72,6 @@ namespace irr virtual bool deactivateGyroscope(); virtual bool isGyroscopeActive(); virtual bool isGyroscopeAvailable(); - virtual void setTextInputEnabled(bool enabled) {TextInputEnabled = enabled;} void fromSTKEditBox(int widget_id, const core::stringw& text, int selection_start, int selection_end, int type); virtual void toggleOnScreenKeyboard(bool show, s32 type = 0); virtual bool supportsTouchDevice() const { return HasTouchDevice; } @@ -104,31 +103,18 @@ namespace irr const ASensor* Gyroscope; bool AccelerometerActive; bool GyroscopeActive; - bool TextInputEnabled; static AndroidApplicationInfo ApplicationInfo; static bool IsPaused; static bool IsFocused; static bool IsStarted; - struct TouchEventData - { - int x; - int y; - ETOUCH_INPUT_EVENT event; - - TouchEventData() : x(0), y(0), event(ETIE_COUNT) {}; - }; - - TouchEventData TouchEventsData[32]; bool HasTouchDevice; float GamepadAxisX; float GamepadAxisY; DeviceOrientation DefaultOrientation; video::SExposedVideoData ExposedVideoData; - - std::map KeyMap; void printConfig(); void createDriver(); @@ -142,10 +128,6 @@ namespace irr video::SExposedVideoData& getExposedVideoData(); static void handleAndroidCommand(android_app* app, int32_t cmd); - static s32 handleInput(android_app* app, AInputEvent* event); - - s32 handleTouch(AInputEvent* androidEvent); - s32 handleKeyboard(AInputEvent* androidEvent); }; } // end namespace irr diff --git a/lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c b/lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c index aca8bce25..a25a56af9 100644 --- a/lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c +++ b/lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c @@ -432,9 +432,13 @@ static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) android_app_set_input(app, NULL); } +// Defined in CIrrDeviceAndroid, we call it in android main thread so after activity +// starts keymap is visible to all threads +extern void createKeyMap(); void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) { LOGV("Creating: %p\n", activity); + createKeyMap(); activity->callbacks->onDestroy = onDestroy; activity->callbacks->onStart = onStart; activity->callbacks->onResume = onResume; diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index 80db37d87..b35f004c7 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -189,7 +189,6 @@ CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border, PasswordChar(U'*'), HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER), CurrentTextRect(0,0,1,1), FrameRect(rectangle) { - m_from_android_edittext = false; m_composing_start = 0; m_composing_end = 0; m_type = (GUIEngine::TextBoxType)0; @@ -244,14 +243,6 @@ CGUIEditBox::~CGUIEditBox() } #elif defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) DestroyCaret(); -#endif -#ifdef ANDROID - if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID) - { - CIrrDeviceAndroid* dl = dynamic_cast( - irr_driver->getDevice()); - dl->setTextInputEnabled(false); - } #endif if (GUIEngine::ScreenKeyboard::shouldUseScreenKeyboard() && GUIEngine::ScreenKeyboard::hasSystemScreenKeyboard()) @@ -347,9 +338,6 @@ bool CGUIEditBox::OnEvent(const SEvent& event) #ifndef SERVER_ONLY if (isEnabled()) { - // Ignore key input if we only fromAndroidEditText - if (m_from_android_edittext && event.EventType == EET_KEY_INPUT_EVENT) - return true; switch(event.EventType) { case EET_GUI_EVENT: @@ -370,15 +358,6 @@ bool CGUIEditBox::OnEvent(const SEvent& event) #elif defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) DestroyCaret(); #endif -#ifdef ANDROID - if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID) - { - CIrrDeviceAndroid* dl = dynamic_cast( - irr_driver->getDevice()); - dl->setTextInputEnabled(false); - } -#endif - m_from_android_edittext = false; m_composing_start = 0; m_composing_end = 0; m_composing_text.clear(); @@ -396,29 +375,17 @@ bool CGUIEditBox::OnEvent(const SEvent& event) #endif calculateScrollPos(); #ifdef ANDROID - if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID) - { - CIrrDeviceAndroid* dl = dynamic_cast( - irr_driver->getDevice()); - dl->setTextInputEnabled(true); - } - if (GUIEngine::ScreenKeyboard::shouldUseScreenKeyboard() && GUIEngine::ScreenKeyboard::hasSystemScreenKeyboard() && irr_driver->getDevice()->getType() == irr::EIDT_ANDROID) { // If user toggle with hacker keyboard with arrows, keep // using only text from STKEditTex - m_from_android_edittext = true; CIrrDeviceAndroid* dl = dynamic_cast( irr_driver->getDevice()); dl->fromSTKEditBox(getID(), Text, m_mark_begin, m_mark_end, m_type); } - else #endif - { - m_from_android_edittext = false; - } m_composing_text.clear(); } break; @@ -1523,8 +1490,6 @@ void CGUIEditBox::fromAndroidEditText(const std::u32string& text, int start, int end, int composing_start, int composing_end) { - // When focus of this element is lost, this will be set to false again - m_from_android_edittext = true; // Prevent invalid start or end if ((unsigned)end > text.size()) { diff --git a/src/guiengine/widgets/CGUIEditBox.hpp b/src/guiengine/widgets/CGUIEditBox.hpp index 5411d40ae..9d32fbaef 100644 --- a/src/guiengine/widgets/CGUIEditBox.hpp +++ b/src/guiengine/widgets/CGUIEditBox.hpp @@ -180,10 +180,6 @@ namespace GUIEngine s32 m_composing_start; s32 m_composing_end; - /* If true, this editbox will copy text and selection only from - * android edittext, and process only mouse event. */ - bool m_from_android_edittext; - /* UTF32 string for shaping and editing to avoid wchar_t issue in * windows */ std::u32string m_edit_text;