/** * Convert an Android key event to ASCII. */ static unsigned char key_ascii(struct android_app* app, AInputEvent* event) { int32_t code = AKeyEvent_getKeyCode(event); /* Handle a few special cases: */ switch (code) { case AKEYCODE_DEL: return 8; case AKEYCODE_FORWARD_DEL: return 127; case AKEYCODE_ESCAPE: return 27; } /* Get usable JNI context */ JNIEnv* env = app->activity->env; JavaVM* vm = app->activity->vm; (*vm)->AttachCurrentThread(vm, &env, NULL); jclass KeyEventClass = (*env)->FindClass(env, "android/view/KeyEvent"); jmethodID KeyEventConstructor = (*env)->GetMethodID(env, KeyEventClass, "<init>", "(II)V"); jobject keyEvent = (*env)->NewObject(env, KeyEventClass, KeyEventConstructor, AKeyEvent_getAction(event), AKeyEvent_getKeyCode(event)); jmethodID KeyEvent_getUnicodeChar = (*env)->GetMethodID(env, KeyEventClass, "getUnicodeChar", "(I)I"); int ascii = (*env)->CallIntMethod(env, keyEvent, KeyEvent_getUnicodeChar, AKeyEvent_getMetaState(event)); /* LOGI("getUnicodeChar(%d) = %d ('%c')", AKeyEvent_getKeyCode(event), ascii, ascii); */ return ascii; }
bool InputService::onKeyboardEvent(AInputEvent* pEvent) { #ifdef INPUTSERVICE_LOG_EVENTS packt_Log_debug("AKeyEvent_getAction=%d", AKeyEvent_getAction(pEvent)); packt_Log_debug("AKeyEvent_getFlags=%d", AKeyEvent_getFlags(pEvent)); packt_Log_debug("AKeyEvent_getKeyCode=%d", AKeyEvent_getKeyCode(pEvent)); packt_Log_debug("AKeyEvent_getScanCode=%d", AKeyEvent_getScanCode(pEvent)); packt_Log_debug("AKeyEvent_getMetaState=%d", AKeyEvent_getMetaState(pEvent)); packt_Log_debug("AKeyEvent_getRepeatCount=%d", AKeyEvent_getRepeatCount(pEvent)); packt_Log_debug("AKeyEvent_getDownTime=%lld", AKeyEvent_getDownTime(pEvent)); packt_Log_debug("AKeyEvent_getEventTime=%lld", AKeyEvent_getEventTime(pEvent)); #endif const float ORTHOGONAL_MOVE = 1.0f; if (AKeyEvent_getAction(pEvent) == AKEY_EVENT_ACTION_DOWN) { switch (AKeyEvent_getKeyCode(pEvent)) { case AKEYCODE_DPAD_LEFT: mHorizontal = -ORTHOGONAL_MOVE; break; case AKEYCODE_DPAD_RIGHT: mHorizontal = ORTHOGONAL_MOVE; break; case AKEYCODE_DPAD_DOWN: mVertical = -ORTHOGONAL_MOVE; break; case AKEYCODE_DPAD_UP: mVertical = ORTHOGONAL_MOVE; break; case AKEYCODE_BACK: return false; } } else { switch (AKeyEvent_getKeyCode(pEvent)) { case AKEYCODE_DPAD_LEFT: case AKEYCODE_DPAD_RIGHT: mHorizontal = 0.0f; break; case AKEYCODE_DPAD_DOWN: case AKEYCODE_DPAD_UP: mVertical = 0.0f; break; case AKEYCODE_MENU: mMenuKey = true; break; case AKEYCODE_BACK: return false; } } return true; }
static int32_t input(struct android_app * app, AInputEvent * e) { int handled = 1; int kc; cvkey cvkc; int action; switch (AInputEvent_getType(e)) { case AINPUT_EVENT_TYPE_KEY: kc = AKeyEvent_getKeyCode(e); action = AKeyEvent_getAction(e); cvkc = mapkey(kc); handled = kc != CVK_NONE; if (handled) { if (action == AKEY_EVENT_ACTION_DOWN) cvInject(CVE_DOWN, cvkc, 0); if (action == AKEY_EVENT_ACTION_UP) cvInject(CVE_UP, cvkc, 0); } break; case AINPUT_EVENT_TYPE_MOTION: cvInject(CVE_MOTION, AMotionEvent_getX(e, 0), AMotionEvent_getY(e, 0)); break; default: handled = 0; } return handled; }
static bool _process_keys(bool isJoy, AInputEvent *event, CookedEventCallback callback) { if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) { int action = AKeyEvent_getAction(event); int code = _translate_keycode(AKeyEvent_getKeyCode(event)); bool handled = code >= 0; if (code >= 0 && action == AKEY_EVENT_ACTION_DOWN) { _report_key_state(code, true, callback); } else if (code >= 0 && action == AKEY_EVENT_ACTION_UP) { _report_key_state(code, false, callback); } return handled; } else if (isJoy) { // use joystick axes to emulate directional key events (we could leave this // up to the platform, but joystick-to-dpad conversion doesn't work // on NDK on older devices, so we implement manually for maximum compatibility) float x = AMotionEvent_getX(event, 0); float y = AMotionEvent_getY(event, 0); if (_getAxisValue) { // take the hat switches into account too, so that either the // regular axes or the hat axes can be used to navigate UIs x += _getAxisValue(event, AXIS_HAT_X, 0); y += _getAxisValue(event, AXIS_HAT_Y, 0); x = Clamp(x, -1.0f, 1.0f); y = Clamp(y, -1.0f, 1.0f); } _report_key_states_from_axes(x, y, callback); return true; } }
int32_t handle_input_events(struct android_app* app, AInputEvent* event) { int etype = AInputEvent_getType(event); switch (etype) { case AINPUT_EVENT_TYPE_KEY: int32_t eaction, eflags, ekeycode, escancode; eaction = AKeyEvent_getAction(event); eflags = AKeyEvent_getFlags(event); ekeycode = AKeyEvent_getKeyCode(event); // LOGI(2, "%s", get_key_event_str(eaction, eflags, ekeycode)); break; case AINPUT_EVENT_TYPE_MOTION: int32_t action, posX, pointer_index; action = AMotionEvent_getAction(event); pointer_index = (action&AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; posX = AMotionEvent_getX(event, pointer_index); //write a command to the activity lifecycle event queue (pipe) if (action == AMOTION_EVENT_ACTION_MOVE) { int xMove = posX - mPreviousX; USERDATA* userData = (USERDATA*)app->userData; userData->xMove = xMove; app->redrawNeeded = 1; } mPreviousX = posX; // LOGI(2, "action: %d, posX: %d, mPreviousX: %d, posX: %d", action, posX, mPreviousX, posX); break; default: LOGI(2, "other input event"); break; } }
bool CookEvent(AInputEvent *event, CookedEventCallback callback) { int type = AInputEvent_getType(event); int src = AInputEvent_getSource(event); bool isJoy = (type == AINPUT_EVENT_TYPE_MOTION) && (src & AINPUT_SOURCE_CLASS_MASK) == SOURCE_CLASS_JOYSTICK; if (!_init_done) { _init(); _init_done = true; } if (isJoy) { return CookEvent_Joy(event, callback); } else if (type == AINPUT_EVENT_TYPE_KEY) { bool handled = _process_keys(false, event, callback); if (AKeyEvent_getKeyCode(event) == AKEYCODE_BACK && 0 == AKeyEvent_getAction(event)) { // back key was pressed struct CookedEvent ev; memset(&ev, 0, sizeof(ev)); ev.type = COOKED_EVENT_TYPE_BACK; return callback(&ev); } // Note: if you want to handle other keys, add code here. For now we only // handle DPAD keys as indicated in _process_keys. return handled; } else if (type == AINPUT_EVENT_TYPE_MOTION) { return CookEvent_Motion(event, callback); } return false; }
/** * @brief * Call this to process the next key input event */ void AndroidKeyboardDevice::OnKeyInputEvent(const struct AInputEvent &cAKeyInputEvent) { // Check if input device is valid if (m_pDevice) { // Get Android key code const int32_t nKeyCode = AKeyEvent_getKeyCode(&cAKeyInputEvent); // Lookout! The virtual keyboard of Android sends "down" and "up" directly one after another // -> This is really a problem and we have to delay further keys... if (m_lstProcessedKeys.IsElement(nKeyCode)) { // Add key for later processing KeyInfo sKeyInfo; sKeyInfo.nKeyCode = nKeyCode; sKeyInfo.bPressed = (AKeyEvent_getAction(&cAKeyInputEvent) == AKEY_EVENT_ACTION_DOWN); m_lstDelayedKeys.Add(sKeyInfo); } else { // Get keyboard device Keyboard *pKeyboard = static_cast<Keyboard*>(m_pDevice); // Get button Button *pButton = GetKeyboardKey(*pKeyboard, nKeyCode); if (pButton) { // Get button state const bool bPressed = (AKeyEvent_getAction(&cAKeyInputEvent) == AKEY_EVENT_ACTION_DOWN); // Propagate changes if (pButton->IsPressed() != bPressed) pButton->SetPressed(bPressed); } // Add this key to the processed keys m_lstProcessedKeys.Add(nKeyCode); } } }
event_result message_dispatcher::fire_on_dpad(app& the_app, AInputEvent *ie) { int kcode = AKeyEvent_getKeyCode(ie); int type = AKeyEvent_getAction(ie); bool h = false; switch (kcode) { case AKEYCODE_DPAD_UP: h = the_app.on_dpad_up(type == AKEY_EVENT_ACTION_DOWN ? button_event::down : button_event::up); break; case AKEYCODE_DPAD_DOWN: h = the_app.on_dpad_down(type == AKEY_EVENT_ACTION_DOWN ? button_event::down : button_event::up); break; case AKEYCODE_DPAD_LEFT: h = the_app.on_dpad_left(type == AKEY_EVENT_ACTION_DOWN ? button_event::down : button_event::up); break; case AKEYCODE_DPAD_RIGHT: h = the_app.on_dpad_right(type == AKEY_EVENT_ACTION_DOWN ? button_event::down : button_event::up); break; case AKEYCODE_DPAD_CENTER: h = the_app.on_dpad_center(type == AKEY_EVENT_ACTION_DOWN ? button_event::down : button_event::up); break; default: break; } return h ? event_result::handled : event_result::unhandled; }
///// キー入力イベント処理 void get_key_event(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*) app->userData; int keyaction; // キーコードを取得 int keycode = AKeyEvent_getKeyCode(event); /////-----(1) ここから // 音量キー(上)の入力が変化した if (keycode == AKEYCODE_VOLUME_UP) { /////-----(1) ここまで keyaction = AKeyEvent_getAction(event); /////-----(2) ここから if (keyaction == AKEY_EVENT_ACTION_DOWN) { /////-----(2) ここまで // キーを押した engine->volumeup_keydown = TRUE; } else { // キーを離した engine->volumeup_keydown = FALSE; } } // 音量キー(下)の入力変化した if (keycode == AKEYCODE_VOLUME_DOWN) { keyaction = AKeyEvent_getAction(event); if (keyaction == AKEY_EVENT_ACTION_DOWN) { // キーを押した engine->volumedown_keydown = TRUE; } else { // キーを離した engine->volumedown_keydown = FALSE; } } }
/* * Handle Key Inputs */ static int32_t handle_key_input(AInputEvent *event) { if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) { auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher(); switch (AKeyEvent_getKeyCode(event)) { case AKEYCODE_BACK: { cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE, false); dispatcher->dispatchEvent(&event); } return 1; case AKEYCODE_MENU: { cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_MENU, false); dispatcher->dispatchEvent(&event); } return 1; default: break; } } return 0; }
static int32_t handleInput(struct android_app* app, AInputEvent* event) { if (okit.getInput()) { if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { int action = (int)(AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction(event)); if (action == 0) okit.injectTouch(2, AMotionEvent_getRawX(event, 0), AMotionEvent_getRawY(event, 0)); okit.injectTouch(action, AMotionEvent_getRawX(event, 0), AMotionEvent_getRawY(event, 0)); } else { int action = AKeyEvent_getAction(event); int unicodeChar = 0; okit.injectKey(action, unicodeChar, AKeyEvent_getKeyCode(event)); //mInputInjector->injectKeyEvent(AKeyEvent_getAction(event), AKeyEvent_getKeyCode(event)); } return 1; } return 0; }
static void process_input(struct android_app* app, struct android_poll_source* source) { AInputEvent* event = NULL; if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { // HACK: Override back buttom to show / hide keyboard. int type = AInputEvent_getType(event); if(type == AINPUT_EVENT_TYPE_KEY) { if(AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) { static bool keyboard_shown = false; if( AKeyEvent_getKeyCode(event) == AKEYCODE_BACK ) { displayKeyboard(app,!keyboard_shown); keyboard_shown = !keyboard_shown; AInputQueue_finishEvent(app->inputQueue, event, 1); return; } } } if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { return; } int32_t handled = 0; if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); AInputQueue_finishEvent(app->inputQueue, event, handled); } else { LOGE("Failure reading next input event: %s\n", strerror(errno)); } }
static int32_t input_eventcallback(struct android_app* app, AInputEvent* event) { int32_t type = AInputEvent_getType(event); AndroidApplication* a = (AndroidApplication*)app->userData; switch (type) { case AINPUT_EVENT_TYPE_MOTION: switch (AInputEvent_getSource(event)) { case AINPUT_SOURCE_TOUCHSCREEN: return a->eventManager()->processTouchEvent(event); break; } break; case AINPUT_EVENT_TYPE_KEY: Log::debug("EVENT INPUT OK"); switch(AKeyEvent_getKeyCode(event)) { case AKEYCODE_BACK: return 1; break; } return 0; break; } }
event_result message_dispatcher::fire_on_external(app& the_app, AInputEvent *ie) { int kcode = AKeyEvent_getKeyCode(ie); if (kcode >= AKEYCODE_DPAD_UP && kcode <= AKEYCODE_DPAD_CENTER) { return fire_on_dpad(the_app, ie); } if (kcode == AKEYCODE_CALL) { if (the_app.on_call()) return event_result::handled; return event_result::unhandled; } else if (kcode == AKEYCODE_ENDCALL) { if (the_app.on_endcall()) return event_result::handled; return event_result::unhandled; } else if (kcode == AKEYCODE_VOLUME_UP || kcode == AKEYCODE_VOLUME_DOWN) { if (the_app.on_volume_change(kcode == AKEYCODE_VOLUME_UP ? 1 : -1)) return event_result::handled; return event_result::unhandled; } else if (kcode == AKEYCODE_MENU) { int action = AKeyEvent_getAction(ie); button_event be = button_event::down; if (action != AKEY_EVENT_ACTION_DOWN) be = button_event::up; if (the_app.on_menu(be)) return event_result::handled; return event_result::unhandled; } // I should handle some other "keys", but I'm a bit lazy to write the code... LOGE("%s:%d> unknown external function %d\n", __FILE__, __LINE__, kcode); return event_result::unhandled; }
int32_t AndroidAppHelper::handleInput (struct android_app* app, AInputEvent* event) { if (mInputInjector) { if (AInputEvent_getType (event) == AINPUT_EVENT_TYPE_MOTION) { int action = (int) (AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction (event)); if (action == 0) { mInputInjector->injectTouchEvent (2, AMotionEvent_getRawX (event, 0), AMotionEvent_getRawY (event, 0)); } mInputInjector->injectTouchEvent (action, AMotionEvent_getRawX (event, 0), AMotionEvent_getRawY (event, 0)); } else { mInputInjector->injectKeyEvent (AKeyEvent_getAction (event), AKeyEvent_getKeyCode (event)); } return 1; } return 0; }
/* * IN_Android_KeyEvent2UCS */ static wchar_t IN_Android_KeyEvent2UCS( const AInputEvent *event ) { JNIEnv *env = Sys_Android_GetJNIEnv(); static jclass mapClass; static jmethodID load, get; jobject map; unsigned int ucs; if( !mapClass ) { jclass mapClassRef; mapClassRef = (*env)->FindClass( env, "android/view/KeyCharacterMap" ); mapClass = (*env)->NewGlobalRef( env, mapClassRef ); load = (*env)->GetStaticMethodID( env, mapClass, "load", "(I)Landroid/view/KeyCharacterMap;" ); get = (*env)->GetMethodID( env, mapClass, "get", "(II)I" ); (*env)->DeleteLocalRef( env, mapClassRef ); } map = (*env)->CallStaticObjectMethod( env, mapClass, load, AInputEvent_getDeviceId( event ) ); ucs = (*env)->CallIntMethod( env, map, get, AKeyEvent_getKeyCode( event ), AKeyEvent_getMetaState( event ) ); (*env)->DeleteLocalRef( env, map ); return ucs; }
static int HandleInput(struct android_app* app, AInputEvent* event) { Android_App* myapp = (Android_App*) app->userData; if(myapp) { switch(AInputEvent_getType(event)) { case AINPUT_EVENT_TYPE_KEY: { switch(AKeyEvent_getKeyCode(event)) { case 4: // Back if(AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) myapp->OnKeyPress(enumKEY_Back); break; case 24: // Volume up break; case 25: // Volume down break; } break; } case AINPUT_EVENT_TYPE_MOTION: // Handle touch events { switch(AMotionEvent_getAction(event)) { case AMOTION_EVENT_ACTION_DOWN: { Touch t = { AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) }; myapp->OnTouchDown(&t, 1); break; } case AMOTION_EVENT_ACTION_MOVE: { Touch t = { AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) }; myapp->OnTouchMoved(&t, 1); break; } case AMOTION_EVENT_ACTION_UP: { Touch t = { AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) }; myapp->OnTouchUp(&t, 1); break; } } return 1; } } } return 1; }
void engine_handle_key_evt (struct android_app* app, AInputEvent* event) { int32_t key_code; if (AKeyEvent_getAction(event) != AKEY_EVENT_ACTION_UP) { return; } key_code = AKeyEvent_getKeyCode(event); }
int32_t getKeyRune(JNIEnv* env, AInputEvent* e) { return (int32_t)(*env)->CallIntMethod( env, current_ctx, key_rune_method, AInputEvent_getDeviceId(e), AKeyEvent_getKeyCode(e), AKeyEvent_getMetaState(e) ); }
void ApplicationContextAndroid::_fireInputEventAndroid(AInputEvent* event, int wheel) { Event evt = {0}; static TouchFingerEvent lastTouch = {0}; if(wheel) { evt.type = MOUSEWHEEL; evt.wheel.y = wheel; _fireInputEvent(evt, 0); lastTouch.fingerId = -1; // prevent move-jump after pinch is over return; } if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { int32_t action = AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction(event); switch (action) { case AMOTION_EVENT_ACTION_DOWN: evt.type = FINGERDOWN; break; case AMOTION_EVENT_ACTION_UP: evt.type = FINGERUP; break; case AMOTION_EVENT_ACTION_MOVE: evt.type = FINGERMOTION; break; default: return; } Ogre::RenderWindow* win = getRenderWindow(); evt.tfinger.fingerId = AMotionEvent_getPointerId(event, 0); evt.tfinger.x = AMotionEvent_getRawX(event, 0) / win->getWidth(); evt.tfinger.y = AMotionEvent_getRawY(event, 0) / win->getHeight(); if(evt.type == FINGERMOTION) { if(evt.tfinger.fingerId != lastTouch.fingerId) return; // wrong finger evt.tfinger.dx = evt.tfinger.x - lastTouch.x; evt.tfinger.dy = evt.tfinger.y - lastTouch.y; } lastTouch = evt.tfinger; } else { if(AKeyEvent_getKeyCode(event) != AKEYCODE_BACK) return; evt.type = AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN ? KEYDOWN : KEYUP; evt.key.keysym.sym = SDLK_ESCAPE; } _fireInputEvent(evt, 0); }
int32_t android_handle_input(struct android_app* app, AInputEvent* event) { switch (AInputEvent_getType(event)) { case AINPUT_EVENT_TYPE_KEY: return AKeyEvent_getKeyCode(event) == AKEYCODE_BACK; case AINPUT_EVENT_TYPE_MOTION: return android_handle_motion(app, event); default: return 0; } }
bool CAndroidJoyStick::onJoyStickKeyEvent(AInputEvent *event) { if (event == NULL) return false; int32_t keycode = AKeyEvent_getKeyCode(event); // watch this check, others might be different. // AML IR Controller is AINPUT_SOURCE_GAMEPAD | AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD // Gamestick Controller == AINPUT_SOURCE_GAMEPAD | AINPUT_SOURCE_KEYBOARD // NVidiaShield Controller == AINPUT_SOURCE_GAMEPAD | AINPUT_SOURCE_KEYBOARD // we want to reject AML IR Controller. if (AInputEvent_getSource(event) == (AINPUT_SOURCE_GAMEPAD | AINPUT_SOURCE_KEYBOARD)) { // GamePad events are AINPUT_EVENT_TYPE_KEY events, // trap them here and revector valid ones as JoyButtons // so we get keymap handling. for (size_t i = 0; i < sizeof(ButtonMap) / sizeof(KeyMap); i++) { if (keycode == ButtonMap[i].nativeKey) { uint32_t holdtime = 0; uint8_t button = ButtonMap[i].xbmcID; int32_t action = AKeyEvent_getAction(event); int32_t device = AInputEvent_getDeviceId(event); if ((action == AKEY_EVENT_ACTION_UP)) { // ProcessJoystickEvent does not understand up, ignore it. m_prev_holdtime = m_prev_device = m_prev_button = 0; return false; } else { if (m_prev_holdtime && device == m_prev_device && button == m_prev_button) { holdtime = CTimeUtils::GetFrameTime() - m_prev_holdtime; } else { m_prev_holdtime = CTimeUtils::GetFrameTime(); m_prev_device = device; m_prev_button = button; } } XBMC_JoyButton(device, button, holdtime, action == AKEY_EVENT_ACTION_UP); return true; } } } return false; }
int WindowImplAndroid::getUnicode(AInputEvent* event) { // Retrieve activity states ActivityStates* states = getActivity(NULL); Lock lock(states->mutex); // Initializes JNI jint lResult; jint lFlags = 0; JavaVM* lJavaVM = states->activity->vm; JNIEnv* lJNIEnv = states->activity->env; JavaVMAttachArgs lJavaVMAttachArgs; lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.name = "NativeThread"; lJavaVMAttachArgs.group = NULL; lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); if (lResult == JNI_ERR) err() << "Failed to initialize JNI, couldn't get the Unicode value" << std::endl; // Retrieve key data from the input event jlong downTime = AKeyEvent_getDownTime(event); jlong eventTime = AKeyEvent_getEventTime(event); jint action = AKeyEvent_getAction(event); jint code = AKeyEvent_getKeyCode(event); jint repeat = AKeyEvent_getRepeatCount(event); // not sure! jint metaState = AKeyEvent_getMetaState(event); jint deviceId = AInputEvent_getDeviceId(event); jint scancode = AKeyEvent_getScanCode(event); jint flags = AKeyEvent_getFlags(event); jint source = AInputEvent_getSource(event); // Construct a KeyEvent object from the event data jclass ClassKeyEvent = lJNIEnv->FindClass("android/view/KeyEvent"); jmethodID KeyEventConstructor = lJNIEnv->GetMethodID(ClassKeyEvent, "<init>", "(JJIIIIIIII)V"); jobject ObjectKeyEvent = lJNIEnv->NewObject(ClassKeyEvent, KeyEventConstructor, downTime, eventTime, action, code, repeat, metaState, deviceId, scancode, flags, source); // Call its getUnicodeChar() method to get the Unicode value jmethodID MethodGetUnicode = lJNIEnv->GetMethodID(ClassKeyEvent, "getUnicodeChar", "(I)I"); int unicode = lJNIEnv->CallIntMethod(ObjectKeyEvent, MethodGetUnicode, metaState); lJNIEnv->DeleteLocalRef(ClassKeyEvent); lJNIEnv->DeleteLocalRef(ObjectKeyEvent); // Detach this thread from the JVM lJavaVM->DetachCurrentThread(); return unicode; }
int32_t cxAndroid::HandleKeyInput(AInputEvent* event) { cxKeyType type = cxKeyTypeDown; cxInt action = AKeyEvent_getAction(event); if(action == AKEY_EVENT_ACTION_DOWN){ type = cxKeyTypeDown; }else if(action == AKEY_EVENT_ACTION_UP){ type = cxKeyTypeUp; }else if(action == AKEY_EVENT_ACTION_MULTIPLE){ type = cxKeyTypeMultiple; } return cxEngine::Instance()->Dispatch(type, AKeyEvent_getKeyCode(event)); }
extern "C" int AndroidGetKeyText( AInputEvent *event ) { int result = 0; // Attaches the current thread to the JVM. jint lResult; jint lFlags = 0; JavaVM* lJavaVM = engine.app->activity->vm; JNIEnv* lJNIEnv = engine.app->activity->env; JavaVMAttachArgs lJavaVMAttachArgs; lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.name = "NativeThread"; lJavaVMAttachArgs.group = NULL; lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); if (lResult == JNI_ERR) { return 0; } // Retrieves NativeActivity. jobject lNativeActivity = engine.app->activity->clazz; jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity); jmethodID MethodSetFlags = lJNIEnv->GetMethodID( ClassNativeActivity, "getKeyText", "(JJIIIIIII)I"); lprintf( "..." ); if( MethodSetFlags ) result = lJNIEnv->CallIntMethod( lNativeActivity, MethodSetFlags , AKeyEvent_getDownTime(event) , AKeyEvent_getEventTime(event) , AKeyEvent_getAction(event) , AKeyEvent_getKeyCode(event) , AKeyEvent_getRepeatCount(event) , AKeyEvent_getMetaState(event) , AInputEvent_getDeviceId(event) , AKeyEvent_getScanCode(event) , AKeyEvent_getFlags(event) ); else { lprintf( "Failed to get method." ); result = 0; } // Finished with the JVM. lJavaVM->DetachCurrentThread(); return result; }
static void _log_event(AInputEvent *event) { if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) { LOGD("DEBUG: Key event: action=%d, keycode=%d, meta=0x%x, source=%d", AKeyEvent_getAction(event), AKeyEvent_getKeyCode(event), AKeyEvent_getMetaState(event), (int)(AInputEvent_getSource(event))); } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { LOGD("DEBUG: Motion event: deviceid=%d, pointerid=%d, sourceid=%d, action=%d, keycode=%d" "x,y=%f,%f, raw x,y=%f,%f, source=%d", (int)AInputEvent_getDeviceId(event), (int)AMotionEvent_getPointerId(event, 0), (int)AInputEvent_getSource(event), (int)AKeyEvent_getAction(event), (int)AKeyEvent_getKeyCode(event), (float)AMotionEvent_getX(event,0), (float)AMotionEvent_getY(event,0), (float)AMotionEvent_getRawX(event,0), (float)AMotionEvent_getRawY(event,0), (int)(AInputEvent_getSource(event))); } else { LOGD("DEBUG: other type of event, %d", AInputEvent_getType(event)); } }
static int32_t handle_input(struct android_app* app, AInputEvent* event) { /* app->userData is available here */ if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { app_has_focus = true; return 1; } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) { LOGI("Key event: action=%d keyCode=%d metaState=0x%x", AKeyEvent_getAction(event), AKeyEvent_getKeyCode(event), AKeyEvent_getMetaState(event)); } return 0; }
static int32_t engine_handle_input(struct android_app *app, AInputEvent * event) { struct engine *engine = (struct engine *) app->userData; if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { // engine->animating = 1; return 1; } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) { LOGI("Key event: action=%d keyCode=%d metaState=0x%x", AKeyEvent_getAction(event), AKeyEvent_getKeyCode(event), AKeyEvent_getMetaState(event)); } return 0; }
static void Sys_Android_ProcessInput( struct android_app *app, struct android_poll_source *source ) { AInputEvent *event = NULL; int32_t handled; while( AInputQueue_getEvent( app->inputQueue, &event ) >= 0 ) { // Instead of calling AInputQueue_preDispatchEvent which hangs the whole engine on API 17 and lower, // let onInputEvent hide the IME using JNI. handled = 0; if( app->onInputEvent ) handled = app->onInputEvent( app, event ); if( ( AInputEvent_getType( event ) == AINPUT_EVENT_TYPE_KEY ) && ( AKeyEvent_getKeyCode( event ) == AKEYCODE_BACK ) ) handled = 1; AInputQueue_finishEvent( app->inputQueue, event, handled ); } }
static int32_t OnAndroidInputEvent( struct android_app* app, AInputEvent* event ) { int eventType = AInputEvent_getType( event ); switch ( eventType ) { case AINPUT_EVENT_TYPE_KEY: { int androidKeyCode = AKeyEvent_getKeyCode( event ); int androidKeyAction = AKeyEvent_getAction( event ); KeyCode gucefKeyCode = MapAndroidKeyToGucef( androidKeyCode ); if ( AKEY_EVENT_ACTION_DOWN == androidKeyAction ) { NotifyAllContextsOfKeyDown( gucefKeyCode ); } else if ( AKEY_EVENT_ACTION_UP == androidKeyAction ) { NotifyAllContextsOfKeyUp( gucefKeyCode ); } break; } case AINPUT_EVENT_TYPE_MOTION: { static int prevXPos = 0; static int prevYPos = 0; int xPos = AMotionEvent_getX( event, 0 ); int yPos = AMotionEvent_getY( event, 0 ); int xDelta = xPos - prevXPos; int yDelta = yPos - prevYPos; prevXPos = xPos; prevYPos = yPos; NotifyAllContextsOfMouseMove( xPos, yPos, xDelta, yDelta ); break; } } return 0; }