bool InputView::dispatchGenericMotionEvent(AInputEvent* motionEvent) { int64_t downTime = AMotionEvent_getDownTime(motionEvent); int64_t eventTime = AMotionEvent_getEventTime(motionEvent); int32_t action = AMotionEvent_getAction(motionEvent); int32_t metaState = AMotionEvent_getMetaState(motionEvent); int32_t pointerCount = AMotionEvent_getPointerCount(motionEvent); int32_t buttonState = AMotionEvent_getButtonState(motionEvent); float xPrecision = AMotionEvent_getXPrecision(motionEvent); float yPrecision = AMotionEvent_getYPrecision(motionEvent); int32_t deviceId = AInputEvent_getDeviceId(motionEvent); int32_t edgeFlags = AMotionEvent_getEdgeFlags(motionEvent); int32_t flags = AMotionEvent_getFlags(motionEvent); int32_t source = AInputEvent_getSource(motionEvent); int* pointerPropertiesId = new int[pointerCount]; int* pointerPropertiesToolType = new int[pointerCount]; float* pointerCoordsOrientation = new float[pointerCount]; float* pointerCoordsPressure = new float[pointerCount]; float* pointerCoordsSize = new float[pointerCount]; float* pointerCoordsToolMajor = new float[pointerCount]; float* pointerCoordsToolMinor = new float[pointerCount]; float* pointerCoordsTouchMajor = new float[pointerCount]; float* pointerCoordsTouchMinor = new float[pointerCount]; float* pointerCoordsX = new float[pointerCount]; float* pointerCoordsY = new float[pointerCount]; std::vector<int> listAxisIndices; std::vector<float> listAxisValues; if (pointerCount > 0) { #if ENABLE_VERBOSE_LOGGING __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "pointerCount=%d deviceId=%d source=%d", pointerCount, deviceId, source); #endif // MotionEvent.PointerProperties long long pointerId = AMotionEvent_getPointerId(motionEvent, 0); int32_t toolType = AMotionEvent_getToolType(motionEvent, 0); #if ENABLE_VERBOSE_LOGGING __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "PointerProperties pointerId=%lld toolType-%d", pointerId, toolType); #endif pointerPropertiesId[0] = pointerId; pointerPropertiesToolType[0] = toolType; // MotionEvent.PointerCoords float orientation = AMotionEvent_getOrientation(motionEvent, pointerId); float pressure = AMotionEvent_getPressure(motionEvent, pointerId); float size = AMotionEvent_getSize(motionEvent, pointerId); float toolMajor = AMotionEvent_getTouchMajor(motionEvent, pointerId); float toolMinor = AMotionEvent_getToolMinor(motionEvent, pointerId); float touchMajor = AMotionEvent_getTouchMajor(motionEvent, pointerId); float touchMinor = AMotionEvent_getTouchMinor(motionEvent, pointerId); float x = AMotionEvent_getX(motionEvent, pointerId); float y = AMotionEvent_getY(motionEvent, pointerId); #if ENABLE_VERBOSE_LOGGING __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "PointerCoords orientation=%f pressure=%f size=%f toolMajor=%f toolMinor=%f touchMajor=%f touchMinor=%f x=%f y=%f", orientation, pressure, size, toolMajor, toolMinor, touchMajor, touchMinor, x, y); #endif pointerCoordsOrientation[0] = orientation; pointerCoordsPressure[0] = pressure; pointerCoordsSize[0] = size; pointerCoordsToolMajor[0] = toolMajor; pointerCoordsToolMinor[0] = toolMinor; pointerCoordsTouchMajor[0] = touchMajor; pointerCoordsTouchMinor[0] = touchMinor; pointerCoordsX[0] = x; pointerCoordsY[0] = y; for (int32_t axis = 0; axis < 50; ++axis) // 50 is based on the AXIS_value range I saw in the documentation { float val = AMotionEvent_getAxisValue(motionEvent, axis, pointerId); if (val != 0.0f) { #if ENABLE_VERBOSE_LOGGING __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "axis=%d val=%f", axis, val); #endif listAxisIndices.push_back(axis); listAxisValues.push_back(val); } } } int axisCount = listAxisIndices.size(); int* axisIndexes = new int[axisCount]; float* axisValues = new float[axisCount]; for (int index = 0; index < axisCount; ++index) { axisIndexes[index] = listAxisIndices[index]; axisValues[index] = listAxisValues[index]; } listAxisIndices.clear(); listAxisValues.clear(); bool handled = javaDispatchGenericMotionEvent( downTime, eventTime, action, pointerCount, metaState, buttonState, xPrecision, yPrecision, deviceId, edgeFlags, source, flags, pointerPropertiesId, pointerPropertiesToolType, pointerCoordsOrientation, pointerCoordsPressure, pointerCoordsSize, pointerCoordsToolMajor, pointerCoordsToolMinor, pointerCoordsTouchMajor, pointerCoordsTouchMinor, pointerCoordsX, pointerCoordsY, axisCount, axisIndexes, axisValues); delete pointerPropertiesId; delete pointerPropertiesToolType; delete pointerCoordsOrientation; delete pointerCoordsPressure; delete pointerCoordsSize; delete pointerCoordsToolMajor; delete pointerCoordsToolMinor; delete pointerCoordsTouchMajor; delete pointerCoordsTouchMinor; delete pointerCoordsX; delete pointerCoordsY; delete axisIndexes; delete axisValues; return handled; }
int WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates* states) { // Prepare the Java virtual machine 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; return 0; } // Retrieve everything we need to create this MotionEvent in Java jlong downTime = AMotionEvent_getDownTime(_event); jlong eventTime = AMotionEvent_getEventTime(_event); jint action = AMotionEvent_getAction(_event); jfloat x = AMotionEvent_getX(_event, 0); jfloat y = AMotionEvent_getY(_event, 0); jfloat pressure = AMotionEvent_getPressure(_event, 0); jfloat size = AMotionEvent_getSize(_event, 0); jint metaState = AMotionEvent_getMetaState(_event); jfloat xPrecision = AMotionEvent_getXPrecision(_event); jfloat yPrecision = AMotionEvent_getYPrecision(_event); jint deviceId = AInputEvent_getDeviceId(_event); jint edgeFlags = AMotionEvent_getEdgeFlags(_event); // Create the MotionEvent object in Java trough its static constructor obtain() jclass ClassMotionEvent = lJNIEnv->FindClass("android/view/MotionEvent"); jmethodID StaticMethodObtain = lJNIEnv->GetStaticMethodID(ClassMotionEvent, "obtain", "(JJIFFFFIFFII)Landroid/view/MotionEvent;"); jobject ObjectMotionEvent = lJNIEnv->CallStaticObjectMethod(ClassMotionEvent, StaticMethodObtain, downTime, eventTime, action, x, y, pressure, size, metaState, xPrecision, yPrecision, deviceId, edgeFlags); // Call its getAxisValue() method to get the delta value of our wheel move event jmethodID MethodGetAxisValue = lJNIEnv->GetMethodID(ClassMotionEvent, "getAxisValue", "(I)F"); jfloat delta = lJNIEnv->CallFloatMethod(ObjectMotionEvent, MethodGetAxisValue, 0x00000001); lJNIEnv->DeleteLocalRef(ClassMotionEvent); lJNIEnv->DeleteLocalRef(ObjectMotionEvent); // Create and send our mouse wheel event Event event; event.type = Event::MouseWheelMoved; event.mouseWheel.delta = static_cast<double>(delta); event.mouseWheel.x = AMotionEvent_getX(_event, 0); event.mouseWheel.y = AMotionEvent_getY(_event, 0); forwardEvent(event); // Detach this thread from the JVM lJavaVM->DetachCurrentThread(); return 1; }